From b95f73d374c43006a82eddd35b630bd10a9fbb5f Mon Sep 17 00:00:00 2001 From: Christopher Smith Date: Sun, 16 Feb 2014 16:20:54 +0000 Subject: Add ordering to event handlers Allows a sequence integer to be supplied when registering to handle an event. When processing an event, handlers (hooks) will be executed in ascending order of their sequence number. If two or more handlers have the same sequence number their order of execution is undefined. A handler wanting to be first, should use -PHP_MAX_INT. A handler wanting to be last can use PHP_MAX_INT. There may be conflicts if two or more plugins use these values in the expectation that they will guarantee being first or last. --- inc/events.php | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'inc/events.php') diff --git a/inc/events.php b/inc/events.php index f7b1a7a16..9c3169b34 100644 --- a/inc/events.php +++ b/inc/events.php @@ -148,9 +148,10 @@ class Doku_Event_Handler { * if NULL, method is assumed to be a globally available function * @param $method (function) event handler function * @param $param (mixed) data passed to the event handler + * @param $seq (int) sequence number for ordering hook execution (ascending) */ - function register_hook($event, $advise, $obj, $method, $param=null) { - $this->_hooks[$event.'_'.$advise][] = array($obj, $method, $param); + function register_hook($event, $advise, $obj, $method, $param=null, $seq=0) { + $this->_hooks[$event.'_'.$advise][] = array($obj, $method, $param, (int)$seq); } function process_event(&$event,$advise='') { @@ -158,8 +159,8 @@ class Doku_Event_Handler { $evt_name = $event->name . ($advise ? '_'.$advise : '_BEFORE'); if (!empty($this->_hooks[$evt_name])) { - foreach ($this->_hooks[$evt_name] as $hook) { - // list($obj, $method, $param) = $hook; + foreach ($this->sort_hooks($this->_hooks[$evt_name]) as $hook) { + // list($obj, $method, $param, $seq) = $hook; $obj =& $hook[0]; $method = $hook[1]; $param = $hook[2]; @@ -174,6 +175,20 @@ class Doku_Event_Handler { } } } + + protected function sort_hooks($hooks) { + usort($hooks, array('Doku_Event_Handler','cmp_hooks')); + return $hooks; + } + + public static function cmp_hooks($a, $b) { + if ($a[3] == $b[3]) { + return 0; + } + + return ($a[3] < $b[3]) ? -1 : 1; + } + } /** -- cgit v1.2.3