Completed
Push — psr2 ( 1a953a...9ddafc )
by Andreas
19:17 queued 15:31
created

Doku_Event_Handler::hasHandlerForEvent()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 2
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * DokuWiki Events
4
 *
5
 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6
 * @author     Christopher Smith <[email protected]>
7
 */
8
9
/**
10
 * The event
11
 */
12
class Doku_Event {
13
14
    // public properties
15
    public $name = '';                // READONLY  event name, objects must register against this name to see the event
16
    public $data = null;              // READWRITE data relevant to the event, no standardised format (YET!)
17
    public $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
    public $canPreventDefault = true; // READONLY  if true, event handlers can prevent the events default action
21
22
    // private properties, event handlers can effect these through the provided methods
23
    protected $_default = true;     // whether or not to carry out the default action associated with the event
24
    protected $_continue = true;    // whether or not to continue propagating the event to other handlers
25
26
    /**
27
     * event constructor
28
     *
29
     * @param string $name
30
     * @param mixed $data
31
     */
32
    public function __construct($name, &$data) {
33
34
        $this->name = $name;
35
        $this->data =& $data;
36
37
    }
38
39
    /**
40
     * @return string
41
     */
42
    public function __toString() {
43
        return $this->name;
44
    }
45
46
    /**
47
     * advise functions
48
     *
49
     * advise all registered handlers of this event
50
     *
51
     * if these methods are used by functions outside of this object, they must
52
     * properly handle correct processing of any default action and issue an
53
     * advise_after() signal. e.g.
54
     *    $evt = new Doku_Event(name, data);
55
     *    if ($evt->advise_before(canPreventDefault) {
56
     *      // default action code block
57
     *    }
58
     *    $evt->advise_after();
59
     *    unset($evt);
60
     *
61
     * @param bool $enablePreventDefault
62
     * @return bool results of processing the event, usually $this->_default
63
     */
64
    public function advise_before($enablePreventDefault=true) {
65
        global $EVENT_HANDLER;
66
67
        $this->canPreventDefault = $enablePreventDefault;
68
        $EVENT_HANDLER->process_event($this,'BEFORE');
69
70
        return (!$enablePreventDefault || $this->_default);
71
    }
72
73
    public function advise_after() {
74
        global $EVENT_HANDLER;
75
76
        $this->_continue = true;
77
        $EVENT_HANDLER->process_event($this,'AFTER');
78
    }
79
80
    /**
81
     * trigger
82
     *
83
     * - advise all registered (<event>_BEFORE) handlers that this event is about to take place
84
     * - carry out the default action using $this->data based on $enablePrevent and
85
     *   $this->_default, all of which may have been modified by the event handlers.
86
     * - advise all registered (<event>_AFTER) handlers that the event has taken place
87
     *
88
     * @param null|callable $action
89
     * @param bool $enablePrevent
90
     * @return  mixed $event->results
91
     *          the value set by any <event>_before or <event> handlers if the default action is prevented
92
     *          or the results of the default action (as modified by <event>_after handlers)
93
     *          or NULL no action took place and no handler modified the value
94
     */
95
    public function trigger($action=null, $enablePrevent=true) {
96
97
        if (!is_callable($action)) {
98
            $enablePrevent = false;
99
            if (!is_null($action)) {
100
                trigger_error(
101
                    'The default action of ' . $this .
102
                    ' is not null but also not callable. Maybe the method is not public?',
103
                    E_USER_WARNING
104
                );
105
            }
106
        }
107
108
        if ($this->advise_before($enablePrevent) && is_callable($action)) {
109
            if (is_array($action)) {
110
                list($obj,$method) = $action;
111
                $this->result = $obj->$method($this->data);
112
            } else {
113
                $this->result = $action($this->data);
114
            }
115
        }
116
117
        $this->advise_after();
118
119
        return $this->result;
120
    }
121
122
    /**
123
     * stopPropagation
124
     *
125
     * stop any further processing of the event by event handlers
126
     * this function does not prevent the default action taking place
127
     */
128
    public function stopPropagation() {
129
        $this->_continue = false;
130
    }
131
132
    /**
133
     * may the event propagate to the next handler?
134
     *
135
     * @return bool
136
     */
137
    public function mayPropagate() {
138
        return $this->_continue;
139
    }
140
141
    /**
142
     * preventDefault
143
     *
144
     * prevent the default action taking place
145
     */
146
    public function preventDefault() {
147
        $this->_default = false;
148
    }
149
150
    /**
151
     * should the default action be executed?
152
     *
153
     * @return bool
154
     */
155
    public function mayRunDefault() {
156
        return $this->_default;
157
    }
158
}
159
160
/**
161
 * Controls the registration and execution of all events,
162
 */
