From d2a4676faacff3b2377a966bb5e0ef52bab435b8 Mon Sep 17 00:00:00 2001
From: Oliver Bartsch <bo@cedev.de>
Date: Sat, 5 Aug 2023 09:29:08 +0200
Subject: [PATCH] [BUGFIX] Expose listener identifier to ListenerProvider

The listener identifier is now exposed into
the ListenerProvider, making this information
available, e.g. in the configuration module.

Resolves: #101584
Releases: main, 12.4
Change-Id: I3dbcc4182532c6da0239d0e7bd715e081d1c283e
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/80401
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: core-ci <typo3@b13.com>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Andreas Fernandez <a.fernandez@scripting-base.de>
Reviewed-by: Andreas Fernandez <a.fernandez@scripting-base.de>
---
 .../ListenerProviderPass.php                  |  3 ++-
 .../EventDispatcher/ListenerProvider.php      |  4 ++--
 .../ListenerProviderPassTest.php              |  6 +++---
 .../EventDispatcher/ListenerProviderTest.php  | 20 +++++++++++++++++--
 4 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/typo3/sysext/core/Classes/DependencyInjection/ListenerProviderPass.php b/typo3/sysext/core/Classes/DependencyInjection/ListenerProviderPass.php
index 0651172eec30..aef2b63e9200 100644
--- a/typo3/sysext/core/Classes/DependencyInjection/ListenerProviderPass.php
+++ b/typo3/sysext/core/Classes/DependencyInjection/ListenerProviderPass.php
@@ -59,11 +59,12 @@ final class ListenerProviderPass implements CompilerPassInterface
 
         foreach ($unorderedEventListeners as $eventName => $listeners) {
             // Configure ListenerProvider factory to include these listeners
-            foreach ($this->orderer->orderByDependencies($listeners) as $listener) {
+            foreach ($this->orderer->orderByDependencies($listeners) as $listenerIdentifier => $listener) {
                 $listenerProviderDefinition->addMethodCall('addListener', [
                     $eventName,
                     $listener['service'],
                     $listener['method'],
+                    $listenerIdentifier,
                 ]);
             }
         }
diff --git a/typo3/sysext/core/Classes/EventDispatcher/ListenerProvider.php b/typo3/sysext/core/Classes/EventDispatcher/ListenerProvider.php
index d67de0693569..6abda1e412eb 100644
--- a/typo3/sysext/core/Classes/EventDispatcher/ListenerProvider.php
+++ b/typo3/sysext/core/Classes/EventDispatcher/ListenerProvider.php
@@ -49,9 +49,9 @@ class ListenerProvider implements ListenerProviderInterface
      * @param string|null $method
      * @internal
      */
-    public function addListener(string $event, string $service, string $method = null): void
+    public function addListener(string $event, string $service, string $method = null, string $identifier = null): void
     {
-        $this->listeners[$event][] = [
+        $this->listeners[$event][$identifier ?? $service] = [
             'service' => $service,
             'method' => $method,
         ];
diff --git a/typo3/sysext/core/Tests/Unit/DependencyInjection/ListenerProviderPassTest.php b/typo3/sysext/core/Tests/Unit/DependencyInjection/ListenerProviderPassTest.php
index 1e749df8d9a5..0465108eec32 100644
--- a/typo3/sysext/core/Tests/Unit/DependencyInjection/ListenerProviderPassTest.php
+++ b/typo3/sysext/core/Tests/Unit/DependencyInjection/ListenerProviderPassTest.php
@@ -68,17 +68,17 @@ final class ListenerProviderPassTest extends UnitTestCase
         self::assertEquals(
             [
                 'TYPO3\\CMS\\Core\\Mail\\Event\\AfterMailerInitializationEvent' => [
-                    [
+                    'package2.listener' => [
                         'service' => 'package2.listener',
                         'method' => 'onEvent',
                     ],
-                    [
+                    'legacy-hook' => [
                         'service' => 'package1.listener1',
                         'method' => null,
                     ],
                 ],
                 'TYPO3\\CMS\\Core\\Foo\\Event\\TestEvent' => [
-                    [
+                    'legacy-hook' => [
                         'service' => 'package3.listener',
                         'method' => null,
                     ],
diff --git a/typo3/sysext/core/Tests/Unit/EventDispatcher/ListenerProviderTest.php b/typo3/sysext/core/Tests/Unit/EventDispatcher/ListenerProviderTest.php
index 9ed8683f02c9..d6e94d5467db 100644
--- a/typo3/sysext/core/Tests/Unit/EventDispatcher/ListenerProviderTest.php
+++ b/typo3/sysext/core/Tests/Unit/EventDispatcher/ListenerProviderTest.php
@@ -55,8 +55,24 @@ final class ListenerProviderTest extends UnitTestCase
 
         self::assertEquals([
             'Event\\Name' => [
-                [ 'service' => 'listener1', 'method' => null ],
-                [ 'service' => 'listener2', 'method' => 'methodName' ],
+                'listener1' => [ 'service' => 'listener1', 'method' => null ],
+                'listener2' => [ 'service' => 'listener2', 'method' => 'methodName' ],
+            ],
+        ], $this->listenerProvider->getAllListenerDefinitions());
+    }
+
+    /**
+     * @test
+     */
+    public function addedListenerCorrectlySetsTheListenerIdentifier(): void
+    {
+        $this->listenerProvider->addListener(event: 'Event\\Name', service: 'service.name1');
+        $this->listenerProvider->addListener(event: 'Event\\Name', service: 'service.name2', identifier: 'listenerIdentifier2');
+
+        self::assertEquals([
+            'Event\\Name' => [
+                'service.name1' => [ 'service' => 'service.name1', 'method' => null ],
+                'listenerIdentifier2' => [ 'service' => 'service.name2', 'method' => null ],
             ],
         ], $this->listenerProvider->getAllListenerDefinitions());
     }
-- 
GitLab