1
0
mirror of synced 2025-02-21 22:53:15 +03:00

Merge branch 'DDC-1033'

This commit is contained in:
Benjamin Eberlei 2011-02-26 12:48:10 +01:00
commit 521705a0f2
4 changed files with 86 additions and 7 deletions

View File

@ -172,6 +172,14 @@ class BasicEntityPersister
$this->_platform = $this->_conn->getDatabasePlatform(); $this->_platform = $this->_conn->getDatabasePlatform();
} }
/**
* @return Doctrine\ORM\Mapping\ClassMetadata
*/
public function getClassMetadata()
{
return $this->_class;
}
/** /**
* Adds an entity to the queued insertions. * Adds an entity to the queued insertions.
* The entity remains queued until {@link executeInserts} is invoked. * The entity remains queued until {@link executeInserts} is invoked.

View File

@ -130,11 +130,12 @@ class ProxyFactory
{ {
$methods = $this->_generateMethods($class); $methods = $this->_generateMethods($class);
$sleepImpl = $this->_generateSleep($class); $sleepImpl = $this->_generateSleep($class);
$cloneImpl = $class->reflClass->hasMethod('__clone') ? 'parent::__clone();' : ''; // hasMethod() checks case-insensitive
$placeholders = array( $placeholders = array(
'<namespace>', '<namespace>',
'<proxyClassName>', '<className>', '<proxyClassName>', '<className>',
'<methods>', '<sleepImpl>' '<methods>', '<sleepImpl>', '<cloneImpl>'
); );
if(substr($class->name, 0, 1) == "\\") { if(substr($class->name, 0, 1) == "\\") {
@ -146,7 +147,7 @@ class ProxyFactory
$replacements = array( $replacements = array(
$this->_proxyNamespace, $this->_proxyNamespace,
$proxyClassName, $className, $proxyClassName, $className,
$methods, $sleepImpl $methods, $sleepImpl, $cloneImpl
); );
$file = str_replace($placeholders, $replacements, $file); $file = str_replace($placeholders, $replacements, $file);
@ -166,7 +167,7 @@ class ProxyFactory
foreach ($class->reflClass->getMethods() as $method) { foreach ($class->reflClass->getMethods() as $method) {
/* @var $method ReflectionMethod */ /* @var $method ReflectionMethod */
if ($method->isConstructor() || strtolower($method->getName()) == "__sleep") { if ($method->isConstructor() || in_array(strtolower($method->getName()), array("__sleep", "__clone"))) {
continue; continue;
} }
@ -285,5 +286,22 @@ class <proxyClassName> extends \<className> implements \Doctrine\ORM\Proxy\Proxy
{ {
<sleepImpl> <sleepImpl>
} }
public function __clone()
{
if (!$this->__isInitialized__ && $this->_entityPersister) {
$this->__isInitialized__ = true;
$class = $this->_entityPersister->getClassMetadata();
$original = $this->_entityPersister->load($this->_identifier);
if ($original === null) {
throw new \Doctrine\ORM\EntityNotFoundException();
}
foreach ($class->reflFields AS $field => $reflProperty) {
$reflProperty->setValue($this, $reflProperty->getValue($original));
}
unset($this->_entityPersister, $this->_identifier);
}
<cloneImpl>
}
}'; }';
} }

View File

@ -55,6 +55,8 @@ class ECommerceProduct
*/ */
private $related; private $related;
public $isCloned = false;
public function __construct() public function __construct()
{ {
$this->features = new ArrayCollection; $this->features = new ArrayCollection;
@ -159,4 +161,9 @@ class ECommerceProduct
$related->removeRelated($this); $related->removeRelated($this);
} }
} }
public function __clone()
{
$this->isCloned = true;
}
} }

View File

@ -26,7 +26,7 @@ class ReferenceProxyTest extends \Doctrine\Tests\OrmFunctionalTestCase
true); true);
} }
public function testLazyLoadsFieldValuesFromDatabase() public function createProduct()
{ {
$product = new ECommerceProduct(); $product = new ECommerceProduct();
$product->setName('Doctrine Cookbook'); $product->setName('Doctrine Cookbook');
@ -34,8 +34,13 @@ class ReferenceProxyTest extends \Doctrine\Tests\OrmFunctionalTestCase
$this->_em->flush(); $this->_em->flush();
$this->_em->clear(); $this->_em->clear();
$id = $product->getId(); return $product->getId();
}
public function testLazyLoadsFieldValuesFromDatabase()
{
$id = $this->createProduct();
$productProxy = $this->_factory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceProduct', array('id' => $id)); $productProxy = $this->_factory->getProxy('Doctrine\Tests\Models\ECommerce\ECommerceProduct', array('id' => $id));
$this->assertEquals('Doctrine Cookbook', $productProxy->getName()); $this->assertEquals('Doctrine Cookbook', $productProxy->getName());
@ -46,9 +51,50 @@ class ReferenceProxyTest extends \Doctrine\Tests\OrmFunctionalTestCase
*/ */
public function testAccessMetatadaForProxy() public function testAccessMetatadaForProxy()
{ {
$entity = $this->_em->getReference('Doctrine\Tests\Models\ECommerce\ECommerceProduct' , 1); $id = $this->createProduct();
$entity = $this->_em->getReference('Doctrine\Tests\Models\ECommerce\ECommerceProduct' , $id);
$class = $this->_em->getClassMetadata(get_class($entity)); $class = $this->_em->getClassMetadata(get_class($entity));
$this->assertEquals('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $class->name); $this->assertEquals('Doctrine\Tests\Models\ECommerce\ECommerceProduct', $class->name);
} }
/**
* @group DDC-1033
*/
public function testReferenceFind()
{
$id = $this->createProduct();
$entity = $this->_em->getReference('Doctrine\Tests\Models\ECommerce\ECommerceProduct' , $id);
$entity2 = $this->_em->find('Doctrine\Tests\Models\ECommerce\ECommerceProduct' , $id);
$this->assertSame($entity, $entity2);
$this->assertEquals('Doctrine Cookbook', $entity2->getName());
}
/**
* @group DDC-1033
*/
public function testCloneProxy()
{
$id = $this->createProduct();
/* @var $entity Doctrine\Tests\Models\ECommerce\ECommerceProduct */
$entity = $this->_em->getReference('Doctrine\Tests\Models\ECommerce\ECommerceProduct' , $id);
/* @var $clone Doctrine\Tests\Models\ECommerce\ECommerceProduct */
$clone = clone $entity;
$this->assertEquals($id, $entity->getId());
$this->assertEquals('Doctrine Cookbook', $entity->getName());
$this->assertFalse($this->_em->contains($clone), "Cloning a reference proxy should return an unmanaged/detached entity.");
$this->assertEquals($id, $clone->getId(), "Cloning a reference proxy should return same id.");
$this->assertEquals('Doctrine Cookbook', $clone->getName(), "Cloning a reference proxy should return same product name.");
// domain logic, Product::__clone sets isCloned public property
$this->assertTrue($clone->isCloned);
$this->assertFalse($entity->isCloned);
}
} }