xref: /dokuwiki/inc/Extension/EventHandler.php (revision e1d9dcc8b460b6f029ac9c8d5d3b8d23b6e73402)
1*e1d9dcc8SAndreas Gohr<?php
2*e1d9dcc8SAndreas Gohr
3*e1d9dcc8SAndreas Gohrnamespace dokuwiki\Extension;
4*e1d9dcc8SAndreas Gohr
5*e1d9dcc8SAndreas Gohr/**
6*e1d9dcc8SAndreas Gohr * Controls the registration and execution of all events,
7*e1d9dcc8SAndreas Gohr */
8*e1d9dcc8SAndreas Gohrclass EventHandler
9*e1d9dcc8SAndreas Gohr{
10*e1d9dcc8SAndreas Gohr
11*e1d9dcc8SAndreas Gohr    // public properties:  none
12*e1d9dcc8SAndreas Gohr
13*e1d9dcc8SAndreas Gohr    // private properties
14*e1d9dcc8SAndreas Gohr    protected $_hooks = array();          // array of events and their registered handlers
15*e1d9dcc8SAndreas Gohr
16*e1d9dcc8SAndreas Gohr    /**
17*e1d9dcc8SAndreas Gohr     * event_handler
18*e1d9dcc8SAndreas Gohr     *
19*e1d9dcc8SAndreas Gohr     * constructor, loads all action plugins and calls their register() method giving them
20*e1d9dcc8SAndreas Gohr     * an opportunity to register any hooks they require
21*e1d9dcc8SAndreas Gohr     */
22*e1d9dcc8SAndreas Gohr    public function __construct()
23*e1d9dcc8SAndreas Gohr    {
24*e1d9dcc8SAndreas Gohr
25*e1d9dcc8SAndreas Gohr        // load action plugins
26*e1d9dcc8SAndreas Gohr        /** @var ActionPlugin $plugin */
27*e1d9dcc8SAndreas Gohr        $plugin = null;
28*e1d9dcc8SAndreas Gohr        $pluginlist = plugin_list('action');
29*e1d9dcc8SAndreas Gohr
30*e1d9dcc8SAndreas Gohr        foreach ($pluginlist as $plugin_name) {
31*e1d9dcc8SAndreas Gohr            $plugin = plugin_load('action', $plugin_name);
32*e1d9dcc8SAndreas Gohr
33*e1d9dcc8SAndreas Gohr            if ($plugin !== null) $plugin->register($this);
34*e1d9dcc8SAndreas Gohr        }
35*e1d9dcc8SAndreas Gohr    }
36*e1d9dcc8SAndreas Gohr
37*e1d9dcc8SAndreas Gohr    /**
38*e1d9dcc8SAndreas Gohr     * register_hook
39*e1d9dcc8SAndreas Gohr     *
40*e1d9dcc8SAndreas Gohr     * register a hook for an event
41*e1d9dcc8SAndreas Gohr     *
42*e1d9dcc8SAndreas Gohr     * @param  string $event string   name used by the event, (incl '_before' or '_after' for triggers)
43*e1d9dcc8SAndreas Gohr     * @param  string $advise
44*e1d9dcc8SAndreas Gohr     * @param  object $obj object in whose scope method is to be executed,
45*e1d9dcc8SAndreas Gohr     *                             if NULL, method is assumed to be a globally available function
46*e1d9dcc8SAndreas Gohr     * @param  string $method event handler function
47*e1d9dcc8SAndreas Gohr     * @param  mixed $param data passed to the event handler
48*e1d9dcc8SAndreas Gohr     * @param  int $seq sequence number for ordering hook execution (ascending)
49*e1d9dcc8SAndreas Gohr     */
50*e1d9dcc8SAndreas Gohr    public function register_hook($event, $advise, $obj, $method, $param = null, $seq = 0)
51*e1d9dcc8SAndreas Gohr    {
52*e1d9dcc8SAndreas Gohr        $seq = (int)$seq;
53*e1d9dcc8SAndreas Gohr        $doSort = !isset($this->_hooks[$event . '_' . $advise][$seq]);
54*e1d9dcc8SAndreas Gohr        $this->_hooks[$event . '_' . $advise][$seq][] = array($obj, $method, $param);
55*e1d9dcc8SAndreas Gohr
56*e1d9dcc8SAndreas Gohr        if ($doSort) {
57*e1d9dcc8SAndreas Gohr            ksort($this->_hooks[$event . '_' . $advise]);
58*e1d9dcc8SAndreas Gohr        }
59*e1d9dcc8SAndreas Gohr    }
60*e1d9dcc8SAndreas Gohr
61*e1d9dcc8SAndreas Gohr    /**
62*e1d9dcc8SAndreas Gohr     * process the before/after event
63*e1d9dcc8SAndreas Gohr     *
64*e1d9dcc8SAndreas Gohr     * @param Event $event
65*e1d9dcc8SAndreas Gohr     * @param string $advise BEFORE or AFTER
66*e1d9dcc8SAndreas Gohr     */
67*e1d9dcc8SAndreas Gohr    public function process_event($event, $advise = '')
68*e1d9dcc8SAndreas Gohr    {
69*e1d9dcc8SAndreas Gohr
70*e1d9dcc8SAndreas Gohr        $evt_name = $event->name . ($advise ? '_' . $advise : '_BEFORE');
71*e1d9dcc8SAndreas Gohr
72*e1d9dcc8SAndreas Gohr        if (!empty($this->_hooks[$evt_name])) {
73*e1d9dcc8SAndreas Gohr            foreach ($this->_hooks[$evt_name] as $sequenced_hooks) {
74*e1d9dcc8SAndreas Gohr                foreach ($sequenced_hooks as $hook) {
75*e1d9dcc8SAndreas Gohr                    list($obj, $method, $param) = $hook;
76*e1d9dcc8SAndreas Gohr
77*e1d9dcc8SAndreas Gohr                    if (is_null($obj)) {
78*e1d9dcc8SAndreas Gohr                        $method($event, $param);
79*e1d9dcc8SAndreas Gohr                    } else {
80*e1d9dcc8SAndreas Gohr                        $obj->$method($event, $param);
81*e1d9dcc8SAndreas Gohr                    }
82*e1d9dcc8SAndreas Gohr
83*e1d9dcc8SAndreas Gohr                    if (!$event->mayPropagate()) return;
84*e1d9dcc8SAndreas Gohr                }
85*e1d9dcc8SAndreas Gohr            }
86*e1d9dcc8SAndreas Gohr        }
87*e1d9dcc8SAndreas Gohr    }
88*e1d9dcc8SAndreas Gohr
89*e1d9dcc8SAndreas Gohr    /**
90*e1d9dcc8SAndreas Gohr     * Check if an event has any registered handlers
91*e1d9dcc8SAndreas Gohr     *
92*e1d9dcc8SAndreas Gohr     * When $advise is empty, both BEFORE and AFTER events will be considered,
93*e1d9dcc8SAndreas Gohr     * otherwise only the given advisory is checked
94*e1d9dcc8SAndreas Gohr     *
95*e1d9dcc8SAndreas Gohr     * @param string $name Name of the event
96*e1d9dcc8SAndreas Gohr     * @param string $advise BEFORE, AFTER or empty
97*e1d9dcc8SAndreas Gohr     * @return bool
98*e1d9dcc8SAndreas Gohr     */
99*e1d9dcc8SAndreas Gohr    public function hasHandlerForEvent($name, $advise = '')
100*e1d9dcc8SAndreas Gohr    {
101*e1d9dcc8SAndreas Gohr        if ($advise) {
102*e1d9dcc8SAndreas Gohr            return isset($this->_hooks[$name . '_' . $advise]);
103*e1d9dcc8SAndreas Gohr        } else {
104*e1d9dcc8SAndreas Gohr            return isset($this->_hooks[$name . '_BEFORE']) || isset($this->_hooks[$name . '_AFTER']);
105*e1d9dcc8SAndreas Gohr        }
106*e1d9dcc8SAndreas Gohr    }
107*e1d9dcc8SAndreas Gohr}
108