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