Skip to content

Commit

Permalink
[references] use manager registry #821
Browse files Browse the repository at this point in the history
  • Loading branch information
l3pp4rd authored and stof committed Oct 6, 2014
1 parent 9ba6c4e commit 668ea01
Show file tree
Hide file tree
Showing 7 changed files with 63 additions and 67 deletions.
1 change: 0 additions & 1 deletion lib/Gedmo/Mapping/Annotation/Reference.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
*/
abstract class Reference extends Annotation
{
public $type;
public $class;
public $identifier;
public $mappedBy;
Expand Down
1 change: 0 additions & 1 deletion lib/Gedmo/References/Mapping/Driver/Annotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
95 changes: 38 additions & 57 deletions lib/Gedmo/References/ReferencesListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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;
}

/**
Expand All @@ -59,7 +54,7 @@ public function getSubscribedEvents()
/**
* Load the extension metadata
*
* @param \Doctrine\Common\EventArgs $event
* @param EventArgs $event
*/
public function loadClassMetadata(EventArgs $event)
{
Expand All @@ -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)
{
Expand All @@ -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));
}
Expand All @@ -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);

Expand Down Expand Up @@ -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
*
Expand All @@ -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
*
Expand All @@ -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));
}
}
}
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion tests/Gedmo/Fixture/References/ODM/MongoDB/Metadata.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion tests/Gedmo/Fixture/References/ODM/MongoDB/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 1 addition & 1 deletion tests/Gedmo/Fixture/References/ORM/StockItem.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
27 changes: 22 additions & 5 deletions tests/Gedmo/References/ReferenceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit 668ea01

Please sign in to comment.