Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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();