vctls
vctls

Reputation: 735

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?

Upvotes: 10

Views: 5269

Answers (2)

vctls
vctls

Reputation: 735

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.

Upvotes: 9

DrKey
DrKey

Reputation: 3495

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.

Upvotes: 1

Related Questions