Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
D
doctrine-dbal
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Tomáš Trávníček
doctrine-dbal
Commits
52d55da3
Commit
52d55da3
authored
Jul 17, 2009
by
piccoloprincipe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[2.0] working implementation of Association Proxy classes
parent
66f377fb
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
108 additions
and
94 deletions
+108
-94
AssociationMapping.php
lib/Doctrine/ORM/Mapping/AssociationMapping.php
+8
-4
ProxyClassGenerator.php
lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php
+23
-77
ProxyClassGeneratorTest.php
tests/Doctrine/Tests/ORM/Proxy/ProxyClassGeneratorTest.php
+77
-13
No files found.
lib/Doctrine/ORM/Mapping/AssociationMapping.php
View file @
52d55da3
...
...
@@ -378,9 +378,13 @@ abstract class AssociationMapping
}
/**
* Loads data in $targetEntity domain object using this association.
* The data comes from the association navigated from $owningEntity
* using $em.
*
* @param <type> $entity
* @param <type> $entityManager
* @param object $owningEntity
* @param object $targetEntity
* @param EntityManager $em
*/
/*abstract public function load($entity, $em) {}*/
}
\ No newline at end of file
public
function
load
(
$owningEntity
,
$targetEntity
,
$em
)
{}
}
lib/Doctrine/ORM/Proxy/ProxyClassGenerator.php
View file @
52d55da3
...
...
@@ -64,9 +64,30 @@ class ProxyClassGenerator
public
function
generateReferenceProxyClass
(
$originalClassName
)
{
$proxyClassName
=
str_replace
(
'\\'
,
'_'
,
$originalClassName
)
.
'RProxy'
;
//$proxyClassName = $originalClassName . 'RProxy';
return
$this
->
_generateClass
(
$originalClassName
,
$proxyClassName
,
self
::
$_proxyClassTemplate
);
}
/**
* Generates an association proxy class.
* This is a proxy class for an object which we have the association where
* it is involved, but no primary key to retrieve it.
*
* @param string $originalClassName
* @return string the proxy class name
*/
public
function
generateAssociationProxyClass
(
$originalClassName
)
{
$proxyClassName
=
str_replace
(
'\\'
,
'_'
,
$originalClassName
)
.
'AProxy'
;
return
$this
->
_generateClass
(
$originalClassName
,
$proxyClassName
,
self
::
$_assocProxyClassTemplate
);
}
protected
function
_generateClass
(
$originalClassName
,
$proxyClassName
,
$file
)
{
$class
=
$this
->
_em
->
getClassMetadata
(
$originalClassName
);
$proxyFullyQualifiedClassName
=
self
::
$_ns
.
$proxyClassName
;
if
(
class_exists
(
$proxyFullyQualifiedClassName
,
false
))
{
return
$proxyFullyQualifiedClassName
;
}
...
...
@@ -80,7 +101,6 @@ class ProxyClassGenerator
return
$proxyFullyQualifiedClassName
;
}
$file
=
self
::
$_proxyClassTemplate
;
$methods
=
$this
->
_generateMethods
(
$class
);
$sleepImpl
=
$this
->
_generateSleep
(
$class
);
...
...
@@ -96,7 +116,6 @@ class ProxyClassGenerator
file_put_contents
(
$fileName
,
$file
);
require
$fileName
;
return
$proxyFullyQualifiedClassName
;
}
...
...
@@ -167,79 +186,6 @@ class ProxyClassGenerator
return
$sleepImpl
;
}
/**
* Generates a proxy class.
* This is a proxy class for an object which we have the association where
* it is involved, but no primary key to retrieve it.
*
* @param string $originalClassName
* @param string $proxyClassName
*/
public
function
generateAssociationProxyClass
(
$originalClassName
,
$proxyClassName
)
{
$class
=
$this
->
_em
->
getClassMetadata
(
$originalClassName
);
$file
=
self
::
$_assocProxyClassTemplate
;
$methods
=
''
;
foreach
(
$class
->
reflClass
->
getMethods
()
as
$method
)
{
if
(
$method
->
isPublic
()
&&
!
$method
->
isFinal
())
{
$methods
.=
PHP_EOL
.
'public function '
.
$method
->
getName
()
.
'('
;
$firstParam
=
true
;
$parameterString
=
''
;
foreach
(
$method
->
getParameters
()
as
$param
)
{
if
(
$firstParam
)
{
$firstParam
=
false
;
}
else
{
$parameterString
.=
', '
;
}
$parameterString
.=
'$'
.
$param
->
getName
();
}
$methods
.=
$parameterString
.
') {'
.
PHP_EOL
;
$methods
.=
'$this->_load();'
.
PHP_EOL
;
$methods
.=
'return parent::'
.
$method
->
getName
()
.
'('
.
$parameterString
.
');'
;
$methods
.=
'}'
.
PHP_EOL
;
}
}
$sleepImpl
=
''
;
if
(
$class
->
reflClass
->
hasMethod
(
'__sleep'
))
{
$sleepImpl
.=
'return parent::__sleep();'
;
}
else
{
$sleepImpl
.=
'return array('
;
$first
=
true
;
foreach
(
$class
->
getReflectionProperties
()
as
$name
=>
$prop
)
{
if
(
$first
)
{
$first
=
false
;
}
else
{
$sleepImpl
.=
', '
;
}
$sleepImpl
.=
"'"
.
$name
.
"'"
;
}
$sleepImpl
.=
');'
;
}
$placeholders
=
array
(
'<proxyClassName>'
,
'<className>'
,
'<methods>'
,
'<sleepImpl>'
);
$replacements
=
array
(
$proxyClassName
,
$originalClassName
,
$methods
,
$sleepImpl
);
$file
=
str_replace
(
$placeholders
,
$replacements
,
$file
);
file_put_contents
(
$fileName
,
$file
);
return
$fileName
;
}
/** Proxy class code template */
private
static
$_proxyClassTemplate
=
...
...
tests/Doctrine/Tests/ORM/Proxy/ProxyClassGeneratorTest.php
View file @
52d55da3
...
...
@@ -8,8 +8,8 @@ use Doctrine\Tests\Mocks\EntityManagerMock;
use
Doctrine\Tests\Models\ECommerce\ECommerceCart
;
use
Doctrine\Tests\Models\ECommerce\ECommerceCustomer
;
use
Doctrine\Tests\Models\ECommerce\ECommerceFeature
;
use
Doctrine\Tests\Models\ECommerce\ECommerceProduct
;
use
Doctrine\Tests\Models\ECommerce\ECommerceShipping
;
use
Doctrine\ORM\Persisters\StandardEntityPersister
;
require_once
__DIR__
.
'/../../TestInit.php'
;
...
...
@@ -41,12 +41,6 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
}
}
public
function
testCreatesASubclassOfTheOriginalOne
()
{
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$this
->
assertTrue
(
is_subclass_of
(
$proxyClass
,
'\Doctrine\Tests\Models\ECommerce\ECommerceFeature'
));
}
public
function
testCanGuessADefaultTempFolder
()
{
$generator
=
new
ProxyClassGenerator
(
$this
->
_emMock
);
...
...
@@ -54,26 +48,32 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
$this
->
assertTrue
(
is_subclass_of
(
$proxyClass
,
'\Doctrine\Tests\Models\ECommerce\ECommerceShipping'
));
}
public
function
testAllowsClassesWithAConstructor
()
public
function
testCreatesReferenceProxyAsSubclassOfTheOriginalOne
()
{
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$this
->
assertTrue
(
is_subclass_of
(
$proxyClass
,
'\Doctrine\Tests\Models\ECommerce\ECommerceFeature'
));
}
public
function
testAllowsReferenceProxyForClassesWithAConstructor
()
{
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceCart'
);
$this
->
assertTrue
(
is_subclass_of
(
$proxyClass
,
'\Doctrine\Tests\Models\ECommerce\ECommerceCart'
));
}
public
function
testAllowsIdempotentCreationOfProxyClass
()
public
function
testAllowsIdempotentCreationOf
Reference
ProxyClass
()
{
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$theSameProxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$this
->
assertEquals
(
$proxyClass
,
$theSameProxyClass
);
}
public
function
test
CreatesClassesThatRequire
PersisterInTheConstructor
()
public
function
test
ReferenceProxyRequires
PersisterInTheConstructor
()
{
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$proxy
=
new
$proxyClass
(
$this
->
_getMockPersister
(),
null
);
}
public
function
test
CreatesClassesThatDelegate
LoadingToThePersister
()
public
function
test
ReferenceProxyDelegates
LoadingToThePersister
()
{
$identifier
=
array
(
'id'
=>
42
);
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
...
...
@@ -85,7 +85,7 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
$proxy
->
getDescription
();
}
public
function
test
CreatesClassesThat
ExecutesLoadingOnlyOnce
()
public
function
test
ReferenceProxy
ExecutesLoadingOnlyOnce
()
{
$identifier
=
array
(
'id'
=>
42
);
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
...
...
@@ -101,7 +101,7 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
/**
* @expectedException PHPUnit_Framework_Error
*/
public
function
testRespectsMethodsParametersTypeHinting
()
public
function
testRe
ferenceProxyRe
spectsMethodsParametersTypeHinting
()
{
$proxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$proxy
=
new
$proxyClass
(
$this
->
_getMockPersister
(),
null
);
...
...
@@ -113,4 +113,68 @@ class ProxyClassGeneratorTest extends \Doctrine\Tests\OrmTestCase
$persister
=
$this
->
getMock
(
'Doctrine\ORM\Persisters\StandardEntityPersister'
,
array
(
'load'
),
array
(),
''
,
false
);
return
$persister
;
}
public
function
testCreatesAssociationProxyAsSubclassOfTheOriginalOne
()
{
$proxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$this
->
assertTrue
(
is_subclass_of
(
$proxyClass
,
'\Doctrine\Tests\Models\ECommerce\ECommerceFeature'
));
}
public
function
testAllowsAssociationProxyOfClassesWithAConstructor
()
{
$proxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceCart'
);
$this
->
assertTrue
(
is_subclass_of
(
$proxyClass
,
'\Doctrine\Tests\Models\ECommerce\ECommerceCart'
));
}
public
function
testAllowsIdempotentCreationOfAssociationProxyClass
()
{
$proxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$theSameProxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$this
->
assertEquals
(
$proxyClass
,
$theSameProxyClass
);
}
public
function
testAllowsConcurrentCreationOfBothProxyTypes
()
{
$referenceProxyClass
=
$this
->
_generator
->
generateReferenceProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$associationProxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$this
->
assertNotEquals
(
$referenceProxyClass
,
$associationProxyClass
);
}
public
function
testAssociationProxyRequiresEntityManagerAndAssociationAndOwnerInTheConstructor
()
{
$proxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$product
=
new
ECommerceProduct
;
$proxy
=
new
$proxyClass
(
$this
->
_emMock
,
$this
->
_getAssociationMock
(),
$product
);
}
public
function
testAssociationProxyDelegatesLoadingToTheAssociation
()
{
$proxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$product
=
new
ECommerceProduct
;
$assoc
=
$this
->
_getAssociationMock
();
$proxy
=
new
$proxyClass
(
$this
->
_emMock
,
$assoc
,
$product
);
$assoc
->
expects
(
$this
->
any
())
->
method
(
'load'
)
->
with
(
$product
,
$this
->
isInstanceOf
(
$proxyClass
),
$this
->
isInstanceOf
(
'Doctrine\Tests\Mocks\EntityManagerMock'
));
$proxy
->
getDescription
();
}
public
function
testAssociationProxyExecutesLoadingOnlyOnce
()
{
$proxyClass
=
$this
->
_generator
->
generateAssociationProxyClass
(
'Doctrine\Tests\Models\ECommerce\ECommerceFeature'
);
$assoc
=
$this
->
_getAssociationMock
();
$proxy
=
new
$proxyClass
(
$this
->
_emMock
,
$assoc
,
null
);
$assoc
->
expects
(
$this
->
once
())
->
method
(
'load'
);
$proxy
->
getDescription
();
$proxy
->
getDescription
();
}
protected
function
_getAssociationMock
()
{
$assoc
=
$this
->
getMock
(
'Doctrine\ORM\Mapping\AssociationMapping'
,
array
(
'load'
),
array
(),
''
,
false
);
return
$assoc
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment