diff options
Diffstat (limited to 'includes/Hooks.php')
-rw-r--r-- | includes/Hooks.php | 80 |
1 files changed, 49 insertions, 31 deletions
diff --git a/includes/Hooks.php b/includes/Hooks.php index 046a149d..dec1c442 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -32,15 +32,16 @@ function wfRunHooks($event, $args = array()) { global $wgHooks; + // Return quickly in the most common case + if ( !isset( $wgHooks[$event] ) ) { + return true; + } + if (!is_array($wgHooks)) { throw new MWException("Global hooks array is not an array!\n"); return false; } - if (!array_key_exists($event, $wgHooks)) { - return true; - } - if (!is_array($wgHooks[$event])) { throw new MWException("Hooks array for event '$event' is not an array!\n"); return false; @@ -48,59 +49,74 @@ function wfRunHooks($event, $args = array()) { foreach ($wgHooks[$event] as $index => $hook) { - $object = NULL; - $method = NULL; - $func = NULL; - $data = NULL; + $object = null; + $method = null; + $func = null; + $data = null; $have_data = false; + $closure = false; /* $hook can be: a function, an object, an array of $function and $data, * an array of just a function, an array of object and method, or an * array of object, method, and data. */ - if (is_array($hook)) { - if (count($hook) < 1) { + if ( is_array( $hook ) ) { + if ( count( $hook ) < 1 ) { throw new MWException("Empty array in hooks for " . $event . "\n"); - } else if (is_object($hook[0])) { + } else if ( is_object( $hook[0] ) ) { $object = $wgHooks[$event][$index][0]; - if (count($hook) < 2) { - $method = "on" . $event; - } else { - $method = $hook[1]; - if (count($hook) > 2) { - $data = $hook[2]; + if ( $object instanceof Closure ) { + $closure = true; + if ( count( $hook ) > 1 ) { + $data = $hook[1]; $have_data = true; } + } else { + if ( count( $hook ) < 2 ) { + $method = "on" . $event; + } else { + $method = $hook[1]; + if ( count( $hook ) > 2 ) { + $data = $hook[2]; + $have_data = true; + } + } } - } else if (is_string($hook[0])) { + } else if ( is_string( $hook[0] ) ) { $func = $hook[0]; - if (count($hook) > 1) { + if ( count( $hook ) > 1) { $data = $hook[1]; $have_data = true; } } else { - var_dump( $wgHooks ); - throw new MWException("Unknown datatype in hooks for " . $event . "\n"); + throw new MWException( "Unknown datatype in hooks for " . $event . "\n" ); } - } else if (is_string($hook)) { # functions look like strings, too + } else if ( is_string( $hook ) ) { # functions look like strings, too $func = $hook; - } else if (is_object($hook)) { + } else if ( is_object( $hook ) ) { $object = $wgHooks[$event][$index]; - $method = "on" . $event; + if ( $object instanceof Closure ) { + $closure = true; + } else { + $method = "on" . $event; + } } else { - throw new MWException("Unknown datatype in hooks for " . $event . "\n"); + throw new MWException( "Unknown datatype in hooks for " . $event . "\n" ); } /* We put the first data element on, if needed. */ - if ($have_data) { + if ( $have_data ) { $hook_args = array_merge(array($data), $args); } else { $hook_args = $args; } - if ( isset( $object ) ) { + if ( $closure ) { + $callback = $object; + $func = "hook-$event-closure"; + } elseif ( isset( $object ) ) { $func = get_class( $object ) . '::' . $method; $callback = array( $object, $method ); } elseif ( false !== ( $pos = strpos( $func, '::' ) ) ) { @@ -119,12 +135,14 @@ function wfRunHooks($event, $args = array()) { /* String return is an error; false return means stop processing. */ - if (is_string($retval)) { + if ( is_string( $retval ) ) { global $wgOut; - $wgOut->showFatalError($retval); + $wgOut->showFatalError( $retval ); return false; } elseif( $retval === null ) { - if( is_array( $callback ) ) { + if ( $closure ) { + $prettyFunc = "$event closure"; + } elseif( is_array( $callback ) ) { if( is_object( $callback[0] ) ) { $prettyClass = get_class( $callback[0] ); } else { @@ -137,7 +155,7 @@ function wfRunHooks($event, $args = array()) { throw new MWException( "Detected bug in an extension! " . "Hook $prettyFunc failed to return a value; " . "should return true to continue hook processing or false to abort." ); - } else if (!$retval) { + } else if ( !$retval ) { return false; } } |