summaryrefslogtreecommitdiff
path: root/inc/events.php
diff options
context:
space:
mode:
Diffstat (limited to 'inc/events.php')
-rw-r--r--inc/events.php162
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();