Doctrine in Symfony 2: Listening for Events from a Specific Object

I have an Entity Doctrine (News) in which I listen to the prePersist event. To do this, I use an event listener using the prePersist method.

My services.yml as follows:

 listener.entity.news: class: A\BBundle\Listeners\Entity\NewsListener tags: - { name: doctrine.event_listener, event: prePersist } 

It is beautiful and everything works. But the documentation states that when persist() called, the prePersist event is prePersist . Then when my NewsListener configuration NewsListener catch it and execute some code. Inside the method where I catch the event, I have to check if the event came from the News object. Here's where I wonder if Symfony can be told to listen for PrePersist events for a specific Entity and then pass it to my listener?

Currently (as I understand it), when the doctrine raises the prePersist event, all listeners are notified. Isn't it better to say which listeners should listen, which event producers, even if it should be optional, rather than notifying everyone and letting them filter the ones they need?

I hope I asked the question correctly.

+6
source share
4 answers

Can I tell Symfony to listen to PrePersist events for a particular Entity, and then pass it to my listener?

No, It is Immpossible. Your listener will shoot for each object that is saved. You need to do an instanceof check in the event listener to make sure that your code only works for a specific object.

+3
source

This is possible after Doctrine 2.4 with the Entity listenener function.

 namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\EntityListeners({"AppBundle\EntityListener\PostListener"}) */ class Post { } namespace AppBundle\EntityListener; use Doctrine\ORM\Mapping as ORM; class PostListener { public function preUpdate() { } // or /** @ORM\PreUpdate */ public function someOtherName() { } } 

What if I want to add a dependency to the listener? Is it possible?

Yes, it’s possible starting with DoctrineBundle 1.3. You just need to register the entity listener as a service and tag it with doctrine.orm.entity_listener tag.

 class PostListener { public function __construct(SomeDependency $someDependency) { } } services: app.post_listener: class: AppBundle\EntityListener\PostListener arguments: ["@app.some_dependency"] tags: - { name: doctrine.orm.entity_listener } 

Alternative method

With DoctrineBundle 1.5, you can register object listeners through tags , but this method has not yet been documented . This method does not require the listener to display with EntityListeners annotation.

 namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity */ class Post { } namespace AppBundle\EntityListener; class PostListener { public function __construct(SomeDependency $someDependency) { } public function preUpdate() { } public function someOtherName() { } } services: app.post_listener: class: AppBundle\EntityListener\PostListener arguments: ["@app.some_dependency"] tags: - { name: doctrine.orm.entity_listener, entity: AppBundle\Entity\Post, event: preUpdate } # or - { name: doctrine.orm.entity_listener, entity: AppBundle\Entity\Post, event: preUpdate, method: someOtherName } 
+4
source

Depending on what you are doing in your listener, you can use lifecycle callbacks in the News object and implement the prePersist hook.

http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/events.html#lifecycle-callbacks

Thus, the listener will only be called for the instance that is currently being stored.

0
source

Source: https://habr.com/ru/post/908165/


All Articles