Update: This post is super outdated and I don’t think I ever made the technique I was using suitable for general consumption in the first place. And Doctrine added the functionality anyway, further obviating this post.
A bundle to make managing persistence events in Doctrine significantly easier.
Handling Doctrine’s persistence events can get pretty cumbersome. For example, if you want to manage the events for only a single type of entity, you have to do something like this (taken from the the Symfony docs):
// src/AppBundle/EventListener/SearchIndexer.php namespace AppBundle\EventListener; use Doctrine\ORM\Event\LifecycleEventArgs; use AppBundle\Entity\Product; class SearchIndexer { public function postPersist(LifecycleEventArgs $args) { $entity = $args->getEntity(); // only act on some "Product" entity if (!$entity instanceof Product) { return; } $entityManager = $args->getEntityManager(); // ... do something with the Product } }
This may be sufficient if you’re only monitoring the events for a single entity. But for larger applications, it gets tiresome performing a type-check for each entity type, for each event you want to handle. This is an issue whether you’re using event listeners or subscribers.
Enter the DoctrineEventManager bundle.
Using the Bundle, you can abstract away the type-checks and instead implement a different class for each listener. Here’s an example for solving the common task of setting setting creation and modification timestamps on entities, using the code from a handler in the bundle.
First, you create the event handler class:
namespace TravisUribe\DoctrineEventManagerBundle\EventListener\Handler; use Doctrine\ORM\Event\LifecycleEventArgs; use TravisUribe\DoctrineEventManagerBundle\Entity\Dated\DatedEntityInterface; class DatedEntityHandler extends AbstractEntityEventHandler { public function preUpdate (LifecycleEventArgs $args) { $this->prePersist($args); } public function prePersist (LifecycleEventArgs $args) { /** @var DatedEntityInterface $entity */ $entity = $args->getEntity(); if (!$entity->getCreated()) { $entity->setCreated(new \DateTime()); } if (!$entity->getChanged()) { $entity->setChanged($entity->getCreated()); } } public function getSupportedClasses () { return ['TravisUribe\DoctrineBundle\Entity\Dated\DatedEntityInterface']; } }
Second, you register the handler as a service using the turibe_doctrine.event_handler
tag:
services: turibe_doctrine.dated_entity_handler: class: TravisUribe\DoctrineEventManagerBundle\EventListener\Handler\DatedEntityHandler tags: - name: turibe_doctrine.event_handler