Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Doctrine Bridge remove event subscriber (listener) registered with a service definition #52322

Copy link
Copy link
Open
@rela589n

Description

@rela589n
Issue body actions

Symfony version(s) affected

6.2

Description

It seems that it it not possible to disable the listener using EventManager. For particular case I want to disable SoftDeleteableListener from gedmo library. It is registered in the container as gedmo.listener.softdeleteable service (see steps to reproduce).

In order to disable it, I inject this listener into the custom service and call removeEventSubscriber(). It turns out to be that listener is still present in EventManager and executes onFlush().

Would be nice to fix the ability to disable event listeners, since doctrine supports it.

How to reproduce

Register listener:

    gedmo.listener.softdeleteable:
        class: Gedmo\SoftDeleteable\SoftDeleteableListener
        tags:
            - { name: doctrine.event_listener, event: 'onFlush' }
            - { name: doctrine.event_listener, event: 'loadClassMetadata' }
        calls:
            - [ setAnnotationReader, [ "@annotation_reader" ] ]

Create service to disable softdeleteable:


final class ConditionalSoftDelete
{
    private SoftDeleteableListener $listener;

    #[Required]
    public function setListener(SoftDeleteableListener $softDeleteableListener): void
    {
        $this->listener = $softDeleteableListener;
    }

    public function disableListener(EntityManagerInterface $entityManager)
    {
        $entityManager
            ->getEventManager()
            ->removeEventSubscriber($this->listener);
    }
}

In the client code call $conditionalSoftDelete->disableListener().
After that try to remove entity having soft deleteable attribute via entity manager: $em->remove($entity);
See in the database that entity was never removed, but was updated (deletedAt field was populated).

Possible Solution

No response

Additional Context

Debugging showed that removeEventSubscriber() doesn't work, since ContainerAwareEventManager::getHash() method returns spl_object_hash of the object, while listener was registered with string:

    private function getHash(string|object $listener): string
    {
        if (\is_string($listener)) {
            return '_service_'.$listener; // listener registered with this has 
        }

        return spl_object_hash($listener); // we are trying to disable by this hash
    }

Therefore, it disables nothing, and we still have listener enabled.

image

As you can see on the screenshot, hash key is _service_gedmo.listener.softdeleteable, while real hash (object) is 00000000000003450000000000000000.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.