Md. Kausar Alam
Md. Kausar Alam

Reputation: 127

Why listener setting in service.yml in symfony not working?

app/config/services.yml

services:    
    myApp.event_listener:
        class: Test\EventListener\MyListener
        tags:
            - { name: myApp.event_listener, event: onDoSomething }

namespace Test\EventListener

use Test\Event\MyEvent;

class MyListener 
{
    public function onDoSomething(MyEvent $event)
    {
        echo "I m on listener";
    }
}

namespace Test\Event;

use TEST\Entity\MyEntity;
use Symfony\Component\EventDispatcher\Event;

class MyEvent extends Event 
{
    const DO_SOMETHING = 'event.do_something';

    protected $myEntity;

    public function __construct(MyEntity $myEntity)
    {
        $this->myEntity = $myEntity;
    }

    public function getMyEntity()
    {
        return $this->myEntity;
    }
}

From Controller:

$dispatcher = new EventDispatcher();
$dispatcher->dispatch(MyEvent::DO_SOMETHING, new Event());

Can you guy help why it can't add this event into the listener?

Upvotes: 0

Views: 3058

Answers (1)

lordrhodos
lordrhodos

Reputation: 2745

please read the documentation about event listener . Depending on the event you want to listen you will need to fix your tag declaration in the service definition. This is an example if you want to listen to a kernel event:

yaml

# app/config/services.yml
services:
    app.exception_listener:
        class: AppBundle\EventListener\ExceptionListener
        tags:
            - { name: kernel.event_listener, event: kernel.exception }

If you want to listen to a custom event, you need to create an appropriate event class beforehand and maybe using the method attribute of the tag definition, as described in the docs:

There is an optional tag attribute called method which defines which method to execute when the event is triggered. By default the name of the method is on + "camel-cased event name". If the event is kernel.exception the method executed by default is onKernelException().

If you want to create and dispatch your own event, please read the documentation about the EventDispatcher component.

You will need to fix several issues in your code!

the service definition of your event listener should use the tag name kernel.event_listener and the name of your event (MyEvent::DO_SOMETHING) which is event.do_something:

services:    
    myApp.event_listener:
        class: Test\EventListener\MyListener
        tags:
            - { name: kernel.event_listener, event: event.do_something }

The method in your listener which would be called without specifying the method parameter is onEventDoSomething

use Test\Event\MyEvent;

class MyListener 
{
    public function onEventDoSomething(MyEvent $event)
    {
        echo "I m on listener";
    }
}

In your controller you should get the dispatcher from the container, create an instance of your MyEvent class and pass the entity it (see the Events constructor):

/** @var $dispatcher EventDispatcherInterface */
$dispatcher = $this->get('event_dispatcher');
$event = new MyEvent($myEntity);
$dispatcher->dispatch(MyEvent::DO_SOMETHING, $event);

As @Cerad commented: if you want to create a new dispatcher instance you do not need the service definition, but you would need to add the listener to the new dispatcher:

// create dispatcher and add listener to it
$dispatcher = new EventDispatcher();
$listener = new MyListener();
$dispatcher->addListener('event.do_something', array($listener, 'onEventDoSomething'));

// dispatch event
$event = new MyEvent($myEntity);
$dispatcher->dispatch(MyEvent::DO_SOMETHING, $event);

Upvotes: 1

Related Questions