Problem/Motivation
Following #3055198: [Symfony 5] Symfony/Component/EventDispatcher/Event is deprecated in Symfony 4.3 use Symfony/Contracts/EventDispatcher/Event instead and #3055194: [Symfony 5] The signature of the "Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher::dispatch()" method should be updated to "dispatch($event, string $eventName = null)", not doing so is deprecated since Symfony 4.3. Drupal core will no longer have an explicit dependency on the Symfony EventDispatcher Event class which was deprecated in Symfony 4 and replaced by an identical class in the Symfony/Contracts namespace.
However, Symfony Event's own classes (like GenericEvent) still inherit from the deprecated class, and some of Drupal's classes like EntityTypeEvent inherit from GenericEvent.
Because GenericEvent is going to stay in EventDispatcher in Symfony 5 (with the use statement updated), there is no need for any classes inheriting from GenericEvent to do anything - they'll get 'auto-updated' when we update to Symfony 5.
However, this presents a twofold problem:
1. We are currently suppressing Symfony's deprecation message, and there is no way to un-suppress this while the Symfony/EventDispatcher version is in use.
2. This means we're not able to inform people about the bridge Event class added in #3055198: [Symfony 5] Symfony/Component/EventDispatcher/Event is deprecated in Symfony 4.3 use Symfony/Contracts/EventDispatcher/Event instead until at least both of those issues are complete.
Proposed resolution
Check the inheritance chain in Drupal's ContainerAwareEventDispatcher::dispatch(), and selectively trigger deprecation messages for the deprecated Event class - we need to allow Symfony subclasses and Drupal's new event class to be used without triggering a deprecation message, since those will be changed when we update to Symfony 5, but can't be before that.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
The Symfony\Component\EventDispatcher\Event class has been deprecated and the order of parameters for dispatching events has changed, see https://www.drupal.org/node/3159012 for details.
| Comment | File | Size | Author |
|---|---|---|---|
| #36 | 3153803-36.patch | 5.84 KB | catch |
| #36 | 3153803-36-interdiff.txt | 1.16 KB | catch |
| #34 | 3153803-34.patch | 5.71 KB | catch |
| #34 | interdiff.txt | 1.2 KB | catch |
| #31 | 3153803-23.patch | 5.37 KB | krzysztof domański |
Comments
Comment #2
catchHere's an attempt, depends on the two issues mentioned above.
Test coverage is outstanding, but need to see whether this is even possible first. EventDispatcher tests themselves pass.
Comment #4
catchNeed to update the use statement in DrupalKernel.
Comment #5
catchSlightly amazed that works, but not complaining.
Here's test coverage.
Comment #6
catchUndoing one change here - the bc layer should I think be able to continue instantiating the old class. It shouldn't instantiate the contracts version, because that could break existing type hints. If for some reason the legacy class causes problem we could change it to the Drupal bridge Event class instead.
Comment #7
catchAdded a change record: https://www.drupal.org/node/3159012
Comment #8
catchComment #9
catchComment #10
catchThis is actually critical since it doesn't only add the deprecation notices but also allows contrib to use Symfony 5-style event dispatching.
Comment #11
andypostCR could be polished to explain that dispatch() is not so strict
As I see line 7 still using SF Event class?!
Comment #12
longwaveNeeds reroll following #3055198: [Symfony 5] Symfony/Component/EventDispatcher/Event is deprecated in Symfony 4.3 use Symfony/Contracts/EventDispatcher/Event instead
Comment #13
catchIt is, but it's only used in the backwards compatibility layer. We can't use the contracts version, because that would break existing event listeners that type hint on the old class. We could use the new Drupal bridge class, but I there is not a pressing need to.
Comment #14
catchPatch here was stacked on that issue, but no proper conflicts as such so just a straight re-roll with the already-applied hunks (hopefully).
edit: hmm, either I lost track of what's in each patch, or literally some bits from this patch crept into the patch on that issue - so we just have test coverage added here now...
Comment #15
catchHmm even the new test method landed, is it just the use-statement change?
Comment #16
longwaveThe new deprecation (both versions) are not yet committed, I had to manually reconstruct this as patch thinks these hunks are already committed but really it was only the first few lines of each hunk.
Comment #17
catchOK I was so confused, patch relying on the first few lines to see if a hunk was already applied is... understandable but unreliable. #16 looks like what I was expecting to be left with here.
Comment #19
catchDrupalKernel was still using the deprecated Symfony Event class, that should help with a lot of the test failures.
Comment #20
kim.pepperCan we add a “see” to the CR in the deprecation message?
Comment #21
catchAdd the link to the deprecation message.
Comment #22
kim.pepperNice. RTBC+1
Comment #23
andypostBetter to prevent to compare strings twice if not needed
Comment #24
catch#23 is a good change.
Comment #25
krzysztof domańskiIgnore
Comment #26
krzysztof domański1. Combine code that triggers the same deprecation message.
2. Trigger
"Symfony\Component\EventDispatcher\Event is deprecated..."regardless of the argument order.Comment #27
longwaveFWIW I think the combined if statement is much harder to read, I don't think it's necessary to combine here.
Comment #28
krzysztof domański@longwave Thanks for review. What about #26.2?
Comment #29
krzysztof domański1. Trigger
"Symfony\Component\EventDispatcher\Event is deprecated..."regardless of the argument order.Comment #30
krzysztof domańskiFix coding standards.
Comment #31
krzysztof domańskiIgnore my previous patches (redundant changes).
#23 looks good. Reuploaded patch #23.
Comment #32
alexpottWe just had an issue that removed calls to get_class... See #2619482: Convert all get_called_class()/get_class() to static::... looks like we introduced one above already. Whoops.
Also if we going to get the events class let's do this once.
So I think we can do
I'm umming and ahhing about this. I know that there is an effort to use PHPCS to standardise our deprecation messages so sticking them in variables doesn't help. I guess we can move this if that happens.
Can this be
If we add
use Drupal\Component\EventDispatcher\Event as DrupalEvent;.As far as I can see any Symfony events will be using the new Contracts event class. If I change the code to this the test still passes.
Comment #33
thallesHello everyone!
In
Drupal\Component\EventDispatcher,Symfony\Component\EventDispatcher\Eventshould be replaced?Comment #34
catch#32.1
This doesn't work, get_class() is correct afaik:
https://3v4l.org/lRG0v
#32.2 yes would prefer to delay duplicating the text until it's required for phpcs.
#33.3 This doesn't work - GenericEvent for example in Symfony 4, extends from the old Symfony Event class. In Symfony 5, they changed the use statement to contracts.
We can't do anything about that from Drupal, so we have to trigger a deprecation message only when the old Event class, or a direct Drupal subclass of the old event class (that isn't DrupalEvent) is dispatched.
There is a lot of implicit test coverage of this (see here where I made the change: https://www.drupal.org/project/drupal/issues/933404#comment-13758987), but no explicit test coverage, so I added some.
Comment #35
alexpott@catch thanks for working through #34 and adding the extra test.
This can optimised - given we're going to be calling get_class() no matter what.
Comment #36
catchAddressing #35, I had this change locally but it didn't make it into the patch :/
Comment #37
krzysztof domańskiComment #38
alexpottCommitted f3f320a and pushed to 9.1.x. Thanks!