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