Created
July 16, 2015 09:56
-
-
Save 0xPr0xy/bde4f957d09ed63e76a9 to your computer and use it in GitHub Desktop.
ReferenceListener.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace Gedmo\References; | |
use Doctrine\Common\Collections\ArrayCollection; | |
use Doctrine\Common\EventArgs; | |
use Doctrine\Common\Persistence\ObjectManager; | |
use Gedmo\Mapping\MappedEventSubscriber; | |
/** | |
* Listener for loading and persisting cross database references. | |
* | |
* @author Gediminas Morkevicius <[email protected]> | |
* @author Bulat Shakirzyanov <[email protected]> | |
* @author Jonathan H. Wage <[email protected]> | |
* @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
*/ | |
class ReferencesListener extends MappedEventSubscriber | |
{ | |
private $managers; | |
public function __construct(array $managers = array()) | |
{ | |
$this->managers = $managers; | |
} | |
public function loadClassMetadata(EventArgs $eventArgs) | |
{ | |
$ea = $this->getEventAdapter($eventArgs); | |
$this->loadMetadataForObjectClass( | |
$ea->getObjectManager(), $eventArgs->getClassMetadata() | |
); | |
} | |
public function postLoad(EventArgs $eventArgs) | |
{ | |
$ea = $this->getEventAdapter($eventArgs); | |
$om = $ea->getObjectManager(); | |
$object = $ea->getObject(); | |
$meta = $om->getClassMetadata(get_class($object)); | |
$config = $this->getConfiguration($om, $meta->name); | |
if (isset($config['referenceOne'])) { | |
foreach ($config['referenceOne'] as $mapping) { | |
$property = $meta->reflClass->getProperty($mapping['field']); | |
$property->setAccessible(true); | |
if (isset($mapping['identifier'])) { | |
$referencedObjectId = $meta->getFieldValue($object, $mapping['identifier']); | |
if (null !== $referencedObjectId) { | |
$property->setValue( | |
$object, | |
$ea->getSingleReference( | |
$this->getManager($mapping['type']), | |
$mapping['class'], | |
$referencedObjectId | |
) | |
); | |
} | |
} | |
} | |
} | |
if (isset($config['referenceMany'])) { | |
foreach ($config['referenceMany'] as $mapping) { | |
$property = $meta->reflClass->getProperty($mapping['field']); | |
$property->setAccessible(true); | |
if (isset($mapping['mappedBy'])) { | |
$id = $ea->extractIdentifier($om, $object); | |
$manager = $this->getManager($mapping['type']); | |
$class = $mapping['class']; | |
$refMeta = $manager->getClassMetadata($class); | |
$refConfig = $this->getConfiguration($manager, $refMeta->name); | |
if (isset($refConfig['referenceOne'][$mapping['mappedBy']])) { | |
$refMapping = $refConfig['referenceOne'][$mapping['mappedBy']]; | |
$identifier = $refMapping['identifier']; | |
$property->setValue( | |
$object, | |
new LazyCollection( | |
function () use ($id, &$manager, $class, $identifier) { | |
$results = $manager | |
->getRepository($class) | |
->findBy(array( | |
$identifier => $id, | |
)); | |
return new ArrayCollection((is_array($results) ? $results : $results->toArray())); | |
} | |
) | |
); | |
} | |
} | |
} | |
} | |
$this->updateManyEmbedReferences($eventArgs); | |
} | |
public function prePersist(EventArgs $eventArgs) | |
{ | |
$this->updateReferences($eventArgs); | |
} | |
public function preUpdate(EventArgs $eventArgs) | |
{ | |
$this->updateReferences($eventArgs); | |
} | |
public function getSubscribedEvents() | |
{ | |
return array( | |
'postLoad', | |
'loadClassMetadata', | |
'prePersist', | |
'preUpdate', | |
); | |
} | |
public function registerManager($type, $manager) | |
{ | |
$this->managers[$type] = $manager; | |
} | |
/** | |
* @param string $type | |
* | |
* @return ObjectManager | |
*/ | |
public function getManager($type) | |
{ | |
return $this->managers[$type]; | |
} | |
protected function getNamespace() | |
{ | |
return __NAMESPACE__; | |
} | |
private function updateReferences(EventArgs $eventArgs) | |
{ | |
$ea = $this->getEventAdapter($eventArgs); | |
$om = $ea->getObjectManager(); | |
$object = $ea->getObject(); | |
$meta = $om->getClassMetadata(get_class($object)); | |
$config = $this->getConfiguration($om, $meta->name); | |
if (isset($config['referenceOne'])) { | |
foreach ($config['referenceOne'] as $mapping) { | |
if (isset($mapping['identifier'])) { | |
$property = $meta->reflClass->getProperty($mapping['field']); | |
$property->setAccessible(true); | |
$referencedObject = $property->getValue($object); | |
if (is_object($referencedObject)) { | |
$manager = $this->getManager($mapping['type']); | |
$identifier = $ea->getIdentifier($manager, $referencedObject); | |
$meta->setFieldValue( | |
$object, | |
$mapping['identifier'], | |
$identifier | |
); | |
} | |
} | |
} | |
} | |
$this->updateManyEmbedReferences($eventArgs); | |
} | |
public function updateManyEmbedReferences(EventArgs $eventArgs) | |
{ | |
$ea = $this->getEventAdapter($eventArgs); | |
$om = $ea->getObjectManager(); | |
$object = $ea->getObject(); | |
$meta = $om->getClassMetadata(get_class($object)); | |
$config = $this->getConfiguration($om, $meta->name); | |
if (isset($config['referenceManyEmbed'])) { | |
foreach ($config['referenceManyEmbed'] as $mapping) { | |
$property = $meta->reflClass->getProperty($mapping['field']); | |
$property->setAccessible(true); | |
$id = $ea->extractIdentifier($om, $object); | |
$manager = $this->getManager('document'); | |
$class = $mapping['class']; | |
$refMeta = $manager->getClassMetadata($class); | |
// Trigger the loading of the configuration to validate the mapping | |
$this->getConfiguration($manager, $refMeta->name); | |
$identifier = $mapping['identifier']; | |
$property->setValue( | |
$object, | |
new LazyCollection( | |
function () use ($id, &$manager, $class, $identifier) { | |
$results = $manager | |
->getRepository($class) | |
->findBy(array( | |
$identifier => $id, | |
)); | |
return new ArrayCollection((is_array($results) ? $results : $results->toArray())); | |
} | |
) | |
); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment