Failed Conditions
Push — psr2-pluginredux ( 89614c )
by Andreas
05:43 queued 03:04
created

Event::trigger()   B

Complexity

Conditions 6
Paths 9

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 9
nop 2
dl 0
loc 27
rs 8.8657
c 0
b 0
f 0
1
<?php
2
3
namespace dokuwiki\Extension;
4
5
/**
6
 * The Action plugin event
7
 */
8
class Event
9
{
10
11
    // public properties
12
    public $name = '';                // READONLY  event name, objects must register against this name to see the event
13
    public $data = null;              // READWRITE data relevant to the event, no standardised format (YET!)
14
    public $result = null;            // READWRITE the results of the event action, only relevant in "_AFTER" advise
15
    //    event handlers may modify this if they are preventing the default action
16
    //    to provide the after event handlers with event results
17
    public $canPreventDefault = true; // READONLY  if true, event handlers can prevent the events default action
18
19
    // private properties, event handlers can effect these through the provided methods
20
    protected $_default = true;     // whether or not to carry out the default action associated with the event
21
    protected $_continue = true;    // whether or not to continue propagating the event to other handlers
22
23
    /**
24
     * event constructor
25
     *
26
     * @param string $name
27
     * @param mixed $data
28
     */
29
    public function __construct($name, &$data)
30
    {
31
32
        $this->name = $name;
33
        $this->data =& $data;
34
35
    }
36
37
    /**
38
     * @return string
39
     */
40
    public function __toString()
41
    {
42
        return $this->name;
43
    }
44
45
    /**
46
     * advise functions
47
     *
48
     * advise all registered handlers of this event
49
     *
50
     * if these methods are used by functions outside of this object, they must
51
     * properly handle correct processing of any default action and issue an
52
     * advise_after() signal. e.g.
53
     *    $evt = new dokuwiki\Plugin\Doku_Event(name, data);
54
     *    if ($evt->advise_before(canPreventDefault) {
55
     *      // default action code block
56
     *    }
57
     *    $evt->advise_after();
58
     *    unset($evt);
59
     *
60
     * @param bool $enablePreventDefault
61
     * @return bool results of processing the event, usually $this->_default
62
     */
63
    public function advise_before($enablePreventDefault = true)
64
    {
65
        global $EVENT_HANDLER;
66
67
        $this->canPreventDefault = $enablePreventDefault;
68
        if($EVENT_HANDLER !== null) {
69
            $EVENT_HANDLER->process_event($this, 'BEFORE');
70
        } else {
71
            dbglog($this->name.':BEFORE event triggered before event system was initialized');
72
        }
73
74
        return (!$enablePreventDefault || $this->_default);
75
    }
76
77
    public function advise_after()
78
    {
79
        global $EVENT_HANDLER;
80
81
        $this->_continue = true;
82
83
        if($EVENT_HANDLER !== null) {
84
            $EVENT_HANDLER->process_event($this, 'AFTER');
85
        } else {
86
            dbglog($this->name.':AFTER event triggered before event system was initialized');
87
        }
88
    }
89
90
    /**
91
     * trigger
92
     *
93
     * - advise all registered (<event>_BEFORE) handlers that this event is about to take place
94
     * - carry out the default action using $this->data based on $enablePrevent and
95
     *   $this->_default, all of which may have been modified by the event handlers.
96
     * - advise all registered (<event>_AFTER) handlers that the event has taken place
97
     *
98
     * @param null|callable $action
99
     * @param bool $enablePrevent
100
     * @return  mixed $event->results
101
     *          the value set by any <event>_before or <event> handlers if the default action is prevented
102
     *          or the results of the default action (as modified by <event>_after handlers)
103
     *          or NULL no action took place and no handler modified the value
104
     */
105
    public function trigger($action = null, $enablePrevent = true)
106
    {
107
108
        if (!is_callable($action)) {
109
            $enablePrevent = false;
110
            if (!is_null($action)) {
111
                trigger_error(
112
                    'The default action of ' . $this .
113
                    ' is not null but also not callable. Maybe the method is not public?',
114
                    E_USER_WARNING
115
                );
116
            }
117
        }
118
119
        if ($this->advise_before($enablePrevent) && is_callable($action)) {
120
            if (is_array($action)) {
121
                list($obj, $method) = $action;
122
                $this->result = $obj->$method($this->data);
123
            } else {
124
                $this->result = $action($this->data);
125
            }
126
        }
127
128
        $this->advise_after();
129
130
        return $this->result;
131
    }
132
133
    /**
134
     * stopPropagation
135
     *
136
     * stop any further processing of the event by event handlers
137
     * this function does not prevent the default action taking place
138
     */
139
    public function stopPropagation()
140
    {
141
        $this->_continue = false;
142
    }
143
144
    /**
145
     * may the event propagate to the next handler?
146
     *
147
     * @return bool
148
     */
149
    public function mayPropagate()
150
    {
151
        return $this->_continue;
152
    }
153
154
    /**
155
     * preventDefault
156
     *
157
     * prevent the default action taking place
158
     */
159
    public function preventDefault()
160
    {
161
        $this->_default = false;
162
    }
163
164
    /**
165
     * should the default action be executed?
166
     *
167
     * @return bool
168
     */
169
    public function mayRunDefault()
170
    {
171
        return $this->_default;
172
    }
173
174
    /**
175
     * Convenience method to trigger an event
176
     *
177
     * Creates, triggers and destroys an event in one go
178
     *
179
     * @param  string   $name               name for the event
180
     * @param  mixed    $data               event data
181
     * @param  callable $action             (optional, default=NULL) default action, a php callback function
182
     * @param  bool     $canPreventDefault  (optional, default=true) can hooks prevent the default action
183
     *
184
     * @return mixed                        the event results value after all event processing is complete
185
     *                                      by default this is the return value of the default action however
186
     *                                      it can be set or modified by event handler hooks
187
     */
188
    static public function createAndTrigger($name, &$data, $action=null, $canPreventDefault=true) {
189
        $evt = new Event($name, $data);
190
        return $evt->trigger($action, $canPreventDefault);
191
    }
192
}
193