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