first commit. dokuwiki.
[h2N7SspZmY.git] / inc / events.php
blob1604c73c6b0c8ea385b9fc97c20667c6db15a63c
1 <?php
2 /**
3 * DokuWiki Events
5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author Christopher Smith <chris@jalakai.co.uk>
7 */
9 if(!defined('DOKU_INC')) die('meh.');
10 require_once(DOKU_INC.'inc/pluginutils.php');
12 class Doku_Event {
14 // public properties
15 var $name = ''; // READONLY event name, objects must register against this name to see the event
16 var $data = NULL; // READWRITE data relevant to the event, no standardised format (YET!)
17 var $result = NULL; // READWRITE the results of the event action, only relevant in "_AFTER" advise
18 // event handlers may modify this if they are preventing the default action
19 // to provide the after event handlers with event results
20 var $canPreventDefault = true; // READONLY if true, event handlers can prevent the events default action
22 // private properties, event handlers can effect these through the provided methods
23 var $_default = true; // whether or not to carry out the default action associated with the event
24 var $_continue = true; // whether or not to continue propagating the event to other handlers
26 /**
27 * event constructor
29 function Doku_Event($name, &$data) {
31 $this->name = $name;
32 $this->data =& $data;
36 /**
37 * advise functions
39 * advise all registered handlers of this event
41 * if these methods are used by functions outside of this object, they must
42 * properly handle correct processing of any default action and issue an
43 * advise_after() signal. e.g.
44 * $evt = new Doku_Event(name, data);
45 * if ($evt->advise_before(canPreventDefault) {
46 * // default action code block
47 * }
48 * $evt->advise_after();
49 * unset($evt);
51 * @return results of processing the event, usually $this->_default
53 function advise_before($enablePreventDefault=true) {
54 global $EVENT_HANDLER;
56 $this->canPreventDefault = $enablePreventDefault;
57 $EVENT_HANDLER->process_event($this,'BEFORE');
59 return (!$enablePreventDefault || $this->_default);
62 function advise_after() {
63 global $EVENT_HANDLER;
65 $this->_continue = true;
66 $EVENT_HANDLER->process_event($this,'AFTER');
69 /**
70 * trigger
72 * - advise all registered (<event>_BEFORE) handlers that this event is about to take place
73 * - carry out the default action using $this->data based on $enablePrevent and
74 * $this->_default, all of which may have been modified by the event handlers.
75 * - advise all registered (<event>_AFTER) handlers that the event has taken place
77 * @return $event->results
78 * the value set by any <event>_before or <event> handlers if the default action is prevented
79 * or the results of the default action (as modified by <event>_after handlers)
80 * or NULL no action took place and no handler modified the value
82 function trigger($action=NULL, $enablePrevent=true) {
84 if (!is_callable($action)) $enablePrevent = false;
86 if ($this->advise_before($enablePrevent) && is_callable($action)) {
87 if (is_array($action)) {
88 list($obj,$method) = $action;
89 $this->result = $obj->$method($this->data);
90 } else {
91 $this->result = $action($this->data);
95 $this->advise_after();
97 return $this->result;
101 * stopPropagation
103 * stop any further processing of the event by event handlers
104 * this function does not prevent the default action taking place
106 function stopPropagation() { $this->_continue = false; }
109 * preventDefault
111 * prevent the default action taking place
113 function preventDefault() { $this->_default = false; }
116 class Doku_Event_Handler {
118 // public properties: none
120 // private properties
121 var $_hooks = array(); // array of events and their registered handlers
124 * event_handler
126 * constructor, loads all action plugins and calls their register() method giving them
127 * an opportunity to register any hooks they require
129 function Doku_Event_Handler() {
131 // load action plugins
132 $plugin = NULL;
133 $pluginlist = plugin_list('action');
135 foreach ($pluginlist as $plugin_name) {
136 $plugin =& plugin_load('action',$plugin_name);
138 if ($plugin !== NULL) $plugin->register($this);
143 * register_hook
145 * register a hook for an event
147 * @PARAM $event (string) name used by the event, (incl '_before' or '_after' for triggers)
148 * @PARAM $obj (obj) object in whose scope method is to be executed,
149 * if NULL, method is assumed to be a globally available function
150 * @PARAM $method (function) event handler function
151 * @PARAM $param (mixed) data passed to the event handler
153 function register_hook($event, $advise, &$obj, $method, $param=NULL) {
154 $this->_hooks[$event.'_'.$advise][] = array(&$obj, $method, $param);
157 function process_event(&$event,$advise='') {
159 $evt_name = $event->name . ($advise ? '_'.$advise : '_BEFORE');
161 if (!empty($this->_hooks[$evt_name])) {
162 $hook = reset($this->_hooks[$evt_name]);
163 do {
164 // list($obj, $method, $param) = $hook;
165 $obj =& $hook[0];
166 $method = $hook[1];
167 $param = $hook[2];
169 if (is_null($obj)) {
170 $method($event, $param);
171 } else {
172 $obj->$method($event, $param);
175 } while ($event->_continue && $hook = next($this->_hooks[$evt_name]));
181 * trigger_event
183 * function wrapper to process (create, trigger and destroy) an event
185 * @PARAM $name (string) name for the event
186 * @PARAM $data (mixed) event data
187 * @PARAM $action (callback) (optional, default=NULL) default action, a php callback function
188 * @PARAM $canPreventDefault (bool) (optional, default=true) can hooks prevent the default action
190 * @RETURN (mixed) the event results value after all event processing is complete
191 * by default this is the return value of the default action however
192 * it can be set or modified by event handler hooks
194 function trigger_event($name, &$data, $action=NULL, $canPreventDefault=true) {
196 $evt = new Doku_Event($name, $data);
197 return $evt->trigger($action, $canPreventDefault);
200 // create the event handler
201 global $EVENT_HANDLER;
202 $EVENT_HANDLER = new Doku_Event_Handler();