X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FHooks.php;h=a05f732b40a11919284b3b9afb69505ab4cac2d9;hb=7a605cce46eb688dfb697487a1b1d300bef4361c;hp=56ca88d4036411ff3c2aef84bc60860c8db51e77;hpb=80d9f05b37d909690e9c24001f2e09e6b703fcbb;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Hooks.php b/includes/Hooks.php index 56ca88d403..a05f732b40 100644 --- a/includes/Hooks.php +++ b/includes/Hooks.php @@ -1,7 +1,7 @@ . + * Copyright 2004, 2005 Evan Prodromou . * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,116 +15,149 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * - * @author - * @package MediaWiki - * @seealso hooks.doc + * @author Evan Prodromou + * @see hooks.txt + * @file */ -if (defined('MEDIAWIKI')) { - - /* - * Because programmers assign to $wgHooks, we need to be very - * careful about its contents. So, there's a lot more error-checking - * in here than would normally be necessary. - */ - - function wfRunHooks() { - - global $wgHooks; - - if (!is_array($wgHooks)) { - wfDieDebugBacktrace("Global hooks array is not an array!\n"); - return false; - } - $args = func_get_args(); +/** + * Because programmers assign to $wgHooks, we need to be very + * careful about its contents. So, there's a lot more error-checking + * in here than would normally be necessary. + */ +function wfRunHooks($event, $args = array()) { - if (count($args) < 1) { - wfDieDebugBacktrace("No event name given for wfRunHooks().\n"); - return false; - } + global $wgHooks; - $event = array_shift($args); + if (!is_array($wgHooks)) { + throw new MWException("Global hooks array is not an array!\n"); + return false; + } - if (!array_key_exists($wgHooks, $event)) { - return true; - } + if (!array_key_exists($event, $wgHooks)) { + return true; + } - if (!is_array($wgHooks[$event])) { - wfDieDebugBacktrace("Hooks array for event '$event' is not an array!\n"); - return false; - } + if (!is_array($wgHooks[$event])) { + throw new MWException("Hooks array for event '$event' is not an array!\n"); + return false; + } + + foreach ($wgHooks[$event] as $index => $hook) { + + $object = NULL; + $method = NULL; + $func = NULL; + $data = NULL; + $have_data = false; + $closure = false; - foreach ($wgHooks[$event] as $hook) { - - $object = NULL; - $method = NULL; - $func = NULL; - $data = NULL; - $have_data = 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) { - wfDieDebugBacktrace("Empty array in hooks for " . $event . "\n"); - } else if (is_object($hook[0])) { - $object = $hook[0]; - if (count($hook) < 2) { + /* $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 ) { + throw new MWException("Empty array in hooks for " . $event . "\n"); + } else if ( is_object( $hook[0] ) ) { + $object = $wgHooks[$event][$index][0]; + 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) { + if ( count( $hook ) > 2 ) { $data = $hook[2]; $have_data = true; } } - } else if (is_string($hook[0])) { - $func = $hook[0]; - if (count($hook) > 1) { - $data = $hook[1]; - $have_data = true; - } - } else { - wfDieDebugBacktrace("Unknown datatype in hooks for " . $event . "\n"); } - } else if (is_string($hook)) { # functions look like strings, too - $func = $hook; - } else if (is_object($hook)) { - $object = $hook; - $method = "on" . $event; + } else if ( is_string( $hook[0] ) ) { + $func = $hook[0]; + if ( count( $hook ) > 1) { + $data = $hook[1]; + $have_data = true; + } } else { - wfDieDebugBacktrace("Unknown datatype in hooks for " . $event . "\n"); + throw new MWException( "Unknown datatype in hooks for " . $event . "\n" ); } - - if ($have_data) { - $hook_args = array_merge(array($data), $args); + } else if ( is_string( $hook ) ) { # functions look like strings, too + $func = $hook; + } else if ( is_object( $hook ) ) { + $object = $wgHooks[$event][$index]; + if ( $object instanceof Closure ) { + $closure = true; } else { - $hook_args = $args; + $method = "on" . $event; } - - if ($object) { - $retval = call_user_func_array(array($object, $method), $hook_args); + } else { + throw new MWException( "Unknown datatype in hooks for " . $event . "\n" ); + } + + /* We put the first data element on, if needed. */ + + if ( $have_data ) { + $hook_args = array_merge(array($data), $args); + } else { + $hook_args = $args; + } + + 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, '::' ) ) ) { + $callback = array( substr( $func, 0, $pos ), substr( $func, $pos + 2 ) ); + } else { + $callback = $func; + } + + // Run autoloader (workaround for call_user_func_array bug) + is_callable( $callback ); + + /* Call the hook. */ + wfProfileIn( $func ); + $retval = call_user_func_array( $callback, $hook_args ); + wfProfileOut( $func ); + + /* String return is an error; false return means stop processing. */ + + if ( is_string( $retval ) ) { + global $wgOut; + $wgOut->showFatalError( $retval ); + return false; + } elseif( $retval === null ) { + if ( $closure ) { + $prettyFunc = "$event closure"; + } elseif( is_array( $callback ) ) { + if( is_object( $callback[0] ) ) { + $prettyClass = get_class( $callback[0] ); + } else { + $prettyClass = strval( $callback[0] ); + } + $prettyFunc = $prettyClass . '::' . strval( $callback[1] ); } else { - $retval = call_user_func_array($func, $hook_args); - } - - if (is_string($retval)) { - global $wgOut; - $wgOut->fatalError($retval); - return false; - } else if (!$retval) { - return false; + $prettyFunc = strval( $callback ); } + 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 ) { + return false; } - - return true; } -} -?> + return true; +}