diff options
author | chris <chris@jalakai.co.uk> | 2006-04-14 21:37:37 +0200 |
---|---|---|
committer | chris <chris@jalakai.co.uk> | 2006-04-14 21:37:37 +0200 |
commit | f65bfee1954d6697e5002f4253d0a7d2d1940eb6 (patch) | |
tree | 9dcac5e578987a6aea9a4ea043f25a9b0fabaaa3 /inc/events.php | |
parent | c4e0e4a153fee5f985668670a91b2cd94a17dd75 (diff) | |
download | rpg-f65bfee1954d6697e5002f4253d0a7d2d1940eb6.tar.gz rpg-f65bfee1954d6697e5002f4253d0a7d2d1940eb6.tar.bz2 |
action plugins
This patch adds events and a third plugin type, "action" plugins, to DokuWiki.
The patch doesn't include any event signalling, that will be added in later patches.
Action plugins are loaded before most Dokuwiki processing takes place and at the
same time are given the opportunity to register handlers (or hooks) to receive
specific dokuwiki events.
Other parts of Dokuwiki (e.g. templates and syntax plugins) can also register
handlers to receive events.
Any part of Dokuwiki can create and signal events, including templates and plugins.
This patch also revises the admin plugin class by making it an extension of a
new class, DokuWiki_Plugin. The DokuWiki_Plugin_Action class also extends this
new class.
Further details of events, their signalling and handling, and of action plugins will
be added to wiki.splitbrain.org in due course :-)
darcs-hash:20060414193737-9b6ab-f23d3d9b93e4c50a3ad97ced03eabc6c0363650b.gz
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(); |