When we updated to Symfony 2.8 in #2611816: Update to symfony 2.8 we didn't implement the getListenerPriority() method on ContainerAwareEventDispatcher, probably because it was not required on the interface.

Unfortunately the omission of this method on the interface is a bug in Symfony, since the method is being actively used. This has been fixed in Symfony 3.0 in Issue #16301: [EventDispatcher] add method getListenerPriority() to interface but it is not clear if this will be backported to 2.8.

Marking this as a bug since it is already breaking contrib (e.g. #2682343: Fatal error enabling web profiler on 8.1.x). We'll have to implement this anyway before Drupal 8.2.x which will depend on Symfony 3.0, but it would be good to have this in earlier.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

pfrenssen created an issue. See original summary.

thePanz’s picture

Patch attached implementing the missing method.
The two lines

    $event->setDispatcher($this);
    $event->setName($event_name);

have been removed since those calls are deprecated since Symfony 2.4 (and will be removed in Symfony 3.x)

thePanz’s picture

thePanz’s picture

Status: Active » Needs review

Status: Needs review » Needs work
hswong3i’s picture

Priority: Normal » Major

Confirm that it also break CLI usage with drush-8.1.0. I am now temporary apply this patch for https://www.drupal.org/project/drustack

Berdir’s picture

Confirmed that this fixes the problem that I had with webprofiler enabled.

However, not sure about the removal of the deprecated calls. That's unrelated and might be causing those test fails. We can deal with that when updating to 3.0, if we actually do that.

thePanz’s picture

Patch updated against latest 8.1.x branch, the deprecated calls have been restored as @berdir suggested.
Let's see if TestBot is happy again :)

dawehner’s picture

Sure, why not.

It would be nice if we could expand the test coverage, I guess there is some existing test code in symfony we could just copy?

klausi’s picture

Issue summary: View changes

Fixed link.

klausi’s picture

Version: 8.1.x-dev » 8.2.x-dev
FileSize
2.82 KB
2.62 KB

Test coverage is an excellent idea as it turns out that the implementation is broken.

Fixed that plus:
1) Enabled testGetListenerPriority() from Symfony.
2) Added testGetListenerPriorityWithServices() because we do this lazy service instantiation thing in our event dispatcher, which needs to work in every method.

klausi’s picture

Making Symfony 3 update the parent issue of this.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Looks good to me. Thanks @klausi.

catch’s picture

Status: Reviewed & tested by the community » Needs work
  1. +++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
    @@ -159,6 +159,32 @@ public function getListeners($event_name = NULL) {
    +      if (FALSE !== ($key = array_search(['callable' => $listener], $listeners, TRUE))) {
    

    No yoda conditions please.

  2. +++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
    @@ -159,6 +159,32 @@ public function getListeners($event_name = NULL) {
    +
    

    Extra blank line.

  3. +++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
    @@ -159,6 +159,32 @@ public function getListeners($event_name = NULL) {
    +          $definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
    

    Needs a comment as to why we're setting the callable as well as returning the priority. The interface docs mention nothing about this for example.

klausi’s picture

Yoda conditions: this is code copied from Symfony, so we should add a comment: "// Code copied from Symfony, that's why we use yoda conditions here."

The blank line between functions should there, it is just the diff that looks weird.

Setting the callable: this is the lazy loading our Drupal specific implementation does. For the comparison we need the callable, and for subsequent calls we cache it on the object, as we do in the other methods of this class. Comment should be "// Cache the callable here to have it read on subsequent invocations."

klausi’s picture

Status: Needs work » Needs review
FileSize
3.05 KB
1.19 KB

Added those comments.

jibran’s picture

Status: Needs review » Reviewed & tested by the community

Ok. Let's see what @catch thinks about it now.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 16: event-dispatcher-2682373-16.patch, failed testing.

jibran’s picture

Status: Needs work » Reviewed & tested by the community

Random fail.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 16: event-dispatcher-2682373-16.patch, failed testing.

klausi’s picture

Status: Needs work » Reviewed & tested by the community

The usual random migrate module fail, back to RTBC.

  • catch committed da66242 on 8.2.x
    Issue #2682373 by klausi, thePanz: Implement...
catch’s picture

Status: Reviewed & tested by the community » Fixed

Not convinced about copying the yoda condition from Symfony, feels like a slippery slope. But easy to reverse in a minor coding standards issue another time and the parent issue is very important.

+++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php
@@ -159,6 +159,36 @@ public function getListeners($event_name = NULL) {
+    }
+    // Resolve service definitions if the listener has not been found so far.
+    foreach ($this->listeners[$eventName] as $priority => &$definitions) {
+      foreach ($definitions as $key => &$definition) {
+
+        if (!isset($definition['callable'])) {

That's not between a function, but fixed on commit.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.