-
-
Save webdevilopers/e65f795749c40601276f60a5a3517a85 to your computer and use it in GitHub Desktop.
<?php | |
/** | |
* @ORM\Entity() | |
* @ORM\EntityListeners({"Acme\AppBundle\Event\CustomerListener"}) | |
*/ | |
class Customer() | |
{ | |
} |
<?php | |
use Doctrine\ODM\MongoDB\DocumentManager; | |
use Doctrine\ORM\Event\LifecycleEventArgs; | |
use Acme\AppBundle\Entity\Customer; | |
use Symfony\Component\DependencyInjection\Container; | |
class CustomerListener | |
{ | |
/** | |
* @var DocumentManager | |
*/ | |
private $dm; | |
/* | |
public function __construct(DocumentManager $dm) | |
{ | |
$this->dm = $dm; | |
} | |
*/ | |
public function __construct(Container $container) | |
{ | |
$this->dm = $container->get('doctrine_mongodb.odm.default_document_manager'); | |
} | |
public function postLoad(Customer $customer, LifecycleEventArgs $eventArgs) | |
{ | |
$em = $eventArgs->getEntityManager(); | |
$ordersReflProp = $em->getClassMetadata('AcmeAppBundle:Customer') | |
->reflClass->getProperty('orders'); | |
$ordersReflProp->setAccessible(true); | |
$ordersReflProp->setValue( | |
$customer, $this->dm->getRepository('AcmeAppBundle:Order') | |
->findBy(array('customer' => $customer->getId())) | |
); | |
} | |
} |
<?php | |
use Doctrine\ODM\MongoDB\DocumentManager; | |
use Doctrine\ORM\Event\LifecycleEventArgs; | |
class MyEventSubscriber | |
{ | |
public function __construct(DocumentManager $dm) | |
{ | |
$this->dm = $dm; | |
} | |
public function postLoad(LifecycleEventArgs $eventArgs) | |
{ | |
if ($eventArgs->getObject() instanceof Customer) { | |
$customer = $eventArgs->getEntity(); | |
$em = $eventArgs->getEntityManager(); | |
$ordersReflProp = $em->getClassMetadata('AcmeBundle:Customer') | |
->reflClass->getProperty('orders'); | |
$ordersReflProp->setAccessible(true); | |
$ordersReflProp->setValue( | |
$customer, $this->dm->getRepository('AcmeBundle:Order') | |
->findBy(array('customer' => $customer->getId())) | |
); | |
} | |
} | |
} |
<?php | |
use Doctrine\ORM\EntityManager; | |
use Doctrine\ODM\MongoDB\Event\LifecycleEventArgs; | |
use Symfony\Component\DependencyInjection\Container; | |
class MongoEventSubscriber | |
{ | |
/** | |
* @var EntityManager | |
*/ | |
private $_em; | |
/* | |
public function __construct(EntityManager $em) | |
{ | |
$this->_em = $em; | |
} | |
*/ | |
public function __construct(Container $container) | |
{ | |
$this->_em = $container->get('doctrine.orm.default_entity_manager'); | |
} | |
public function postLoad(LifecycleEventArgs $eventArgs) | |
{ | |
if ($eventArgs->getObject() instanceof Order) { | |
$order = $eventArgs->getDocument(); | |
$dm = $eventArgs->getDocumentManager(); | |
$supplierReflProp = $dm->getClassMetadata('AcmeBundle:Order') | |
->reflClass->getProperty('supplier'); | |
$supplierReflProp->setAccessible(true); | |
$supplierReflProp->setValue( | |
$order, $this->_em->getRepository('AcmeBundle:Supplier') | |
->find($order->supplier()) | |
); | |
} | |
} | |
} |
<?php | |
class OrderController extends Controller | |
{ | |
public function listCustomerOrdersAction() | |
{ | |
$em = $this->getDoctrine()->getManager(); | |
$dm = $this->get('doctrine_mongodb.odm.default_document_manager'); | |
$eventManager = $em->getEventManager(); | |
$eventManager->addEventListener( | |
array(\Doctrine\ORM\Events::postLoad), new DoctrineEventSubscriber($dm) | |
); | |
$eventManager2 = $dm->getEventManager(); | |
$eventManager2->addEventListener( | |
array(\Doctrine\ODM\MongoDB\Events::postLoad), new MongoEventSubscriber($em) | |
); | |
$customer = $em->find('AcmeBundle:Customer', 969); | |
dump($customer); | |
$orders = $customer->orders(); | |
dump($orders[0]); | |
$supplier = $orders[0]->supplier(); | |
dump($supplier); | |
echo $supplier->fullName(); | |
exit; | |
} |
<?xml version="1.0" ?> | |
<container xmlns="http://symfony.com/schema/dic/services" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> | |
<services> | |
<!-- | |
<service id="orm.doctrine.listener" class="Acme\AppBundle\Event\DoctrineEventSubscriber"> | |
<argument type="service" id="doctrine.odm.mongodb.document_manager"/> | |
<tag name="doctrine.event_listener" event="postLoad"/> | |
</service> | |
<service id="odm.doctrine.listener" class="Acme\AppBundle\Event\MongoEventSubscriber"> | |
<argument type="service" id="doctrine.orm.entity_manager"/> | |
<tag name="doctrine_mongodb.odm.event_listener" event="postLoad"/> | |
</service> | |
--> | |
<service id="customer.listener" class="Acme\AppBundle\Event\BranchListener"> | |
<argument type="service" id="service_container" /> | |
<tag name="doctrine.orm.entity_listener" /> | |
</service> | |
<service id="odm.doctrine.listener" class="Acme\AppBundle\Event\MongoEventSubscriber"> | |
<argument type="service" id="service_container"/> | |
<tag name="doctrine_mongodb.odm.event_listener" event="postLoad"/> | |
</service> | |
</services> | |
</container> |
The Event Listeners inside the Controller work fine. I would like to move them to the services.xml
.
Unfortunately I get:
Circular reference detected for service "doctrine.orm.default_entity_manager", path: "cache_warmer -> twig -> security.authorization_checker -> security.authentication.manager -> fos_user.user_manager -> fos_user.entity_manager -> doctrine.orm.default_entity_manager -> doctrine.dbal.default_connection -> orm.doctrine.listener -> doctrine_mongodb.odm.default_document_manager -> doctrine_mongodb.odm.default_connection -> doctrine_mongodb.odm.event_manager -> gedmo.listener.reference.mongodb".
Is my DI wrong?
Or is it a @symfony w/ @doctrine problem and I will have to use setterInjection or inject the Container?
Discussion on Twitter:
https://twitter.com/webdevilopers/status/724870430557896704
@cbeyer @stephpy Did you guys find any solution similar to issue stephpy/timeline-bundle#24 (comment)?
Currently I tried to add an EntityListener
directly to the Customer
Entity. Again this gives me a circular reference:
Circular reference detected for service "doctrine.orm.default_entity_manager", path: "doctrine.orm.default_entity_manager".
Any idea @vadim2404 @pkruithof ? It seemed to work for others:
Came from:
- http://egeloen.fr/2013/12/01/symfony2-doctrine2-entity-listener-as-serice/#comment-2643241088
- https://twitter.com/webdevilopers/status/724888059448320000 @egeloen
Also see:
I now inject the Container instead of the Document Manager - as recommended by @egeloen @intelligentbee :
<service id="customer.listener" class="Acme\AppBundle\Event\BranchListener">
<argument type="service" id="service_container" />
<tag name="doctrine.orm.entity_listener" />
</service>
Since Doctrine Bundle 1.6 this would also work with injecting the Document Manager WITHOUT getting a circular reference issue.
Unfortunately it does no longer work as soon I add a second service for the inverse side - a ODM listener that needs the Entity Manager:
<service id="odm.doctrine.listener" class="Acme\AppBundle\Event\MongoEventSubscriber">
<argument type="service" id="service_container"/>
<tag name="doctrine_mongodb.odm.event_listener" event="postLoad"/>
</service>
Result:
Circular reference detected for service "doctrine.orm.default_entity_manager", path: "cache_warmer -> twig -> security.authorization_checker -> security.authentication.manager -> fos_user.user_manager -> fos_user.entity_manager -> doctrine.orm.default_entity_manager -> doctrine.orm.default_entity_listener_resolver -> customer.listener -> doctrine_mongodb.odm.default_document_manager -> doctrine_mongodb.odm.default_connection -> doctrine_mongodb.odm.event_manager -> odm.doctrine.listener".
Unfortunately there does not seem to be an equivalent to the Entity Listener
, I guess it would work with a Document Listener
.
I guess the only way to solve this is overriding the Resolver?
Do you have a better idea @stof?
I think a good alternative would be to use the approach of the References listener by @jwage:
https://github.com/Atlantic18/DoctrineExtensions/blob/master/lib/Gedmo/References/ReferencesListener.php#L20-27
Instead that in my approach I don't want the $referencedObjectId
field.
Came from:
webdevilopers/php-ddd#2 (comment)