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