From c1fc323ffb3d7567d7dc26f2a6187731d88dcb8d Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Fri, 9 Dec 2022 10:04:20 +0200 Subject: [PATCH 1/9] Remove dispatcher dependency --- libraries/src/Extension/PluginInterface.php | 9 +- libraries/src/Plugin/CMSPlugin.php | 105 ++++++++++++++---- libraries/src/Plugin/PluginHelper.php | 43 ++++--- .../Libraries/Cms/Plugin/CMSPluginTest.php | 67 +++++++++++ 4 files changed, 188 insertions(+), 36 deletions(-) diff --git a/libraries/src/Extension/PluginInterface.php b/libraries/src/Extension/PluginInterface.php index 256bdddd87067..a805c3df030ed 100644 --- a/libraries/src/Extension/PluginInterface.php +++ b/libraries/src/Extension/PluginInterface.php @@ -10,6 +10,7 @@ namespace Joomla\CMS\Extension; use Joomla\Event\DispatcherAwareInterface; +use Joomla\Event\DispatcherInterface; // phpcs:disable PSR1.Files.SideEffects \defined('JPATH_PLATFORM') or die; @@ -19,15 +20,21 @@ * Access to plugin specific services. * * @since 4.0.0 + * + * @todo In 6.0 class will no longer extend DispatcherAwareInterface */ interface PluginInterface extends DispatcherAwareInterface { /** * Registers its listeners. * + * @param ?DispatcherInterface Dispatcher instance to register listeners with + * * @return void * * @since 4.0.0 + * + * @todo In 6.0 $dispatcher argument will no longer be nullable */ - public function registerListeners(); + public function registerListeners(?DispatcherInterface $dispatcher = null); } diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index 5ce566686e8c9..fd593732a8306 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -13,7 +13,6 @@ use Joomla\CMS\Extension\PluginInterface; use Joomla\CMS\Factory; use Joomla\Event\AbstractEvent; -use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherAwareTrait; use Joomla\Event\DispatcherInterface; use Joomla\Event\EventInterface; @@ -29,7 +28,7 @@ * * @since 1.5 */ -abstract class CMSPlugin implements DispatcherAwareInterface, PluginInterface +abstract class CMSPlugin implements PluginInterface { use DispatcherAwareTrait; @@ -91,15 +90,31 @@ abstract class CMSPlugin implements DispatcherAwareInterface, PluginInterface /** * Constructor * - * @param DispatcherInterface &$subject The object to observe - * @param array $config An optional associative array of configuration settings. - * Recognized key values include 'name', 'group', 'params', 'language' - * (this list is not meant to be comprehensive). + * @param array $config An optional associative array of configuration settings. + * Recognized key values include 'name', 'group', 'params', 'language' + * (this list is not meant to be comprehensive). * * @since 1.5 */ - public function __construct(&$subject, $config = array()) + public function __construct($config = array()) { + if ($config instanceof DispatcherInterface) + { + @trigger_error( + sprintf( + 'Passing an instance of %1$s to %2$s will not be supported in 6.0', + DispatcherInterface::class, + __METHOD__ + ), + \E_USER_DEPRECATED + ); + + // Set the dispatcher we are to register our listeners with + $this->setDispatcher($config); + + $config = func_num_args() > 1 ? func_get_arg(1) : []; + } + // Get the parameters. if (isset($config['params'])) { if ($config['params'] instanceof Registry) { @@ -143,9 +158,6 @@ public function __construct(&$subject, $config = array()) $this->db = Factory::getDbo(); } } - - // Set the dispatcher we are to register our listeners with - $this->setDispatcher($subject); } /** @@ -187,15 +199,32 @@ public function loadLanguage($extension = '', $basePath = JPATH_ADMINISTRATOR) * This method additionally supports Joomla\Event\SubscriberInterface and plugins implementing this will be * registered to the dispatcher as a subscriber. * + * @param ?DispatcherInterface $dispatcher Dispatcher instance to register listeners with + * * @return void * * @since 4.0.0 + * + * @todo In 6.0 $dispatcher argument will no longer be nullable. */ - public function registerListeners() + public function registerListeners(?DispatcherInterface $dispatcher = null) { + // Make sure we have a dispatcher. + if ($dispatcher === null) + { + try + { + $dispatcher = $this->getDispatcher(); + } + catch (\UnexpectedValueException) + { + $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); + } + } + // Plugins which are SubscriberInterface implementations are handled without legacy layer support if ($this instanceof SubscriberInterface) { - $this->getDispatcher()->addSubscriber($this); + $dispatcher->addSubscriber($this); return; } @@ -211,7 +240,7 @@ public function registerListeners() // Save time if I'm not to detect legacy listeners if (!$this->allowLegacyListeners) { - $this->registerListener($method->name); + $this->registerListener($method->name, $dispatcher); continue; } @@ -221,7 +250,7 @@ public function registerListeners() // If the parameter count is not 1 it is by definition a legacy listener if (\count($parameters) !== 1) { - $this->registerLegacyListener($method->name); + $this->registerLegacyListener($method->name, $dispatcher); continue; } @@ -232,13 +261,13 @@ public function registerListeners() // No type hint / type hint class not an event or parameter name is not "event"? It's a legacy listener. if ($paramName !== 'event' || !$this->parameterImplementsEventInterface($param)) { - $this->registerLegacyListener($method->name); + $this->registerLegacyListener($method->name, $dispatcher); continue; } // Everything checks out, this is a proper listener. - $this->registerListener($method->name); + $this->registerListener($method->name, $dispatcher); } } @@ -250,15 +279,31 @@ public function registerListeners() * into old style method arguments and call your on method with them. The result will be passed back to * the Event, as an element into an array argument called 'result'. * - * @param string $methodName The method name to register + * @param string $methodName The method name to register + * @param ?DispatcherInterface $dispatcher Dispatcher instance to register listeners with * * @return void * * @since 4.0.0 + * + * @todo In 6.0 $dispatcher argument will no longer be nullable. */ - final protected function registerLegacyListener(string $methodName) + final protected function registerLegacyListener(string $methodName, ?DispatcherInterface $dispatcher = null) { - $this->getDispatcher()->addListener( + // Make sure we have a dispatcher. + if ($dispatcher === null) + { + try + { + $dispatcher = $this->getDispatcher(); + } + catch (\UnexpectedValueException) + { + $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); + } + } + + $dispatcher->addListener( $methodName, function (AbstractEvent $event) use ($methodName) { // Get the event arguments @@ -294,15 +339,31 @@ function (AbstractEvent $event) use ($methodName) { * Registers a proper event listener, i.e. a method which accepts an AbstractEvent as its sole argument. This is the * preferred way to implement plugins in Joomla! 4.x and will be the only possible method with Joomla! 5.x onwards. * - * @param string $methodName The method name to register + * @param string $methodName The method name to register + * @param ?DispatcherInterface $dispatcher Dispatcher instance to register listeners with * * @return void * * @since 4.0.0 + * + * @todo In 6.0 $dispatcher argument will no longer be nullable. */ - final protected function registerListener(string $methodName) + final protected function registerListener(string $methodName, ?DispatcherInterface $dispatcher = null) { - $this->getDispatcher()->addListener($methodName, [$this, $methodName]); + // Make sure we have a dispatcher. + if ($dispatcher === null) + { + try + { + $dispatcher = $this->getDispatcher(); + } + catch (\UnexpectedValueException) + { + $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); + } + } + + $dispatcher->addListener($methodName, [$this, $methodName]); } /** diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 51f52c7410e09..b53be2e1fda53 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -139,16 +139,17 @@ public static function isEnabled($type, $plugin = null) * Loads all the plugin files for a particular type if no specific plugin is specified * otherwise only the specific plugin is loaded. * - * @param string $type The plugin type, relates to the subdirectory in the plugins directory. - * @param string $plugin The plugin name. - * @param boolean $autocreate Autocreate the plugin. - * @param DispatcherInterface $dispatcher Optionally allows the plugin to use a different dispatcher. + * @param string $type The plugin type, relates to the subdirectory in the plugins directory. + * @param ?string $plugin The plugin name to import a specific plugin or null to import all plugins in group. + * @param boolean $autocreate Whether to register listeners with the event dispatcher. + * @param ?DispatcherInterface $dispatcher The event dispatcher. In 6.0 this will be required. * * @return boolean True on success. * * @since 1.5 + * @todo Arguments will not be optional in 6.0. */ - public static function importPlugin($type, $plugin = null, $autocreate = true, DispatcherInterface $dispatcher = null) + public static function importPlugin($type, $plugin = null, $autocreate = true, ?DispatcherInterface $dispatcher = null) { static $loaded = []; @@ -160,10 +161,25 @@ public static function importPlugin($type, $plugin = null, $autocreate = true, D } // Ensure we have a dispatcher now so we can correctly track the loaded plugins - $dispatcher = $dispatcher ?: Factory::getApplication()->getDispatcher(); + if ($dispatcher === null) + { + @trigger_error( + sprintf('Passing an instance of %1$s to %2$s will be required in 6.0', DispatcherInterface::class, __METHOD__), + \E_USER_DEPRECATED + ); + + try + { + $dispatcher = Factory::getApplication()->getDispatcher(); + } + catch (\UnexpectedValueException) + { + $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); + } + } // Get the dispatcher's hash to allow plugins to be registered to unique dispatchers - $dispatcherHash = spl_object_hash($dispatcher); + $dispatcherHash = spl_object_id($dispatcher); if (!isset($loaded[$dispatcherHash])) { $loaded[$dispatcherHash] = []; @@ -198,19 +214,19 @@ public static function importPlugin($type, $plugin = null, $autocreate = true, D * Loads the plugin file. * * @param object $plugin The plugin. - * @param boolean $autocreate True to autocreate. - * @param DispatcherInterface $dispatcher Optionally allows the plugin to use a different dispatcher. + * @param boolean $autocreate Whether to register listeners with the event dispatcher. + * @param DispatcherInterface $dispatcher The event dispatcher. * * @return void * * @since 3.2 */ - protected static function import($plugin, $autocreate = true, DispatcherInterface $dispatcher = null) + protected static function import($plugin, $autocreate, DispatcherInterface $dispatcher) { static $plugins = []; // Get the dispatcher's hash to allow paths to be tracked against unique dispatchers - $hash = spl_object_hash($dispatcher) . $plugin->type . $plugin->name; + $hash = spl_object_id($dispatcher) . $plugin->type . $plugin->name; if (\array_key_exists($hash, $plugins)) { return; @@ -220,7 +236,8 @@ protected static function import($plugin, $autocreate = true, DispatcherInterfac $plugin = Factory::getApplication()->bootPlugin($plugin->name, $plugin->type); - if ($dispatcher && $plugin instanceof DispatcherAwareInterface) { + // @todo remove this in 6.0. + if ($plugin instanceof DispatcherAwareInterface) { $plugin->setDispatcher($dispatcher); } @@ -228,7 +245,7 @@ protected static function import($plugin, $autocreate = true, DispatcherInterfac return; } - $plugin->registerListeners(); + $plugin->registerListeners($dispatcher); } /** diff --git a/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php b/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php index e4e92eb447b8f..e14e9e7b57bb0 100644 --- a/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php +++ b/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php @@ -490,4 +490,71 @@ public function onTest() $this->assertEquals(['test', 'unit'], $event->getArgument('result')); } + + /** + * @testdox listeners registered with dispatcher passed to registerListeners() + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function testRegisterListenersDispatcherUsed() + { + $constructorDispatcher = new Dispatcher(); + $setterDispatcher = new Dispatcher(); + $interfaceDispatcher = new Dispatcher(); + + $plugin = new class ($constructorDispatcher, []) extends CMSPlugin + { + public function onLegacyEvent(stdClass $argument) + { + } + + public function onEvent(EventInterface $event) + { + } + }; + + $plugin->setDispatcher($setterDispatcher); + $plugin->registerListeners($interfaceDispatcher); + + $this->assertSame(0, $constructorDispatcher->countListeners('onLegacyEvent')); + $this->assertSame(0, $constructorDispatcher->countListeners('onEvent')); + $this->assertSame(0, $setterDispatcher->countListeners('onLegacyEvent')); + $this->assertSame(0, $setterDispatcher->countListeners('onEvent')); + $this->assertSame(1, $interfaceDispatcher->countListeners('onLegacyEvent')); + $this->assertSame(1, $interfaceDispatcher->countListeners('onEvent')); + } + + /** + * @testdox listeners registered with dispatcher set with setDispatcher() + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function testSetterDispatcherUsed() + { + $constructorDispatcher = new Dispatcher(); + $setterDispatcher = new Dispatcher(); + + $plugin = new class ($constructorDispatcher, []) extends CMSPlugin + { + public function onLegacyEvent(stdClass $argument) + { + } + + public function onEvent(EventInterface $event) + { + } + }; + + $plugin->setDispatcher($setterDispatcher); + $plugin->registerListeners(null); + + $this->assertSame(0, $constructorDispatcher->countListeners('onLegacyEvent')); + $this->assertSame(0, $constructorDispatcher->countListeners('onEvent')); + $this->assertSame(1, $setterDispatcher->countListeners('onLegacyEvent')); + $this->assertSame(1, $setterDispatcher->countListeners('onEvent')); + } } From c1ee129ff6c77aa769ebcfc35103b2a137f05f6a Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Fri, 9 Dec 2022 10:43:50 +0200 Subject: [PATCH 2/9] New codestyle --- libraries/src/Plugin/CMSPlugin.php | 33 ++++++++------------------- libraries/src/Plugin/PluginHelper.php | 10 +++----- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index fd593732a8306..4dd097df623f8 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -98,8 +98,7 @@ abstract class CMSPlugin implements PluginInterface */ public function __construct($config = array()) { - if ($config instanceof DispatcherInterface) - { + if ($config instanceof DispatcherInterface) { @trigger_error( sprintf( 'Passing an instance of %1$s to %2$s will not be supported in 6.0', @@ -210,14 +209,10 @@ public function loadLanguage($extension = '', $basePath = JPATH_ADMINISTRATOR) public function registerListeners(?DispatcherInterface $dispatcher = null) { // Make sure we have a dispatcher. - if ($dispatcher === null) - { - try - { + if ($dispatcher === null) { + try { $dispatcher = $this->getDispatcher(); - } - catch (\UnexpectedValueException) - { + } catch (\UnexpectedValueException) { $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); } } @@ -291,14 +286,10 @@ public function registerListeners(?DispatcherInterface $dispatcher = null) final protected function registerLegacyListener(string $methodName, ?DispatcherInterface $dispatcher = null) { // Make sure we have a dispatcher. - if ($dispatcher === null) - { - try - { + if ($dispatcher === null) { + try { $dispatcher = $this->getDispatcher(); - } - catch (\UnexpectedValueException) - { + } catch (\UnexpectedValueException) { $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); } } @@ -351,14 +342,10 @@ function (AbstractEvent $event) use ($methodName) { final protected function registerListener(string $methodName, ?DispatcherInterface $dispatcher = null) { // Make sure we have a dispatcher. - if ($dispatcher === null) - { - try - { + if ($dispatcher === null) { + try { $dispatcher = $this->getDispatcher(); - } - catch (\UnexpectedValueException) - { + } catch (\UnexpectedValueException) { $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); } } diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index b53be2e1fda53..c564d68a89001 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -161,19 +161,15 @@ public static function importPlugin($type, $plugin = null, $autocreate = true, ? } // Ensure we have a dispatcher now so we can correctly track the loaded plugins - if ($dispatcher === null) - { + if ($dispatcher === null) { @trigger_error( sprintf('Passing an instance of %1$s to %2$s will be required in 6.0', DispatcherInterface::class, __METHOD__), \E_USER_DEPRECATED ); - try - { + try { $dispatcher = Factory::getApplication()->getDispatcher(); - } - catch (\UnexpectedValueException) - { + } catch (\UnexpectedValueException) { $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); } } From b2cc4f440d8e3aef0f787f71c08b2ea06d5a50e7 Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Mon, 12 Dec 2022 08:33:51 +0200 Subject: [PATCH 3/9] Deprecate methods --- libraries/src/Plugin/CMSPlugin.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index 4dd097df623f8..5322942de35ca 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -281,7 +281,7 @@ public function registerListeners(?DispatcherInterface $dispatcher = null) * * @since 4.0.0 * - * @todo In 6.0 $dispatcher argument will no longer be nullable. + * @deprecated 6.0 Without replacement */ final protected function registerLegacyListener(string $methodName, ?DispatcherInterface $dispatcher = null) { @@ -337,7 +337,7 @@ function (AbstractEvent $event) use ($methodName) { * * @since 4.0.0 * - * @todo In 6.0 $dispatcher argument will no longer be nullable. + * @deprecated 6.0 Use \Joomla\Dispatcher\DispatcherInterface::addListener() directly */ final protected function registerListener(string $methodName, ?DispatcherInterface $dispatcher = null) { From 9a6e93ac57907ee868088395e40e641417a6a761 Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Mon, 12 Dec 2022 08:36:34 +0200 Subject: [PATCH 4/9] Correct class name --- libraries/src/Plugin/CMSPlugin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index 5322942de35ca..62dec14504087 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -337,7 +337,7 @@ function (AbstractEvent $event) use ($methodName) { * * @since 4.0.0 * - * @deprecated 6.0 Use \Joomla\Dispatcher\DispatcherInterface::addListener() directly + * @deprecated 6.0 Use \Joomla\Event\DispatcherInterface::addListener() directly */ final protected function registerListener(string $methodName, ?DispatcherInterface $dispatcher = null) { From 6f36c68668e8e783b9db5c8f765a1541bcb0b239 Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Mon, 12 Dec 2022 08:43:18 +0200 Subject: [PATCH 5/9] Log deprecation --- libraries/src/Plugin/CMSPlugin.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index 62dec14504087..c9ca8aae44963 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -101,7 +101,7 @@ public function __construct($config = array()) if ($config instanceof DispatcherInterface) { @trigger_error( sprintf( - 'Passing an instance of %1$s to %2$s will not be supported in 6.0', + 'Passing an instance of %1$s to %2$s will not be supported in 6.0.', DispatcherInterface::class, __METHOD__ ), @@ -210,6 +210,15 @@ public function registerListeners(?DispatcherInterface $dispatcher = null) { // Make sure we have a dispatcher. if ($dispatcher === null) { + @trigger_error( + sprintf( + 'Passing an instance of %1$s to %2$s will be required in 6.0.', + DispatcherInterface::class, + __METHOD__ + ), + \E_USER_DEPRECATED + ); + try { $dispatcher = $this->getDispatcher(); } catch (\UnexpectedValueException) { From b408b35cc5eeb9699e866c6f8e076f392fe784de Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Mon, 12 Dec 2022 09:07:40 +0200 Subject: [PATCH 6/9] Update deprecation messages --- libraries/src/Plugin/CMSPlugin.php | 4 ++-- libraries/src/Plugin/PluginHelper.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index c9ca8aae44963..d2cedab2830fc 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -101,7 +101,7 @@ public function __construct($config = array()) if ($config instanceof DispatcherInterface) { @trigger_error( sprintf( - 'Passing an instance of %1$s to %2$s will not be supported in 6.0.', + 'Passing an instance of %1$s to %2$s() will not be supported in 6.0.', DispatcherInterface::class, __METHOD__ ), @@ -212,7 +212,7 @@ public function registerListeners(?DispatcherInterface $dispatcher = null) if ($dispatcher === null) { @trigger_error( sprintf( - 'Passing an instance of %1$s to %2$s will be required in 6.0.', + 'Passing an instance of %1$s to %2$s() will be required in 6.0.', DispatcherInterface::class, __METHOD__ ), diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index c564d68a89001..427bc0d9bd933 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -163,7 +163,7 @@ public static function importPlugin($type, $plugin = null, $autocreate = true, ? // Ensure we have a dispatcher now so we can correctly track the loaded plugins if ($dispatcher === null) { @trigger_error( - sprintf('Passing an instance of %1$s to %2$s will be required in 6.0', DispatcherInterface::class, __METHOD__), + sprintf('Passing an instance of %1$s to %2$s() will be required in 6.0', DispatcherInterface::class, __METHOD__), \E_USER_DEPRECATED ); From 5cb13b84663a174c7a55d3446b4a101a71754044 Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Tue, 13 Dec 2022 09:17:03 +0200 Subject: [PATCH 7/9] Add deprecation path --- libraries/src/Plugin/PluginHelper.php | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 427bc0d9bd933..ee8d1f3166746 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -209,18 +209,31 @@ public static function importPlugin($type, $plugin = null, $autocreate = true, ? /** * Loads the plugin file. * - * @param object $plugin The plugin. - * @param boolean $autocreate Whether to register listeners with the event dispatcher. - * @param DispatcherInterface $dispatcher The event dispatcher. + * @param object $plugin The plugin. + * @param boolean $autocreate Whether to register listeners with the event dispatcher. + * @param ?DispatcherInterface $dispatcher The event dispatcher. In 6.0 this will be required. * * @return void * * @since 3.2 */ - protected static function import($plugin, $autocreate, DispatcherInterface $dispatcher) + protected static function import($plugin, $autocreate = true, ?DispatcherInterface $dispatcher = null) { static $plugins = []; + if ($dispatcher === null) { + @trigger_error( + sprintf('Passing an instance of %1$s to %2$s() will be required in 6.0', DispatcherInterface::class, __METHOD__), + \E_USER_DEPRECATED + ); + + try { + $dispatcher = Factory::getApplication()->getDispatcher(); + } catch (\UnexpectedValueException) { + $dispatcher = Factory::getContainer()->get(DispatcherInterface::class); + } + } + // Get the dispatcher's hash to allow paths to be tracked against unique dispatchers $hash = spl_object_id($dispatcher) . $plugin->type . $plugin->name; From 0b13c9edf6992382a730ec9774e3bc407b1af530 Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Tue, 13 Dec 2022 09:27:46 +0200 Subject: [PATCH 8/9] Update doc block --- libraries/src/Plugin/PluginHelper.php | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index ee8d1f3166746..e097c7e4f5787 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -216,6 +216,7 @@ public static function importPlugin($type, $plugin = null, $autocreate = true, ? * @return void * * @since 3.2 + * @todo Arguments will not be optional in 6.0. */ protected static function import($plugin, $autocreate = true, ?DispatcherInterface $dispatcher = null) { From 0cfd4f8fdf05e7cac61394247aac5b65370e0c9f Mon Sep 17 00:00:00 2001 From: SharkyKZ Date: Tue, 15 Apr 2025 09:06:06 +0300 Subject: [PATCH 9/9] CS --- libraries/src/Plugin/CMSPlugin.php | 10 +++++----- libraries/src/Plugin/PluginHelper.php | 4 ++-- tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php | 12 +++++------- 3 files changed, 12 insertions(+), 14 deletions(-) diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index ffc9ffbe1c954..b4972c628fc89 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -115,11 +115,11 @@ abstract class CMSPlugin implements PluginInterface, LanguageAwareInterface * * @since 1.5 */ - public function __construct($config = array()) + public function __construct($config = []) { if ($config instanceof DispatcherInterface) { @trigger_error( - sprintf( + \sprintf( 'Passing an instance of %1$s to %2$s() will not be supported in 7.0.', DispatcherInterface::class, __METHOD__ @@ -127,10 +127,10 @@ public function __construct($config = array()) \E_USER_DEPRECATED ); - // Set the dispatcher we are to register our listeners with + // Set the dispatcher we are to register our listeners with $this->setDispatcher($config); - $config = func_num_args() > 1 ? func_get_arg(1) : []; + $config = \func_num_args() > 1 ? func_get_arg(1) : []; } // Get the parameters. @@ -230,7 +230,7 @@ public function registerListeners(?DispatcherInterface $dispatcher = null) // Make sure we have a dispatcher. if ($dispatcher === null) { @trigger_error( - sprintf( + \sprintf( 'Passing an instance of %1$s to %2$s() will be required in 7.0.', DispatcherInterface::class, __METHOD__ diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 30ac1d80f0e82..f01eaa8fe0d35 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -174,7 +174,7 @@ public static function importPlugin($type, $plugin = null, $autocreate = true, ? // Ensure we have a dispatcher now so we can correctly track the loaded plugins if ($dispatcher === null) { @trigger_error( - sprintf('Passing an instance of %1$s to %2$s() will be required in 7.0', DispatcherInterface::class, __METHOD__), + \sprintf('Passing an instance of %1$s to %2$s() will be required in 7.0', DispatcherInterface::class, __METHOD__), \E_USER_DEPRECATED ); @@ -235,7 +235,7 @@ protected static function import($plugin, $autocreate = true, ?DispatcherInterfa if ($dispatcher === null) { @trigger_error( - sprintf('Passing an instance of %1$s to %2$s() will be required in 7.0', DispatcherInterface::class, __METHOD__), + \sprintf('Passing an instance of %1$s to %2$s() will be required in 7.0', DispatcherInterface::class, __METHOD__), \E_USER_DEPRECATED ); diff --git a/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php b/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php index bcd04c11272f3..5926abbe3db9d 100644 --- a/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php +++ b/tests/Unit/Libraries/Cms/Plugin/CMSPluginTest.php @@ -480,11 +480,10 @@ public function onTest() public function testRegisterListenersDispatcherUsed() { $constructorDispatcher = new Dispatcher(); - $setterDispatcher = new Dispatcher(); - $interfaceDispatcher = new Dispatcher(); + $setterDispatcher = new Dispatcher(); + $interfaceDispatcher = new Dispatcher(); - $plugin = new class ($constructorDispatcher, []) extends CMSPlugin - { + $plugin = new class ($constructorDispatcher, []) extends CMSPlugin { public function onLegacyEvent(stdClass $argument) { } @@ -515,10 +514,9 @@ public function onEvent(EventInterface $event) public function testSetterDispatcherUsed() { $constructorDispatcher = new Dispatcher(); - $setterDispatcher = new Dispatcher(); + $setterDispatcher = new Dispatcher(); - $plugin = new class ($constructorDispatcher, []) extends CMSPlugin - { + $plugin = new class ($constructorDispatcher, []) extends CMSPlugin { public function onLegacyEvent(stdClass $argument) { }