How to create an Event Listener when an entity is persisted

I am really new to Event Listeners on Symfony and I want to find a nice way to trigger an event when a specific entity (i.e user) is persisted.

I have searched through the documentation and although I found references to onKernel events I am wasn't able to create a listener for what I need. Can you please point me to the right direction or give me an example?

Upvotes: 2

Views: 9626

Answers (3)

user15539096
user15539096

Reputation: 21

For completeness:

If you only need to handle 1 lifecycle event (e.g. prePersist) on 1 entity class (e.g. User), you can use any of the 4 options documented at https://symfony.com/doc/4.4/doctrine/events.html, but probably the more appropriate are a lifecycle callback or an entity listener.

Example of lifecycle callback:

In your entity:

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks  <-- DO NOT FORGET TO ADD THIS
 */
class User
{
    /* properties, getters/setters... */

    /**
     * @ORM\PrePersist
     */
    public function onPrePersist(): void
    {
        /* write your logic here */
    }
}

(note that you can't inject services).

Example of entity listener:

(1) New class:

namespace App\EventListener;

use App\Entity\User;
use Doctrine\Persistence\Event\LifecycleEventArgs;

class UserPrePersistListener
{
    public function __construct(/* you can inject services here */)
    {
        /* ... */
    }

    public function __invoke(User $user, LifecycleEventArgs $event): void
    {
        /* write your logic here */
    }
}

(2) Config:

services:
    # ...

    App\EventListener\UserPrePersistListener:
        tags: [{ name: doctrine.orm.entity_listener, entity: App\Entity\User, event: prePersist }]

If you need to handle 1 lifecycle event on 2+ entity classes, use a lifecycle listener.

If you need to handle 2+ lifecycle events on 1 entity class, or 2+ lifecycle events on 2+ entity classes, use a lifecycle subscriber.

Upvotes: 2

Masoud Jahromi
Masoud Jahromi

Reputation: 135

You should implement from EventSubscriber class and you can using following events:

prePersist, preUpdate, postPersist, postUpdate

Example:

ApplicationBundle/EventSubscriber/EntitySubscriber.php

namespace App\ApplicationBundle\EventSubscriber;

use Doctrine\Common\EventSubscriber;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;

/**
 * Class EntitySubscriber
 */
class EntitySubscriber implements EventSubscriber
{

    /**
     * Get subscribed events
     *
     * @return array
     */
    public function getSubscribedEvents()
    {
        return [
            'preUpdate',
        ];
    }

    /**
     * @param LifecycleEventArgs $args
     */
    public function preUpdate(LifecycleEventArgs $args)
    {
        /** @var PreUpdateEventArgs $args */
        $entity  = $args->getEntity();
        $changes = $args->getEntityChangeSet();
        dump($changes);
    }
}

Upvotes: 1

kunicmarko20
kunicmarko20

Reputation: 2180

This is quite well documented here.

You basically create a class that implements Doctrine\Common\EventSubscriber and then you have a method getSubscribedEvents() where you add events that you want to trigger it, it would look like:

public function getSubscribedEvents()
{
    return ['postPersist'];
}

public function postPersist(LifecycleEventArgs $args)
{
    $object = $args->getEntity();

    if (!$object instanceof User) {
        return;
    }

    $this->doSomething($object);
}

Upvotes: 5

Related Questions