Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony, Doctrine: how to disable Entity Listeners?

I need to persist some fixtures with Alice Fixtures Bundle, without triggering a specific Entity Listener.
The listener is associated with my entity through the EntityListeners annotation.
I'd rather not change the listener itself.

I've created a custom Loader which has access to the container, hoping to disable all listeners before creating my objects.

I've tried this answer already, but $em->getEventManager()->getListeners() doesn't return Entity Listeners.

ClassMetadata gives me a list of subscribed Entity Listeners for that entity, but it's just a read-only array.

Is there a way of disabling those Entity Listeners?

like image 562
vctls Avatar asked Nov 27 '18 14:11

vctls


2 Answers

I found a way.
This is what I do in my loader:

$em = $this->container->get('doctrine.orm.default_entity_manager');

$entitiesWithListeners = [
    Post::class,
    Comment::class
];

$listenersToDisable = [
    MyListener::class
];

foreach ($entitiesWithListeners as $entity) {
    $metadata = $em->getMetadataFactory()->getMetadataFor($entity);

    foreach ($metadata->entityListeners as $event => $listeners) {
        
        foreach ($listeners as $key => $listener) {
            if (in_array($listener['class'], $listenersToDisable)) {
                unset($listeners[$key]);
            }
        }
        $metadata->entityListeners[$event] = $listeners;
    }
    $em->getMetadataFactory()->setMetadataFor($entity, $metadata);
}

I simply get the metadata for each entity, strip it of my Entity Listeners, and set it back to its corresponding class.

It's ugly but hey, it works. Since I'm stuck with AliceBundle v1.4 at the moment, and I will have to change everything when we update the project, this will do.

like image 104
vctls Avatar answered Nov 14 '22 15:11

vctls


You can use EntityListenerResolver API

$em->getConfiguration()->getEntityListenerResolver()->clear();

or if you want to clear listener of specific class

$em->getConfiguration()->getEntityListenerResolver()->clear(YourEntityListener::class);

Refer to EntityListenerResolver interface for more info.

like image 20
DrKey Avatar answered Nov 14 '22 13:11

DrKey