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