1

In Drupal 8 is possible to use event subscriber that is the separate class that defines the callback that should be called on the defined event. See Event Systems Overview & How To Subscribe To and Dispatch Events

But I'm wondering how to define event listener that will trigger the method of the service on the desired event?

here Symfony references:

Events and Event Listeners

Built-in Symfony Events

2
  • 1
    You can't define an event listener in a service (that wouldn't make sense, what's guaranteeing that the service has even been instantiated when the event is raised?). But you can inject a service into the event listener, and call a method on it that way, which achieves the same thing
    – Clive
    Commented Sep 19, 2018 at 14:29
  • 1
    You could point an event listener to any php callable, but Drupal doesn't use event listeners, only subscribers. An event subscriber class is always a service, implementing getSubscribedEvents() to define which class method to trigger on the desired event.
    – 4uk4
    Commented Sep 19, 2018 at 16:45

1 Answer 1

2

If I understood correctly, I think you are asking about implementing minimalistic single responsibility event listeners declared in the YML config file, like in this Java example:

class MyListener implements ActionListener {
  public void actionPerformed(ActionEvent e) {
    myTextArea.append('Hello from MyListener');
  }
}

That is not possible since this is this what the EventDispatcher actually does:

    public function addSubscriber(EventSubscriberInterface $subscriber)
    {
        foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
            if (is_string($params)) {
                $this->addListener($eventName, array($subscriber, $params));
            } elseif (is_string($params[0])) {
                $this->addListener($eventName, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
            } else {
                foreach ($params as $listener) {
                    $this->addListener($eventName, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
                }
            }
        }
    }

You can still have your separate ActionListener's, but you would have to write some code to call them from your implementation of EventSubscriberInterface.

2
  • I guess it is the correct answer. But also, it worth to mention that better implement EventSubscriberInterface in the service where the event callback will be placed and add the tag - { name: event_subscriber } in *.services.yml file. In the result we have a service and the event callback in the same place.
    – voleger
    Commented Sep 20, 2018 at 14:41
  • @voleger, since this is the correct answer, would you please mark it as the answer. Thank you! Commented Sep 21, 2018 at 13:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.