diff options
Diffstat (limited to 'inc/events.php')
-rw-r--r-- | inc/events.php | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/inc/events.php b/inc/events.php new file mode 100644 index 000000000..59c1d904d --- /dev/null +++ b/inc/events.php @@ -0,0 +1,162 @@ +<?php +/** + * DokuWiki Events + * + * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) + * @author Christopher Smith <chris@jalakai.co.uk> + */ + +if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../').'/'); +require_once(DOKU_INC.'inc/pluginutils.php'); +class event { + + // public properties + var $name = ''; // event name, objects must register against this name to see the event + var $data = NULL; // data relevant to the event, no standardised format (YET!) + var $result = NULL; // the results of the event action, only relevant in "*_after" advise + + // private properties + var $_default = true; // whether or not to carry out the default action associated with the event + var $_continue = true; // whether or not to continue propagating the event to other handlers + var $_action = NULL; // the function executed to carry out the event + + /** + * event constructor + */ + function event($name, &$data, $fn=NULL) { + + $this->name = $name; + $this->data =& $data; + $this->_action = $fn; + + } + + /** + * advise + * + * advise all registered handlers of this event + * any processing based on the event's _default property to be determined by the caller + * + * @return results of processing the event, usually $this->_default + */ + function advise() { + global $EVENT_HANDLER; + + return $EVENT_HANDLER->process_event($this,''); + } + + /** + * trigger + * + * advise all registered (<event>_before) handlers that this event is about to take place + * carry out the default action using $this->data based on $this->_default, all of which + * may have been modified by the event handlers + * if the action was carried out, advise all registered (<event>_after) handlers that the + * event has taken place + * + * @return $event->results + * the value set by any <event>_before or <event> handlers if the default action is prevented + * or the results of the default action (as modified by <event>_after handlers) + * or NULL no action took place and no handler modified the value + */ + function trigger() { + global $EVENT_HANDLER; + + $EVENT_HANDLER->process_event($this,'before'); + if ($this->_continue) $EVENT_HANDLER->process_event($this,''); + + if ($this->_default && is_callable($this->_action)) { + if (is_array($this->_action)) { + list($obj,$method) = $this->_action; + $this->result = $obj->$method($this->data); + } else { + $fn = $this->_action; + $this->result = $fn($this->data); + } + + $EVENT_HANDLER->process_event($this,'after'); + } + + return $this->result; + } + + /** + * stopPropagation + * + * stop any further processing of the event by event handlers + * this function does not prevent the default action taking place + */ + function stopPropagation() { $this->_continue = false; } + + /** + * preventDefault + * + * prevent the default action taking place + */ + function preventDefault() { $this->_default = false; } +} + +class event_handler { + + // public properties: none + + // private properties + var $_hooks = array(); // array of events and their registered handlers + + /* + * event_handler + * + * constructor, loads all action plugins and calls their register() method giving them + * an opportunity to register any hooks they require + */ + function event_handler() { + + // load action plugins + $plugin = NULL; + $pluginlist = plugin_list('action'); + + foreach ($pluginlist as $plugin_name) { + $plugin =& plugin_load('action',$plugin_name); + + if ($plugin !== NULL) $plugin->register($this); + } + } + + /* + * register_hook + * + * register a hook for an event + * + * @PARAM $event (string) name used by the event, (incl '_before' or '_after' for triggers) + * @PARAM $obj (obj) object in whose scope method is to be executed, + * if NULL, method is assumed to be a globally available function + * @PARAM $method (function) event handler function + * @PARAM $param (mixed) data passed to the event handler + */ + function register_hook($event, &$obj, $method, $param) { + $this->_hooks[$event][] = array($obj, $method, $param); + } + + function process_event(&$event,$advise='') { + + $evt_name = $event->name . ($advise ? '_'.$advise : ''); + + if (!empty($this->_hooks[$evt_name])) { + $hook = reset($this->_hooks[$evt_name]); + do { + list($obj, $method, $param) = $hook; + if (is_null($obj)) { + $method($param, $event); + } else { + $obj->$method($param, $event); + } + + } while ($event->_continue && $hook = next($this->_hooks[$evt_name])); + } + + return $event->_default; + } +} + +// create the event handler +$EVENT_HANDLER = new event_handler(); |