From f3f320a78f8adad8b9ef0b5584287d91c754ba2b Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Fri, 24 Jul 2020 14:16:04 +0100 Subject: [PATCH] =?UTF-8?q?Issue=20#3153803=20by=20catch,=20Krzysztof=20Do?= =?UTF-8?q?ma=C5=84ski,=20andypost,=20longwave,=20kim.pepper,=20alexpott:?= =?UTF-8?q?=20[Symfony=205]=20Update=20EventDispatcher::dispatch()=20to=20?= =?UTF-8?q?make=20it=20forward-compatible=20with=20Symfony=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ContainerAwareEventDispatcher.php | 21 +++++++++- core/lib/Drupal/Core/DrupalKernel.php | 2 +- .../ContainerAwareEventDispatcherTest.php | 39 ++++++++++++++++++- 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php index 59c165720ad4..0cf5669543cd 100644 --- a/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php +++ b/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php @@ -91,7 +91,26 @@ public function __construct(ContainerInterface $container, array $listeners = [] public function dispatch($event/*, string $event_name = NULL*/) { $event_name = 1 < \func_num_args() ? func_get_arg(1) : NULL; if (\is_object($event)) { - $event_name = $event_name ?? \get_class($event); + $class_name = get_class($event); + $event_name = $event_name ?? $class_name; + + $deprecation_message = 'Symfony\Component\EventDispatcher\Event is deprecated in drupal:9.1.0 and will be replaced by Symfony\Contracts\EventDispatcher\Event in drupal:10.0.0. A new Drupal\Component\EventDispatcher\Event class is available to bridge the two versions of the class. See https://www.drupal.org/node/3159012'; + + // Trigger a deprecation error if the deprecated Event class is used + // directly. + if ($class_name === 'Symfony\Component\EventDispatcher\Event') { + @trigger_error($deprecation_message, E_USER_DEPRECATED); + } + // Also try to trigger deprecation errors when classes are in the Drupal + // namespace and inherit directly from the deprecated class. If a class is + // in the Symfony namespace or a different one, we have to assume those + // will be updated by the dependency itself. Exclude the Drupal Event + // bridge class as a special case, otherwise it's pointless. + elseif ($class_name !== 'Drupal\Component\EventDispatcher\Event' && strpos($class_name, 'Drupal') !== FALSE) { + if (get_parent_class($event) === 'Symfony\Component\EventDispatcher\Event') { + @trigger_error($deprecation_message, E_USER_DEPRECATED); + } + } } elseif (\is_string($event) && (NULL === $event_name || $event_name instanceof ContractsEvent || $event_name instanceof Event)) { @trigger_error('Calling the Symfony\Component\EventDispatcher\EventDispatcherInterface::dispatch() method with a string event name as the first argument is deprecated in drupal:9.1.0, an Event object will be required instead in drupal:10.0.0. See https://www.drupal.org/node/3154407', E_USER_DEPRECATED); diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index c52b1ec26f05..dcf20841da6f 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -4,7 +4,7 @@ use Composer\Autoload\ClassLoader; use Drupal\Component\Assertion\Handle; -use Symfony\Component\EventDispatcher\Event; +use Drupal\Component\EventDispatcher\Event; use Drupal\Component\FileCache\FileCacheFactory; use Drupal\Component\Utility\UrlHelper; use Drupal\Core\Cache\DatabaseBackend; diff --git a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php index facac8776afa..31fb5a5f8fd7 100644 --- a/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php +++ b/core/tests/Drupal/Tests/Component/EventDispatcher/ContainerAwareEventDispatcherTest.php @@ -7,8 +7,10 @@ use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ContainerInterface; -use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\EventDispatcher\Event as SymfonyEvent; +use Symfony\Component\EventDispatcher\GenericEvent; +use Drupal\Component\EventDispatcher\Event; /** * Unit tests for the ContainerAwareEventDispatcher. @@ -152,6 +154,39 @@ public function testDispatchArgumentOrderDeprecation() { $dispatcher->dispatch('foo'); } + /** + * Tests deprecation notice for Symfony Event class. + * + * @group legacy + * @expectedDeprecation Symfony\Component\EventDispatcher\Event is deprecated in drupal:9.1.0 and will be replaced by Symfony\Contracts\EventDispatcher\Event in drupal:10.0.0. A new Drupal\Component\EventDispatcher\Event class is available to bridge the two versions of the class. See https://www.drupal.org/node/3159012 + */ + public function testSymfonyEventDeprecation() { + $container = new ContainerBuilder(); + $dispatcher = new ContainerAwareEventDispatcher($container, []); + $dispatcher->dispatch(new SymfonyEvent()); + } + + /** + * Tests dispatching Symfony events with core's event dispatcher. + */ + public function testSymfonyEventDispatching() { + $container = new ContainerBuilder(); + $dispatcher = new ContainerAwareEventDispatcher($container, []); + $dispatcher->dispatch(new GenericEvent()); + } + + /** + * Tests deprecation notice for Symfony Event class inheritance. + * + * @group legacy + * @expectedDeprecation Symfony\Component\EventDispatcher\Event is deprecated in drupal:9.1.0 and will be replaced by Symfony\Contracts\EventDispatcher\Event in drupal:10.0.0. A new Drupal\Component\EventDispatcher\Event class is available to bridge the two versions of the class. See https://www.drupal.org/node/3159012 + */ + public function testSymfonyInheritedEventDeprecation() { + $container = new ContainerBuilder(); + $dispatcher = new ContainerAwareEventDispatcher($container, []); + $dispatcher->dispatch(new SymfonyInheritedEvent()); + } + public function testDispatchWithServices() { $container = new ContainerBuilder(); $container->register('listener_service', TestEventListener::class); @@ -612,3 +647,5 @@ public static function getSubscribedEvents() { } } + +class SymfonyInheritedEvent extends SymfonyEvent {} -- GitLab