diff --git a/lib/Gedmo/Mapping/Annotation/Reference.php b/lib/Gedmo/Mapping/Annotation/Reference.php index 11dd2cb5bb..6d58397296 100644 --- a/lib/Gedmo/Mapping/Annotation/Reference.php +++ b/lib/Gedmo/Mapping/Annotation/Reference.php @@ -14,7 +14,6 @@ */ abstract class Reference extends Annotation { - public $type; public $class; public $identifier; public $mappedBy; diff --git a/lib/Gedmo/References/Mapping/Driver/Annotation.php b/lib/Gedmo/References/Mapping/Driver/Annotation.php index f729dafaf5..8db29c8f27 100644 --- a/lib/Gedmo/References/Mapping/Driver/Annotation.php +++ b/lib/Gedmo/References/Mapping/Driver/Annotation.php @@ -61,7 +61,6 @@ public function loadExtensionMetadata(ClassMetadata $meta, ExtensionMetadataInte if ($reference = $this->reader->getPropertyAnnotation($property, $annotation)) { $exm->map($type, $property->getName(), array( 'field' => $property->getName(), - 'type' => $reference->type, 'class' => $reference->class, 'identifier' => $reference->identifier, 'mappedBy' => $reference->mappedBy, diff --git a/lib/Gedmo/References/ReferencesListener.php b/lib/Gedmo/References/ReferencesListener.php index abcbfaaf12..7cb51332e2 100644 --- a/lib/Gedmo/References/ReferencesListener.php +++ b/lib/Gedmo/References/ReferencesListener.php @@ -8,6 +8,7 @@ use Gedmo\Exception\UnexpectedValueException; use Gedmo\Mapping\MappedEventSubscriber; use Gedmo\Mapping\ObjectManagerHelper as OMH; +use Doctrine\Common\Persistence\ManagerRegistry; /** * Listener for loading and persisting cross database references. @@ -20,27 +21,21 @@ class ReferencesListener extends MappedEventSubscriber { /** - * A list of object managers to link references, - * in pairs of - * managerType => ObjectManagerInstance + * Object manager registry * - * Supported types are "entity" and "document" - * - * @var ObjectManager[] + * @var ManagerRegistry */ - private $managers; + private $managerRegistry; /** - * Listener can be initialized with a list of managers + * Listener should be initialized with manager registry * to link references * - * @param ObjectManager[] $managers - list of managers, check above + * @param ManagerRegistry $managerRegistry */ - public function __construct(array $managers = array()) + public function __construct(ManagerRegistry $managerRegistry) { - foreach ($managers as $type => $manager) { - $this->registerManager($type, $manager); - } + $this->managerRegistry = $managerRegistry; } /** @@ -59,7 +54,7 @@ public function getSubscribedEvents() /** * Load the extension metadata * - * @param \Doctrine\Common\EventArgs $event + * @param EventArgs $event */ public function loadClassMetadata(EventArgs $event) { @@ -71,7 +66,7 @@ public function loadClassMetadata(EventArgs $event) * currently it initializes references to foreign manager * if any are confihured * - * @param \Doctrine\Common\EventArgs $event + * @param EventArgs $event */ public function postLoad(EventArgs $event) { @@ -85,9 +80,8 @@ public function postLoad(EventArgs $event) if (isset($mapping['identifier'])) { $referencedObjectId = $meta->getFieldValue($object, $mapping['identifier']); if (null !== $referencedObjectId) { - $manager = $this->getManager($mapping['type']); - if (get_class($manager) === get_class($om)) { - throw new UnexpectedValueException("Referenced manager is of the same type: {$mapping['type']}"); + if ($om === $manager = $this->getManager($mapping['class'])) { + throw new UnexpectedValueException("Referenced manager manages the same class: {$mapping['class']}, use standard relation mapping"); } $property->setValue($object, $this->getSingleReference($manager, $mapping['class'], $referencedObjectId)); } @@ -99,8 +93,10 @@ public function postLoad(EventArgs $event) $property->setAccessible(true); if (isset($mapping['mappedBy'])) { $id = OMH::getIdentifier($om, $object); - $manager = $this->getManager($mapping['type']); $class = $mapping['class']; + if ($om === $manager = $this->getManager($mapping['class'])) { + throw new UnexpectedValueException("Referenced manager manages the same class: {$mapping['class']}, use standard relation mapping"); + } $refMeta = $manager->getClassMetadata($class); $refConfig = $this->getConfiguration($manager, $refMeta->name); @@ -148,38 +144,6 @@ protected function getNamespace() return __NAMESPACE__; } - /** - * Registeners a $manager of type $type - * to support linking references - * - * @param string $type - document or entity - * @param ObjectManager $manager - * - * @return static - */ - public function registerManager($type, ObjectManager $manager) - { - $this->managers[$type] = $manager; - - return $this; - } - - /** - * Get a registered manager of $type - * - * @param string $type - document or entity - * - * @return ObjectManager - */ - public function getManager($type) - { - if (!isset($this->managers[$type])) { - throw new UnexpectedValueException("Object manager for type: {$type} is not registered"); - } - - return $this->managers[$type]; - } - /** * Get a reference to relation managed by another manager $om * @@ -199,6 +163,22 @@ protected function getSingleReference(ObjectManager $om, $class, $identifier) return $om->getReference($class, $identifier); } + /** + * Get object manager from registry which handles $class + * + * @param string $class + * + * @return ObjectManager + */ + private function getManager($class) + { + if (null === $om = $this->managerRegistry->getManagerForClass($class)) { + throw new UnexpectedValueException("Could not find any manager for object class: {$class}"); + } + + return $om; + } + /** * Updates linked references * @@ -217,11 +197,10 @@ private function updateReferences(EventArgs $event) $property->setAccessible(true); $referencedObject = $property->getValue($object); if (is_object($referencedObject)) { - $meta->setFieldValue( - $object, - $mapping['identifier'], - OMH::getIdentifier($this->getManager($mapping['type']), $referencedObject) - ); + if ($om === $manager = $this->getManager($mapping['class'])) { + throw new UnexpectedValueException("Referenced manager manages the same class: {$mapping['class']}, use standard relation mapping"); + } + $meta->setFieldValue($object, $mapping['identifier'], OMH::getIdentifier($manager, $referencedObject)); } } } @@ -246,7 +225,9 @@ public function updateManyEmbedReferences(EventArgs $event) $property->setAccessible(true); $id = OMH::getIdentifier($om, $object); - $manager = $this->getManager('document'); + if ($om === $manager = $this->getManager($mapping['class'])) { + throw new UnexpectedValueException("Referenced manager manages the same class: {$mapping['class']}, use standard relation mapping"); + } $class = $mapping['class']; $refMeta = $manager->getClassMetadata($class); diff --git a/tests/Gedmo/Fixture/References/ODM/MongoDB/Metadata.php b/tests/Gedmo/Fixture/References/ODM/MongoDB/Metadata.php index 1c41fe13d9..8d6a0bcc94 100644 --- a/tests/Gedmo/Fixture/References/ODM/MongoDB/Metadata.php +++ b/tests/Gedmo/Fixture/References/ODM/MongoDB/Metadata.php @@ -17,7 +17,7 @@ class Metadata private $name; /** - * @Gedmo\ReferenceOne(type="entity", class="Gedmo\Fixture\References\ORM\Category", identifier="categoryId") + * @Gedmo\ReferenceOne(class="Gedmo\Fixture\References\ORM\Category", identifier="categoryId") */ private $category; diff --git a/tests/Gedmo/Fixture/References/ODM/MongoDB/Product.php b/tests/Gedmo/Fixture/References/ODM/MongoDB/Product.php index bed0bc5467..7a7293bfa6 100644 --- a/tests/Gedmo/Fixture/References/ODM/MongoDB/Product.php +++ b/tests/Gedmo/Fixture/References/ODM/MongoDB/Product.php @@ -23,7 +23,7 @@ class Product private $name; /** - * @Gedmo\ReferenceMany(type="entity", class="Gedmo\Fixture\References\ORM\StockItem", mappedBy="product") + * @Gedmo\ReferenceMany(class="Gedmo\Fixture\References\ORM\StockItem", mappedBy="product") */ private $stockItems; diff --git a/tests/Gedmo/Fixture/References/ORM/StockItem.php b/tests/Gedmo/Fixture/References/ORM/StockItem.php index e70d0815de..27fae23e1f 100644 --- a/tests/Gedmo/Fixture/References/ORM/StockItem.php +++ b/tests/Gedmo/Fixture/References/ORM/StockItem.php @@ -34,7 +34,7 @@ class StockItem private $quantity; /** - * @Gedmo\ReferenceOne(type="document", class="Gedmo\Fixture\References\ODM\MongoDB\Product", inversedBy="stockItems", identifier="productId") + * @Gedmo\ReferenceOne(class="Gedmo\Fixture\References\ODM\MongoDB\Product", inversedBy="stockItems", identifier="productId") */ private $product; diff --git a/tests/Gedmo/References/ReferenceTest.php b/tests/Gedmo/References/ReferenceTest.php index 65c221e70b..25eed28045 100644 --- a/tests/Gedmo/References/ReferenceTest.php +++ b/tests/Gedmo/References/ReferenceTest.php @@ -27,17 +27,34 @@ class ReferenceTest extends ObjectManagerTestCase protected function setUp() { $evm = new EventManager(); - $evm->addEventSubscriber($this->listener = new ReferencesListener()); - $this->dm = $this->createDocumentManager($evm); - $this->listener->registerManager('document', $this->dm); + $registryMock = $this->getMockBuilder('Doctrine\Common\Persistence\ManagerRegistry') + ->disableOriginalConstructor() + ->getMock(); - $this->em = $this->createEntityManager($evm); + $this->dm = $dm = $this->createDocumentManager($evm); + $this->em = $em = $this->createEntityManager($evm); $this->createSchema($this->em, array( 'Gedmo\Fixture\References\ORM\StockItem', 'Gedmo\Fixture\References\ORM\Category', )); - $this->listener->registerManager('entity', $this->em); + $registryMock + ->expects($this->any()) + ->method('getManagerForClass') + ->will($this->returnCallback(function ($class) use ($dm,$em) { + switch ($class) { + case 'Gedmo\Fixture\References\ORM\StockItem': + case 'Gedmo\Fixture\References\ORM\Category': + return $em; + case 'Gedmo\Fixture\References\ODM\MongoDB\Metadata': + case 'Gedmo\Fixture\References\ODM\MongoDB\Product': + return $dm; + default: + return null; + } + })); + $this->listener = new ReferencesListener($registryMock); + $evm->addEventSubscriber($this->listener); } protected function tearDown()