MediaWiki  1.23.2
Hooks.php
Go to the documentation of this file.
1 <?php
2 
30 class MWHookException extends MWException {}
31 
39 class Hooks {
40 
45  protected static $handlers = array();
46 
55  public static function register( $name, $callback ) {
56  if ( !isset( self::$handlers[$name] ) ) {
57  self::$handlers[$name] = array();
58  }
59 
60  self::$handlers[$name][] = $callback;
61  }
62 
72  public static function clear( $name ) {
73  if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
74  throw new MWException( 'Cannot reset hooks in operation.' );
75  }
76 
77  unset( self::$handlers[$name] );
78  }
79 
89  public static function isRegistered( $name ) {
91  return !empty( $wgHooks[$name] ) || !empty( self::$handlers[$name] );
92  }
93 
103  public static function getHandlers( $name ) {
105 
106  if ( !self::isRegistered( $name ) ) {
107  return array();
108  } elseif ( !isset( self::$handlers[$name] ) ) {
109  return $wgHooks[$name];
110  } elseif ( !isset( $wgHooks[$name] ) ) {
111  return self::$handlers[$name];
112  } else {
113  return array_merge( self::$handlers[$name], $wgHooks[$name] );
114  }
115  }
116 
136  public static function run( $event, array $args = array(), $deprecatedVersion = null ) {
137  wfProfileIn( 'hook: ' . $event );
138  foreach ( self::getHandlers( $event ) as $hook ) {
139  // Turn non-array values into an array. (Can't use casting because of objects.)
140  if ( !is_array( $hook ) ) {
141  $hook = array( $hook );
142  }
143 
144  if ( !array_filter( $hook ) ) {
145  // Either array is empty or it's an array filled with null/false/empty.
146  continue;
147  } elseif ( is_array( $hook[0] ) ) {
148  // First element is an array, meaning the developer intended
149  // the first element to be a callback. Merge it in so that
150  // processing can be uniform.
151  $hook = array_merge( $hook[0], array_slice( $hook, 1 ) );
152  }
153 
159  if ( $hook[0] instanceof Closure ) {
160  $func = "hook-$event-closure";
161  $callback = array_shift( $hook );
162  } elseif ( is_object( $hook[0] ) ) {
163  $object = array_shift( $hook );
164  $method = array_shift( $hook );
165 
166  // If no method was specified, default to on$event.
167  if ( $method === null ) {
168  $method = "on$event";
169  }
170 
171  $func = get_class( $object ) . '::' . $method;
172  $callback = array( $object, $method );
173  } elseif ( is_string( $hook[0] ) ) {
174  $func = $callback = array_shift( $hook );
175  } else {
176  throw new MWException( 'Unknown datatype in hooks for ' . $event . "\n" );
177  }
178 
179  // Run autoloader (workaround for call_user_func_array bug)
180  // and throw error if not callable.
181  if ( !is_callable( $callback ) ) {
182  throw new MWException( 'Invalid callback in hooks for ' . $event . "\n" );
183  }
184 
185  /*
186  * Call the hook. The documentation of call_user_func_array says
187  * false is returned on failure. However, if the function signature
188  * does not match the call signature, PHP will issue an warning and
189  * return null instead. The following code catches that warning and
190  * provides better error message.
191  */
192  $retval = null;
193  $badhookmsg = null;
194  $hook_args = array_merge( $hook, $args );
195 
196  // Profile first in case the Profiler causes errors.
197  wfProfileIn( $func );
198  set_error_handler( 'Hooks::hookErrorHandler' );
199 
200  // mark hook as deprecated, if deprecation version is specified
201  if ( $deprecatedVersion !== null ) {
202  wfDeprecated( "$event hook (used in $func)", $deprecatedVersion );
203  }
204 
205  try {
206  $retval = call_user_func_array( $callback, $hook_args );
207  } catch ( MWHookException $e ) {
208  $badhookmsg = $e->getMessage();
209  } catch ( Exception $e ) {
210  restore_error_handler();
211  throw $e;
212  }
213  restore_error_handler();
214  wfProfileOut( $func );
215 
216  // Process the return value.
217  if ( is_string( $retval ) ) {
218  // String returned means error.
219  throw new FatalError( $retval );
220  } elseif ( $badhookmsg !== null ) {
221  // Exception was thrown from Hooks::hookErrorHandler.
222  throw new MWException(
223  'Detected bug in an extension! ' .
224  "Hook $func has invalid call signature; " . $badhookmsg
225  );
226  } elseif ( $retval === false ) {
227  wfProfileOut( 'hook: ' . $event );
228  // False was returned. Stop processing, but no error.
229  return false;
230  }
231  }
232 
233  wfProfileOut( 'hook: ' . $event );
234  return true;
235  }
236 
250  public static function hookErrorHandler( $errno, $errstr ) {
251  if ( strpos( $errstr, 'expected to be a reference, value given' ) !== false ) {
252  throw new MWHookException( $errstr, $errno );
253  }
254  return false;
255  }
256 }
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
Hooks\getHandlers
static getHandlers( $name)
Returns an array of all the event functions attached to a hook This combines functions registered via...
Definition: Hooks.php:103
wfProfileIn
wfProfileIn( $functionname)
Begin profiling of a function.
Definition: Profiler.php:33
Hooks\clear
static clear( $name)
Clears hooks registered via Hooks::register().
Definition: Hooks.php:72
$wgHooks
$wgHooks['ArticleShow'][]
Definition: hooks.txt:110
MWHookException
Definition: Hooks.php:30
MWException
MediaWiki exception.
Definition: MWException.php:26
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1127
wfProfileOut
wfProfileOut( $functionname='missing')
Stop profiling of a function.
Definition: Profiler.php:46
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
Hooks\run
static run( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:136
Hooks\isRegistered
static isRegistered( $name)
Returns true if a hook has a function registered to it.
Definition: Hooks.php:89
$args
if( $line===false) $args
Definition: cdb.php:62
FatalError
Exception class which takes an HTML error message, and does not produce a backtrace.
Definition: FatalError.php:28
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
$e
if( $useReadline) $e
Definition: eval.php:66
$retval
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account incomplete not yet checked for validity & $retval
Definition: hooks.txt:237
Hooks\hookErrorHandler
static hookErrorHandler( $errno, $errstr)
Handle PHP errors issued inside a hook.
Definition: Hooks.php:250
Hooks
Hooks class.
Definition: Hooks.php:39
Hooks\$handlers
static $handlers
Array of events mapped to an array of callbacks to be run when that event is triggered.
Definition: Hooks.php:45