From bd8f17f01975dacba19199ac4b7f4bba567f3e98 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Tim=20D=C3=BCsterhus?= Date: Fri, 1 Aug 2014 21:51:25 +0200 Subject: [PATCH] Add parameter support to event listeners Note the additional `\listener` in the namespace of IEventListener for parameterized event listeners. --- .../lib/system/event/EventHandler.class.php | 53 +++++++++++++++---- .../lib/system/event/IEventListener.class.php | 2 + .../event/listener/IEventListener.class.php | 24 +++++++++ .../PreParserAtUserListener.class.php | 5 +- .../SessionAccessLogListener.class.php | 5 +- 5 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 wcfsetup/install/files/lib/system/event/listener/IEventListener.class.php diff --git a/wcfsetup/install/files/lib/system/event/EventHandler.class.php b/wcfsetup/install/files/lib/system/event/EventHandler.class.php index a19515498a..e3164f9dcc 100644 --- a/wcfsetup/install/files/lib/system/event/EventHandler.class.php +++ b/wcfsetup/install/files/lib/system/event/EventHandler.class.php @@ -1,6 +1,8 @@ * @package com.woltlab.wcf @@ -76,8 +78,9 @@ class EventHandler extends SingletonFactory { * @param string $eventName * @param string $className * @param string $name + * @param array &$parameters */ - protected function executeInheritedActions($eventObj, $eventName, $className, $name) { + protected function executeInheritedActions($eventObj, $eventName, $className, $name, array &$parameters) { // create objects of the actions if (!isset($this->inheritedActionsObjects[$name]) || !is_array($this->inheritedActionsObjects[$name])) { $this->inheritedActionsObjects[$name] = array(); @@ -107,8 +110,11 @@ class EventHandler extends SingletonFactory { if (!class_exists($action['listenerClassName'])) { throw new SystemException("Unable to find class '".$action['listenerClassName']."'"); } - if (!ClassUtil::isInstanceOf($action['listenerClassName'], 'wcf\system\event\IEventListener')) { - throw new SystemException("'".$action['listenerClassName']."' does not implement 'wcf\system\event\IEventListener'"); + if (!ClassUtil::isInstanceOf($action['listenerClassName'], 'wcf\system\event\listener\IEventListener')) { + // legacy event listeners + if (!ClassUtil::isInstanceOf($action['listenerClassName'], 'wcf\system\event\IEventListener')) { + throw new SystemException("'".$action['listenerClassName']."' does not implement 'wcf\system\event\listener\IEventListener'"); + } } $object = new $action['listenerClassName']; @@ -124,17 +130,32 @@ class EventHandler extends SingletonFactory { // execute actions foreach ($this->inheritedActionsObjects[$name] as $actionObj) { - $actionObj->execute($eventObj, $className, $eventName); + if ($actionObj instanceof IEventListener) { + $actionObj->execute($eventObj, $className, $eventName, $parameters); + + if (!is_array($parameters)) { + throw new SystemException("'".get_class($actionObj)."' breaks the '\$parameters' array!"); + } + } + else if ($actionObj instanceof ILegacyEventListener) { + $actionObj->execute($eventObj, $className, $eventName); + } } } /** * Executes all registered listeners for the given event. * + * $parameters is an optional array of parameters. Event listeners + * are able to modify these. Any modification will be passed on to + * the next event listener and be available after execution of every + * event listener. + * * @param mixed $eventObj * @param string $eventName + * @param array &$parameters */ - public function fireAction($eventObj, $eventName) { + public function fireAction($eventObj, $eventName, array &$parameters = array()) { // get class name if (is_object($eventObj)) $className = get_class($eventObj); else $className = $eventObj; @@ -149,7 +170,7 @@ class EventHandler extends SingletonFactory { // execute inherited actions first if (!empty($this->inheritedActions)) { - $this->executeInheritedActions($eventObj, $eventName, $className, $name); + $this->executeInheritedActions($eventObj, $eventName, $className, $name, $parameters); } // create objects of the actions @@ -172,8 +193,11 @@ class EventHandler extends SingletonFactory { if (!class_exists($action['listenerClassName'])) { throw new SystemException("Unable to find class '".$action['listenerClassName']."'"); } - if (!ClassUtil::isInstanceOf($action['listenerClassName'], 'wcf\system\event\IEventListener')) { - throw new SystemException("'".$action['listenerClassName']."' does not implement 'wcf\system\event\IEventListener'"); + if (!ClassUtil::isInstanceOf($action['listenerClassName'], 'wcf\system\event\listener\IEventListener')) { + // legacy event listeners + if (!ClassUtil::isInstanceOf($action['listenerClassName'], 'wcf\system\event\IEventListener')) { + throw new SystemException("'".$action['listenerClassName']."' does not implement 'wcf\system\event\listener\IEventListener'"); + } } $object = new $action['listenerClassName']; @@ -186,7 +210,16 @@ class EventHandler extends SingletonFactory { // execute actions foreach ($this->actionsObjects[$name] as $actionObj) { - $actionObj->execute($eventObj, $className, $eventName); + if ($actionObj instanceof IEventListener) { + $actionObj->execute($eventObj, $className, $eventName, $parameters); + + if (!is_array($parameters)) { + throw new SystemException("'".get_class($actionObj)."' breaks the '\$parameters' array!"); + } + } + else if ($actionObj instanceof ILegacyEventListener) { + $actionObj->execute($eventObj, $className, $eventName); + } } } diff --git a/wcfsetup/install/files/lib/system/event/IEventListener.class.php b/wcfsetup/install/files/lib/system/event/IEventListener.class.php index 97be76ab79..575abbea98 100644 --- a/wcfsetup/install/files/lib/system/event/IEventListener.class.php +++ b/wcfsetup/install/files/lib/system/event/IEventListener.class.php @@ -2,8 +2,10 @@ namespace wcf\system\event; /** + * *DEPRECATED* * EventListeners can be registered for a specific event in many controller objects. * + * @deprecated since 2.1, use \wcf\system\event\listener\IEventListener * @author Marcel Werk * @copyright 2001-2014 WoltLab GmbH * @license GNU Lesser General Public License diff --git a/wcfsetup/install/files/lib/system/event/listener/IEventListener.class.php b/wcfsetup/install/files/lib/system/event/listener/IEventListener.class.php new file mode 100644 index 0000000000..208ba82309 --- /dev/null +++ b/wcfsetup/install/files/lib/system/event/listener/IEventListener.class.php @@ -0,0 +1,24 @@ + + * @package com.woltlab.wcf + * @subpackage system.event.listener + * @category Community Framework + */ +interface IEventListener { + /** + * Executes this action. + * + * @param object $eventObj Object firing the event + * @param string $className class name of $eventObj + * @param string $eventName name of the event fired + * @param array &$parameters given parameters + */ + public function execute($eventObj, $className, $eventName, array &$parameters); +} diff --git a/wcfsetup/install/files/lib/system/event/listener/PreParserAtUserListener.class.php b/wcfsetup/install/files/lib/system/event/listener/PreParserAtUserListener.class.php index 43610bbede..3c92a13bb4 100644 --- a/wcfsetup/install/files/lib/system/event/listener/PreParserAtUserListener.class.php +++ b/wcfsetup/install/files/lib/system/event/listener/PreParserAtUserListener.class.php @@ -2,7 +2,6 @@ namespace wcf\system\event\listener; use wcf\data\bbcode\BBCode; use wcf\data\user\UserList; -use wcf\system\event\IEventListener; use wcf\system\request\LinkHandler; use wcf\system\Callback; use wcf\system\Regex; @@ -20,9 +19,9 @@ use wcf\util\StringStack; */ class PreParserAtUserListener implements IEventListener { /** - * @see \wcf\system\event\IEventListener::execute() + * @see \wcf\system\event\listener\IEventListener::execute() */ - public function execute($eventObj, $className, $eventName) { + public function execute($eventObj, $className, $eventName, array &$parameters) { if (!$eventObj->text) return; // check if needed url BBCode is allowed diff --git a/wcfsetup/install/files/lib/system/event/listener/SessionAccessLogListener.class.php b/wcfsetup/install/files/lib/system/event/listener/SessionAccessLogListener.class.php index d581985887..9f6d488de6 100644 --- a/wcfsetup/install/files/lib/system/event/listener/SessionAccessLogListener.class.php +++ b/wcfsetup/install/files/lib/system/event/listener/SessionAccessLogListener.class.php @@ -3,7 +3,6 @@ namespace wcf\system\event\listener; use wcf\data\acp\session\access\log\ACPSessionAccessLogEditor; use wcf\data\acp\session\log\ACPSessionLog; use wcf\data\acp\session\log\ACPSessionLogEditor; -use wcf\system\event\IEventListener; use wcf\system\WCF; use wcf\util\UserUtil; @@ -19,9 +18,9 @@ use wcf\util\UserUtil; */ class SessionAccessLogListener implements IEventListener { /** - * @see \wcf\system\event\IEventListener::execute() + * @see \wcf\system\event\listener\IEventListener::execute() */ - public function execute($eventObj, $className, $eventName) { + public function execute($eventObj, $className, $eventName, array &$parameters) { if (WCF::getUser()->userID && WCF::getSession()->getPermission('admin.general.canUseAcp') && !defined(get_class($eventObj).'::DO_NOT_LOG')) { // try to find existing session log $sql = "SELECT sessionLogID -- 2.20.1