diff --git a/libraries/src/Event/ConfigurableSubscriberInterface.php b/libraries/src/Event/ConfigurableSubscriberInterface.php new file mode 100644 index 0000000000000..9fe7b833eaa7b --- /dev/null +++ b/libraries/src/Event/ConfigurableSubscriberInterface.php @@ -0,0 +1,37 @@ + + * @license GNU General Public License version 2 or later; see LICENSE.txt + */ + +namespace Joomla\CMS\Event; + +use Joomla\Event\DispatcherInterface; + +// phpcs:disable PSR1.Files.SideEffects +\defined('_JEXEC') or die; +// phpcs:enable PSR1.Files.SideEffects + +/** + * Interface for configurable event subscriber. + * + * @since __DEPLOY_VERSION__ + */ +interface ConfigurableSubscriberInterface +{ + /** + * Method allows to set up custom event listeners, wich is not possible to set up with generic SubscriberInterface + * (such as LazyServiceEventListener, private listeners etc.). + * And/or set the listeners only when specific environment requirement are meets (such as the app client id). + * + * @param \Joomla\Event\DispatcherInterface $dispatcher The dispatcher instance. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function configureListeners(DispatcherInterface $dispatcher): void; +} diff --git a/libraries/src/Extension/PluginInterface.php b/libraries/src/Extension/PluginInterface.php index 55baeb78188ed..828e2d9600f15 100644 --- a/libraries/src/Extension/PluginInterface.php +++ b/libraries/src/Extension/PluginInterface.php @@ -28,6 +28,10 @@ interface PluginInterface extends DispatcherAwareInterface * @return void * * @since 4.0.0 + * + * @deprecated 5.2 will be removed in 7.0 + * Plugin should implement SubscriberInterface. + * These plugins will be added to dispatcher in PluginHelper::import(). */ public function registerListeners(); } diff --git a/libraries/src/Plugin/CMSPlugin.php b/libraries/src/Plugin/CMSPlugin.php index 0666323886331..ca6d29b63be53 100644 --- a/libraries/src/Plugin/CMSPlugin.php +++ b/libraries/src/Plugin/CMSPlugin.php @@ -200,6 +200,10 @@ public function loadLanguage($extension = '', $basePath = JPATH_ADMINISTRATOR) * @return void * * @since 4.0.0 + * + * @deprecated 5.2 will be removed in 7.0 + * Plugin should implement SubscriberInterface. + * These plugins will be added to dispatcher in PluginHelper::import(). */ public function registerListeners() { @@ -210,6 +214,8 @@ public function registerListeners() return; } + @trigger_error('The plugin ' . __CLASS__ . ' should implement SubscriberInterface.', \E_USER_DEPRECATED); + $reflectedObject = new \ReflectionObject($this); $methods = $reflectedObject->getMethods(\ReflectionMethod::IS_PUBLIC); @@ -265,6 +271,9 @@ public function registerListeners() * @return void * * @since 4.0.0 + * + * @deprecated 5.2 will be removed in 7.0 + * Plugin should implement SubscriberInterface. */ final protected function registerLegacyListener(string $methodName) { @@ -313,6 +322,9 @@ function (AbstractEvent $event) use ($methodName) { * @return void * * @since 4.0.0 + * + * @deprecated 5.2 will be removed in 7.0 + * Plugin should implement SubscriberInterface. */ final protected function registerListener(string $methodName) { @@ -327,6 +339,9 @@ final protected function registerListener(string $methodName) * @return boolean * * @since 4.0.0 + * + * @deprecated 5.2 will be removed in 7.0 + * Plugin should implement SubscriberInterface. */ private function parameterImplementsEventInterface(\ReflectionParameter $parameter): bool { diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 9c3c591e311ae..22ebdd955d282 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -10,6 +10,7 @@ namespace Joomla\CMS\Plugin; use Joomla\CMS\Cache\Exception\CacheExceptionInterface; +use Joomla\CMS\Event\ConfigurableSubscriberInterface; use Joomla\CMS\Factory; use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherInterface; @@ -239,7 +240,18 @@ protected static function import($plugin, $autocreate = true, DispatcherInterfac return; } - $plugin->registerListeners(); + // Check for Configurable Subscriber + if ($plugin instanceof ConfigurableSubscriberInterface) { + if (!$dispatcher) { + throw new \RuntimeException('Dispatcher instance is required to set up ConfigurableSubscriber when autocreate is on.'); + } + + $plugin->configureListeners($dispatcher); + } else { + // Register regular Subscribers + // @TODO: Starting from 7.0 it should use $dispatcher->addSubscriber($plugin);, for plugins which implements SubscriberInterface. + $plugin->registerListeners(); + } } /** diff --git a/plugins/system/guidedtours/services/provider.php b/plugins/system/guidedtours/services/provider.php index 8e30afd6b0b47..6448beb06b332 100644 --- a/plugins/system/guidedtours/services/provider.php +++ b/plugins/system/guidedtours/services/provider.php @@ -38,8 +38,7 @@ function (Container $container) { $plugin = new GuidedTours( $container->get(DispatcherInterface::class), - (array) PluginHelper::getPlugin('system', 'guidedtours'), - $app->isClient('administrator') + (array) PluginHelper::getPlugin('system', 'guidedtours') ); $plugin->setApplication($app); diff --git a/plugins/system/guidedtours/src/Extension/GuidedTours.php b/plugins/system/guidedtours/src/Extension/GuidedTours.php index 4bcc765ad39fc..d66c45fd8e010 100644 --- a/plugins/system/guidedtours/src/Extension/GuidedTours.php +++ b/plugins/system/guidedtours/src/Extension/GuidedTours.php @@ -10,6 +10,7 @@ namespace Joomla\Plugin\System\GuidedTours\Extension; +use Joomla\CMS\Event\ConfigurableSubscriberInterface; use Joomla\CMS\Language\Text; use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Plugin\CMSPlugin; @@ -29,7 +30,7 @@ * * @since 4.3.0 */ -final class GuidedTours extends CMSPlugin implements SubscriberInterface +final class GuidedTours extends CMSPlugin implements SubscriberInterface, ConfigurableSubscriberInterface { /** * A mapping for the step types @@ -59,43 +60,34 @@ final class GuidedTours extends CMSPlugin implements SubscriberInterface ]; /** - * An internal flag whether plugin should listen any event. - * - * @var bool - * - * @since 4.3.0 - */ - protected static $enabled = false; - - /** - * Constructor + * function for getSubscribedEvents : new Joomla 4 feature * - * @param DispatcherInterface $dispatcher The object to observe - * @param array $config An optional associative array of configuration settings. - * @param boolean $enabled An internal flag whether plugin should listen any event. + * @return array * * @since 4.3.0 */ - public function __construct(DispatcherInterface $dispatcher, array $config = [], bool $enabled = false) + public static function getSubscribedEvents(): array { - self::$enabled = $enabled; - - parent::__construct($dispatcher, $config); + return [ + 'onAjaxGuidedtours' => 'startTour', + 'onBeforeCompileHead' => 'onBeforeCompileHead', + ]; } /** - * function for getSubscribedEvents : new Joomla 4 feature + * Method allows to set up custom event listeners. * - * @return array + * @param \Joomla\Event\DispatcherInterface $dispatcher The dispatcher instance. * - * @since 4.3.0 + * @return void + * + * @since __DEPLOY_VERSION__ */ - public static function getSubscribedEvents(): array + public function configureListeners(DispatcherInterface $dispatcher): void { - return self::$enabled ? [ - 'onAjaxGuidedtours' => 'startTour', - 'onBeforeCompileHead' => 'onBeforeCompileHead', - ] : []; + if ($this->getApplication()->isClient('administrator')) { + $dispatcher->addSubscriber($this); + } } /** diff --git a/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php b/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php index 143272585d5f6..bfca2d41a7187 100644 --- a/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php +++ b/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php @@ -11,6 +11,7 @@ namespace Joomla\Plugin\System\ScheduleRunner\Extension; use Joomla\CMS\Component\ComponentHelper; +use Joomla\CMS\Event\ConfigurableSubscriberInterface; use Joomla\CMS\Event\Model; use Joomla\CMS\Factory; use Joomla\CMS\Log\Log; @@ -22,9 +23,9 @@ use Joomla\Component\Scheduler\Administrator\Model\TasksModel; use Joomla\Component\Scheduler\Administrator\Scheduler\Scheduler; use Joomla\Component\Scheduler\Administrator\Task\Task; +use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; use Joomla\Event\EventInterface; -use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects @@ -42,7 +43,7 @@ * * @since 4.1.0 */ -final class ScheduleRunner extends CMSPlugin implements SubscriberInterface +final class ScheduleRunner extends CMSPlugin implements ConfigurableSubscriberInterface { /** * Length of auto-generated webcron key. @@ -53,39 +54,35 @@ final class ScheduleRunner extends CMSPlugin implements SubscriberInterface private const WEBCRON_KEY_LENGTH = 20; /** - * @inheritDoc + * Method allows to set up custom event listeners. * - * @return string[] + * @param \Joomla\Event\DispatcherInterface $dispatcher The dispatcher instance. * - * @since 4.1.0 + * @return void * - * @throws \Exception + * @since __DEPLOY_VERSION__ */ - public static function getSubscribedEvents(): array + public function configureListeners(DispatcherInterface $dispatcher): void { - $config = ComponentHelper::getParams('com_scheduler'); - $app = Factory::getApplication(); - - $mapping = []; + $app = $this->getApplication(); if ($app->isClient('site') || $app->isClient('administrator')) { - $mapping['onBeforeCompileHead'] = 'injectLazyJS'; - $mapping['onAjaxRunSchedulerLazy'] = 'runLazyCron'; - - // Only allowed in the frontend - if ($app->isClient('site')) { - if ($config->get('webcron.enabled')) { - $mapping['onAjaxRunSchedulerWebcron'] = 'runWebCron'; - } - } elseif ($app->isClient('administrator')) { - $mapping['onContentPrepareForm'] = 'enhanceSchedulerConfig'; - $mapping['onExtensionBeforeSave'] = 'generateWebcronKey'; - - $mapping['onAjaxRunSchedulerTest'] = 'runTestCron'; + $config = ComponentHelper::getParams('com_scheduler'); + + // Common listeners + $dispatcher->addListener('onBeforeCompileHead', [$this, 'injectLazyJS']); + $dispatcher->addListener('onAjaxRunSchedulerLazy', [$this, 'runLazyCron']); + + if ($app->isClient('administrator')) { + // Only allowed in the administrator + $dispatcher->addListener('onContentPrepareForm', [$this, 'enhanceSchedulerConfig']); + $dispatcher->addListener('onExtensionBeforeSave', [$this, 'generateWebcronKey']); + $dispatcher->addListener('onAjaxRunSchedulerTest', [$this, 'runTestCron']); + } elseif ($app->isClient('site') && $config->get('webcron.enabled')) { + // Only allowed in the site + $dispatcher->addListener('onAjaxRunSchedulerWebcron', [$this, 'runWebCron']); } } - - return $mapping; } /**