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