wiki.techinc.nl/includes/HookContainer/FauxHookHandlerArray.php
Lucas Werkmeister 5f2bfc44ce Simplify HookContainer (v2)
This reverts change I50c3d1c5df (commit b0317287bc), thus reinstating
change I7d690a1172 (commit d139eb07fe). The only change from the
original is in getHookMethodName(), additionally replacing '-' with '_'
(not just ':' and '\'). The original commit message follows:

This converts all hook handlers to the same internal representation.
This is done lazily, when the hook is run for the first time.

The logic for temporarily disabling handlers by calling scopedRegister()
with the $replace parameter set has been greatly simplified.

There are some minor changes to the class's interface and behavior,
none of which should be breaking changes:
* run() will emit deprecation warnings if and only if it was called
  with the deprecationVersion option set, for all kinds of handlers.
  The idea is that deprecated hooks should emit a warning either from
  run(), or from emitDeprecationWarnings(). The latter happens if the
  hook is listed in DeprecatedHooks.
* register() now also accepts hook handlers declared in the way that
  extensions register hooks.
* Attempts to call register() with an invalid hook definition now
  result in an invalidArgumentException.
* Attempts to call register() for a deprecated hook will consistently
  result in a deprecation warning.
* The internal getRegisteredHooks() method has been removed in favor
  of the identical getHookNames() method.
* The internal getLegacyHandlers method has been removed in favor
  of getHandlerDescriptions() and getHandlerCallbacks().
* The call order changed so that dynamically registered handlers
  are called last, instead of getting called before handler objects
  from extensions.

Bug: T338213
Change-Id: I6efb09e314ad2b124a33a757fdda2a07ae0d8f7c
2023-06-06 12:06:23 +02:00

93 lines
2.1 KiB
PHP

<?php
namespace MediaWiki\HookContainer;
use InvalidArgumentException;
use LogicException;
use OutOfBoundsException;
/**
* @internal
*/
class FauxHookHandlerArray implements \ArrayAccess, \IteratorAggregate {
private HookContainer $hookContainer;
private string $name;
private ?array $handlers = null;
/**
* @param HookContainer $hookContainer
* @param string $name
*/
public function __construct( HookContainer $hookContainer, string $name ) {
$this->hookContainer = $hookContainer;
$this->name = $name;
}
/**
* @inheritDoc
*/
#[\ReturnTypeWillChange]
public function offsetExists( $offset ) {
return $this->getHandler( $offset ) !== null;
}
/**
* @inheritDoc
*/
#[\ReturnTypeWillChange]
public function offsetGet( $offset ) {
$handler = $this->getHandler( $offset );
if ( !$handler ) {
throw new OutOfBoundsException( "No such index in the handler list: $offset" );
}
return $handler;
}
/**
* @inheritDoc
*/
#[\ReturnTypeWillChange]
public function offsetSet( $offset, $value ) {
if ( $offset !== null ) {
throw new InvalidArgumentException( '$offset must be null, this array is append only' );
}
$this->hookContainer->register( $this->name, $value );
$this->handlers = null;
}
/**
* @inheritDoc
* @return never
*/
#[\ReturnTypeWillChange]
public function offsetUnset( $offset ) {
throw new LogicException( 'unset is not supported for hook handler arrays' );
}
private function getHandler( $offset ) {
if ( $this->handlers === null ) {
// NOTE: getHandlerCallbacks() only exists to support this.
// It should be deleted when we no longer need it here.
$this->handlers = $this->hookContainer->getHandlerCallbacks( $this->name );
}
return $this->handlers[$offset] ?? null;
}
#[\ReturnTypeWillChange]
public function getIterator() {
if ( $this->handlers === null ) {
// NOTE: getHandlerCallbacks() only exists to support this.
// It should be deleted when we no longer need it here.
$this->handlers = $this->hookContainer->getHandlerCallbacks( $this->name );
}
return new \ArrayIterator( $this->handlers );
}
}