163
class Doku_Event_Handler {
164
165
    // public properties:  none
166
167
    // private properties
168
    protected $_hooks = array();          // array of events and their registered handlers
169
170
    /**
171
     * event_handler
172
     *
173
     * constructor, loads all action plugins and calls their register() method giving them
174
     * an opportunity to register any hooks they require
175
     */
176
    public function __construct() {
177
178
        // load action plugins
179
        /** @var DokuWiki_Action_Plugin $plugin */
180
        $plugin = null;
0 ignored issues
show
Unused Code introduced by
$plugin is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
181
        $pluginlist = plugin_list('action');
182
183
        foreach ($pluginlist as $plugin_name) {
184
            $plugin = plugin_load('action',$plugin_name);
185
186
            if ($plugin !== null) $plugin->register($this);
187
        }
188
    }
189
190
    /**
191
     * register_hook
192
     *
193
     * register a hook for an event
194
     *
195
     * @param  string   $event   string   name used by the event, (incl '_before' or '_after' for triggers)
196
     * @param  string   $advise
197
     * @param  object   $obj     object in whose scope method is to be executed,
198
     *                             if NULL, method is assumed to be a globally available function
199
     * @param  string   $method  event handler function
200
     * @param  mixed    $param   data passed to the event handler
201
     * @param  int      $seq     sequence number for ordering hook execution (ascending)
202
     */
203
    public function register_hook($event, $advise, $obj, $method, $param=null, $seq=0) {
204
        $seq = (int)$seq;
205
        $doSort = !isset($this->_hooks[$event.'_'.$advise][$seq]);
206
        $this->_hooks[$event.'_'.$advise][$seq][] = array($obj, $method, $param);
207
208
        if ($doSort) {
209
            ksort($this->_hooks[$event.'_'.$advise]);
210
        }
211
    }
212
213
    /**
214
     * process the before/after event
215
     *
216
     * @param Doku_Event $event
217
     * @param string     $advise BEFORE or AFTER
218
     */
219
    public function process_event($event,$advise='') {
220
221
        $evt_name = $event->name . ($advise ? '_'.$advise : '_BEFORE');
222
223
        if (!empty($this->_hooks[$evt_name])) {
224
            foreach ($this->_hooks[$evt_name] as $sequenced_hooks) {
225
                foreach ($sequenced_hooks as $hook) {
226
                    list($obj, $method, $param) = $hook;
227
228
                    if (is_null($obj)) {
229
                        $method($event, $param);
230
                    } else {
231
                        $obj->$method($event, $param);
232
                    }
233
234
                    if (!$event->mayPropagate()) return;
235
                }
236
            }
237
        }
238
    }
239
240
    /**
241
     * Check if an event has any registered handlers
242
     *
243
     * When $advise is empty, both BEFORE and AFTER events will be considered,
244
     * otherwise only the given advisory is checked
245
     *
246
     * @param string $name Name of the event
247
     * @param string $advise BEFORE, AFTER or empty
248
     * @return bool
249
     */
250
    public function hasHandlerForEvent($name, $advise = '') {
251
        if($advise) {
252
            return isset($this->_hooks[$name . '_' . $advise]);
253
        } else {
254
            return isset($this->_hooks[$name . '_BEFORE']) || isset($this->_hooks[$name . '_AFTER']);
255
        }
256
    }
257
}
258
259
/**
260
 * trigger_event
261
 *
262
 * function wrapper to process (create, trigger and destroy) an event
263
 *
264
 * @param  string   $name               name for the event
265
 * @param  mixed    $data               event data
266
 * @param  callback $action             (optional, default=NULL) default action, a php callback function
267
 * @param  bool     $canPreventDefault  (optional, default=true) can hooks prevent the default action
268
 *
269
 * @return mixed                        the event results value after all event processing is complete
270
 *                                      by default this is the return value of the default action however
271
 *                                      it can be set or modified by event handler hooks
272
 */
273
function trigger_event($name, &$data, $action=null, $canPreventDefault=true) {
274
275
    $evt = new Doku_Event($name, $data);
276
    return $evt->trigger($action, $canPreventDefault);
277
}
278