es3zkw
Last Updated: February 25, 2016
·
4.618K
· zoltanradics
360

Symfony2 - Listen Doctrine events

In this ProTip i will show you how to listen Doctrine events so you can track whenever your application interacts with the database. It may can be helpful if you want to create a custom log workflow.

First of all, we will register a service. Add the following example to your bundle's services.yml. (Vendor/ExampleBundle/Resources/config/services.yml) In this example i will dispatch 2 events.

# Listen Doctrine events
vendor.example_bundle.listener.doctrine:
  class: Vendor\ExampleBundle\Service\DoctrineListenerService
  arguments: ['@service_container']
  tags:
    - { name: doctrine.event_listener, event: postUpdate }
    - { name: doctrine.event_listener, event: postPersist }

And now we are creating the listener class

namespace Vendor\ExampleBundle\Service;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Symfony\Component\DependencyInjection\ContainerInterface;

class DoctrineListenerService implements EventSubscriber
{

  protected $container;

  public function __construct(ContainerInterface $container)
  {
    $this->container = $container;
  }

  public function getSubscribedEvents() 
  {
    return array(
      'postPersist',
      'postUpdate',
    );
  }

  /**
   * This method will called on Doctrine postPersist event
   */
  public function postPersist(LifecycleEventArgs $args)
  {
    # Avoid to log the logging process
    if (!$args->getEntity() instanceof Log)
      # Handle the log creation
      $this->createLog($args, 'persist');
  }

  /**
   * This method will called on Doctrine postUpdate event
   */
  public function postUpdate(LifecycleEventArgs $args)
  {
    # Handle the log creation
    $this->createLog($args, 'update');
  }

  /**
   * Handle the log creation
   */
  public function createLog(LifecycleEventArgs $args, $action)
  {
    # Entity manager
    $em = $args->getEntityManager();
    $entity = $args->getEntity();

    # Set DateTime()
    $dateTime = new \DateTime();

    # Get user
    if (method_exists($this->container->get('security.context'), 'getUser')):

      # Get current user
      $user = $this->container->get('security.context')->getToken()->getUser();

      # ... Do some logging action

    endif;
  }

}

Here are the events you can dispactch as well

  • prePersist
  • preRemove
  • preFlush
  • onFlush
  • postFlush
  • preUpdate
  • postUpdate
  • postRemove
  • postPersist
  • postLoad
Say Thanks
Respond

10 Responses
Add your response

16422
3168e28fdb38c81f59cce6c1d28bcf52

Hi, are you sure that your code work with symfony2?
I tried to check this code, but not work! :S
Thanks

over 1 year ago ·
16425
360

Hello there, i copied this code from one of my project, so it is already implemented. What is the error message in your app?

over 1 year ago ·
16442
3168e28fdb38c81f59cce6c1d28bcf52

Thanks for your reply.
I'm not getting any error. Simply does not seem to capture the event.
If I put a die(); inside postPersist() the process does not die.
I use symfony2.5 and in my entity I added the annotation @ORM\HasLifecycleCallbacks.
Thank you
Regards

over 1 year ago ·
16443
360

In that case you did not register the service properly. So finally did you solve another way?!

over 1 year ago ·
16447
3168e28fdb38c81f59cce6c1d28bcf52

I checked the more recording of the service and now it works!
Thank you very much!

over 1 year ago ·
16448
360

No probs. Feel free to ask it any help needs!

over 1 year ago ·
26350

Hi there!
It has been 2/3 years, but it is never too late, if we can learn something, isn't it?
I hope my english will be enough for commenting... :P
I was wondering how to Avoid to log the logging process...

if  ( !$args->getEntity() instanceof Log )

... and I can't find de Log Class...

I'm working in a simfony 2.8 app... no sugestions from the IDE, and i can only find Event Listeners, Event Subscribers, Loggers, but not a Log.

Is it a Monolog Class, or is it part of some kernel component?
I have to confess that I didn't read enough documentation about the subject yet.... but it is kind of strange I can't get any quick reference for it...

Any help about this Class?
Thanks in advance!

over 1 year ago ·
26354
360

@rrdavik: Log was a custom entity in my application. It was responsible to store records in the database when Doctrine updated or persisted objects. You can use Monolog or any other logger class instead. Cheers!

over 1 year ago ·
26356

Thanks for the quick answer...
Approaching I was going to read determined logs... and i didn't see clear how to do this... I ended creating the log entity to persist all the logging processes in Database and monitoring my test cases.
Also it is a useful event tracking functionality for my App...

over 1 year ago ·
26357
360

@rrdavik: Exactly. I used Log entity for the same. I wanted to give this possibility to the system andiminstrators to review the interactions of the single users.

over 1 year ago ·