Skip to content

Commit

Permalink
Add ordering to event handlers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Chris--S committed Feb 16, 2014
1 parent 221cb66 commit b95f73d
Showing 1 changed file with 19 additions and 4 deletions.
23 changes: 19 additions & 4 deletions inc/events.php
Expand Up @@ -148,18 +148,19 @@ function 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='') {

$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];
Expand All @@ -174,6 +175,20 @@ function process_event(&$event,$advise='') {
}
}
}

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;
}

}

/**
Expand Down

0 comments on commit b95f73d

Please sign in to comment.