From bda593a66dcceed8c32b25843c69289e6ba3cefd Mon Sep 17 00:00:00 2001 From: Benjamin Eberlei Date: Sat, 19 Nov 2011 12:41:06 +0100 Subject: [PATCH] DDC-1448 - Add support for ObjectManagerAware interface and PersistentObject in ORM --- .../ORM/Mapping/ClassMetadataInfo.php | 18 +++ lib/Doctrine/ORM/UnitOfWork.php | 24 +++- lib/vendor/doctrine-common | 2 +- .../ORM/Functional/PersistentObjectTest.php | 105 ++++++++++++++++++ 4 files changed, 145 insertions(+), 4 deletions(-) create mode 100644 tests/Doctrine/Tests/ORM/Functional/PersistentObjectTest.php diff --git a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php index 2734d3647..21643be96 100644 --- a/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php +++ b/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php @@ -1993,4 +1993,22 @@ class ClassMetadataInfo implements ClassMetadata { return isset($assoc['joinTable']['quoted']) ? $platform->quoteIdentifier($assoc['joinTable']['name']) : $assoc['joinTable']['name']; } + + /** + * @param string $fieldName + * @return bool + */ + public function isAssociationInverseSide($fieldName) + { + return isset($this->associationMappings[$fieldName]) && ! $this->associationMappings[$fieldName]['isOwningSide']; + } + + /** + * @param string $fieldName + * @return string + */ + public function getAssociationMappedByTargetField($fieldName) + { + return $this->associationMappings[$fieldName]['mappedBy']; + } } diff --git a/lib/Doctrine/ORM/UnitOfWork.php b/lib/Doctrine/ORM/UnitOfWork.php index 513f58b5a..2e096f890 100644 --- a/lib/Doctrine/ORM/UnitOfWork.php +++ b/lib/Doctrine/ORM/UnitOfWork.php @@ -24,6 +24,7 @@ use Exception, InvalidArgumentException, UnexpectedValueException, Doctrine\Common\Collections\Collection, Doctrine\Common\NotifyPropertyChanged, Doctrine\Common\PropertyChangedListener, + Doctrine\Common\Persistence\ObjectManagerAware, Doctrine\ORM\Event\LifecycleEventArgs, Doctrine\ORM\Mapping\ClassMetadata, Doctrine\ORM\Proxy\Proxy; @@ -1642,7 +1643,7 @@ class UnitOfWork implements PropertyChangedListener // If there is no ID, it is actually NEW. if ( ! $id) { - $managedCopy = $class->newInstance(); + $managedCopy = $this->newInstance($class); $this->persistNew($class, $managedCopy); } else { @@ -1666,7 +1667,7 @@ class UnitOfWork implements PropertyChangedListener throw new EntityNotFoundException; } - $managedCopy = $class->newInstance(); + $managedCopy = $this->newInstance($class); $class->setIdentifierValues($managedCopy, $id); $this->persistNew($class, $managedCopy); @@ -2157,6 +2158,18 @@ class UnitOfWork implements PropertyChangedListener return isset($this->collectionsDeletions[spl_object_hash($coll)]); } + /** + * @param ClassMetadata $class + */ + private function newInstance($class) + { + $entity = $class->newInstance(); + if ($entity instanceof \Doctrine\Common\Persistence\ObjectManagerAware) { + $entity->injectObjectManager($this->em, $class); + } + return $entity; + } + /** * INTERNAL: * Creates an entity. Used for reconstitution of persistent entities. @@ -2209,6 +2222,11 @@ class UnitOfWork implements PropertyChangedListener // If only a specific entity is set to refresh, check that it's the one if(isset($hints[Query::HINT_REFRESH_ENTITY])) { $overrideLocalValues = $hints[Query::HINT_REFRESH_ENTITY] === $entity; + + // inject ObjectManager into just loaded proxies. + if ($overrideLocalValues && $entity instanceof ObjectManagerAware) { + $entity->injectObjectManager($this->em, $class); + } } } @@ -2216,7 +2234,7 @@ class UnitOfWork implements PropertyChangedListener $this->originalEntityData[$oid] = $data; } } else { - $entity = $class->newInstance(); + $entity = $this->newInstance($class); $oid = spl_object_hash($entity); $this->entityIdentifiers[$oid] = $id; $this->entityStates[$oid] = self::STATE_MANAGED; diff --git a/lib/vendor/doctrine-common b/lib/vendor/doctrine-common index 3052115f2..9c880cf9a 160000 --- a/lib/vendor/doctrine-common +++ b/lib/vendor/doctrine-common @@ -1 +1 @@ -Subproject commit 3052115f241020b67326cf1368540d33baa991f3 +Subproject commit 9c880cf9ae2c14102568520b5ee885b03bda93e4 diff --git a/tests/Doctrine/Tests/ORM/Functional/PersistentObjectTest.php b/tests/Doctrine/Tests/ORM/Functional/PersistentObjectTest.php new file mode 100644 index 000000000..88e54ae2e --- /dev/null +++ b/tests/Doctrine/Tests/ORM/Functional/PersistentObjectTest.php @@ -0,0 +1,105 @@ +_schemaTool->createSchema(array( + $this->_em->getClassMetadata('Doctrine\Tests\ORM\Functional\PersistentEntity'), + )); + } catch (\Exception $e) { + + } + PersistentObject::setObjectManager($this->_em); + } + + public function testPersist() + { + $entity = new PersistentEntity(); + $entity->setName("test"); + + $this->_em->persist($entity); + $this->_em->flush(); + } + + public function testFind() + { + $entity = new PersistentEntity(); + $entity->setName("test"); + + $this->_em->persist($entity); + $this->_em->flush(); + $this->_em->clear(); + + $entity = $this->_em->find(__NAMESPACE__ . '\PersistentEntity', $entity->getId()); + + $this->assertEquals('test', $entity->getName()); + $entity->setName('foobar'); + + $this->_em->flush(); + } + + public function testGetReference() + { + $entity = new PersistentEntity(); + $entity->setName("test"); + + $this->_em->persist($entity); + $this->_em->flush(); + $this->_em->clear(); + + $entity = $this->_em->getReference(__NAMESPACE__ . '\PersistentEntity', $entity->getId()); + + $this->assertEquals('test', $entity->getName()); + } + + public function testSetAssociation() + { + $entity = new PersistentEntity(); + $entity->setName("test"); + $entity->setParent($entity); + + $this->_em->persist($entity); + $this->_em->flush(); + $this->_em->clear(); + + $entity = $this->_em->getReference(__NAMESPACE__ . '\PersistentEntity', $entity->getId()); + $this->assertSame($entity, $entity->getParent()); + } +} + +/** + * @Entity + */ +class PersistentEntity extends PersistentObject +{ + /** + * @Id @Column(type="integer") @GeneratedValue + * @var int + */ + protected $id; + + /** + * @Column(type="string") + * @var string + */ + protected $name; + + /** + * @ManyToOne(targetEntity="PersistentEntity") + * @var PersistentEntity + */ + protected $parent; +}