diff --git a/libraries/src/Event/DynamicSubscriberInterface.php b/libraries/src/Event/DynamicSubscriberInterface.php new file mode 100644 index 0000000000000..8ce05f74b603f --- /dev/null +++ b/libraries/src/Event/DynamicSubscriberInterface.php @@ -0,0 +1,43 @@ + 'methodName') + * * array('eventName' => array('methodName', $priority)) + * * array('eventName' => $callable) + * * array('eventName' => array($callable, $priority)) + * + * @return array + * + * @since __DEPLOY_VERSION__ + */ + public function getSubscribedEvents(): array; +} diff --git a/libraries/src/Plugin/PluginHelper.php b/libraries/src/Plugin/PluginHelper.php index 9c3c591e311ae..0c993420a9a01 100644 --- a/libraries/src/Plugin/PluginHelper.php +++ b/libraries/src/Plugin/PluginHelper.php @@ -10,9 +10,11 @@ namespace Joomla\CMS\Plugin; use Joomla\CMS\Cache\Exception\CacheExceptionInterface; +use Joomla\CMS\Event\DynamicSubscriberInterface; use Joomla\CMS\Factory; use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherInterface; +use Joomla\Event\Priority; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; @@ -239,7 +241,22 @@ protected static function import($plugin, $autocreate = true, DispatcherInterfac return; } - $plugin->registerListeners(); + // Check for dynamic Subscriber + if ($plugin instanceof DynamicSubscriberInterface) { + foreach ($plugin->getSubscribedEvents() as $eventName => $params) { + if (\is_array($params)) { + $callback = !\is_string($params[0]) && \is_callable($params[0]) ? $params[0] : [$plugin, $params[0]]; + $dispatcher->addListener($eventName, $callback, $params[1] ?? Priority::NORMAL); + } else { + $callback = !\is_string($params) && \is_callable($params) ? $params : [$plugin, $params]; + $dispatcher->addListener($eventName, $callback); + } + } + } 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..4e20edd57496b 100644 --- a/plugins/system/guidedtours/services/provider.php +++ b/plugins/system/guidedtours/services/provider.php @@ -34,15 +34,12 @@ public function register(Container $container) $container->set( PluginInterface::class, function (Container $container) { - $app = Factory::getApplication(); - $plugin = new GuidedTours( $container->get(DispatcherInterface::class), - (array) PluginHelper::getPlugin('system', 'guidedtours'), - $app->isClient('administrator') + (array) PluginHelper::getPlugin('system', 'guidedtours') ); - $plugin->setApplication($app); + $plugin->setApplication(Factory::getApplication()); $wa = $container->get(WebAssetRegistry::class); diff --git a/plugins/system/guidedtours/src/Extension/GuidedTours.php b/plugins/system/guidedtours/src/Extension/GuidedTours.php index 4bcc765ad39fc..9b65b8c3fa0d4 100644 --- a/plugins/system/guidedtours/src/Extension/GuidedTours.php +++ b/plugins/system/guidedtours/src/Extension/GuidedTours.php @@ -10,15 +10,14 @@ namespace Joomla\Plugin\System\GuidedTours\Extension; +use Joomla\CMS\Event\DynamicSubscriberInterface; use Joomla\CMS\Language\Text; use Joomla\CMS\Object\CMSObject; use Joomla\CMS\Plugin\CMSPlugin; use Joomla\CMS\Session\Session; use Joomla\Component\Guidedtours\Administrator\Extension\GuidedtoursComponent; use Joomla\Component\Guidedtours\Administrator\Model\TourModel; -use Joomla\Event\DispatcherInterface; use Joomla\Event\Event; -use Joomla\Event\SubscriberInterface; // phpcs:disable PSR1.Files.SideEffects \defined('_JEXEC') or die; @@ -29,7 +28,7 @@ * * @since 4.3.0 */ -final class GuidedTours extends CMSPlugin implements SubscriberInterface +final class GuidedTours extends CMSPlugin implements DynamicSubscriberInterface { /** * A mapping for the step types @@ -58,31 +57,6 @@ final class GuidedTours extends CMSPlugin implements SubscriberInterface GuidedtoursComponent::STEP_INTERACTIVETYPE_SELECT => 'select', ]; - /** - * An internal flag whether plugin should listen any event. - * - * @var bool - * - * @since 4.3.0 - */ - protected static $enabled = false; - - /** - * Constructor - * - * @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. - * - * @since 4.3.0 - */ - public function __construct(DispatcherInterface $dispatcher, array $config = [], bool $enabled = false) - { - self::$enabled = $enabled; - - parent::__construct($dispatcher, $config); - } - /** * function for getSubscribedEvents : new Joomla 4 feature * @@ -90,9 +64,9 @@ public function __construct(DispatcherInterface $dispatcher, array $config = [], * * @since 4.3.0 */ - public static function getSubscribedEvents(): array + public function getSubscribedEvents(): array { - return self::$enabled ? [ + return $this->getApplication()->isClient('administrator') ? [ 'onAjaxGuidedtours' => 'startTour', 'onBeforeCompileHead' => 'onBeforeCompileHead', ] : []; diff --git a/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php b/plugins/system/schedulerunner/src/Extension/ScheduleRunner.php index 143272585d5f6..5194e36ae04e9 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\DynamicSubscriberInterface; use Joomla\CMS\Event\Model; use Joomla\CMS\Factory; use Joomla\CMS\Log\Log; @@ -24,7 +25,6 @@ use Joomla\Component\Scheduler\Administrator\Task\Task; use Joomla\Event\Event; use Joomla\Event\EventInterface; -use Joomla\Event\SubscriberInterface; use Joomla\Registry\Registry; // phpcs:disable PSR1.Files.SideEffects @@ -42,7 +42,7 @@ * * @since 4.1.0 */ -final class ScheduleRunner extends CMSPlugin implements SubscriberInterface +final class ScheduleRunner extends CMSPlugin implements DynamicSubscriberInterface { /** * Length of auto-generated webcron key. @@ -61,27 +61,28 @@ final class ScheduleRunner extends CMSPlugin implements SubscriberInterface * * @throws \Exception */ - public static function getSubscribedEvents(): array + public function getSubscribedEvents(): array { - $config = ComponentHelper::getParams('com_scheduler'); - $app = Factory::getApplication(); + $app = $this->getApplication(); + $isSite = $app->isClient('site'); + $isAdmin = $app->isClient('administrator'); + $mapping = []; - $mapping = []; + if ($isSite || $isAdmin) { + $config = ComponentHelper::getParams('com_scheduler'); - 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')) { + if ($isAdmin) { + // Only allowed in the administrator $mapping['onContentPrepareForm'] = 'enhanceSchedulerConfig'; $mapping['onExtensionBeforeSave'] = 'generateWebcronKey'; $mapping['onAjaxRunSchedulerTest'] = 'runTestCron'; + } elseif ($isSite && $config->get('webcron.enabled')) { + // Only allowed in the frontend + $mapping['onAjaxRunSchedulerWebcron'] = 'runWebCron'; } }