wiki.techinc.nl/includes/HookContainer/FauxHookHandlerArray.php
daniel db729e46f6 Treat $wgHooks as a regular setting
$wgHooks should be treated like a regular setting, which cannot be
manipulated after bootstrapping is complete. This will allow us to
greatly simplify the logic in HookContainer.

Replacing $wgHooks with a fake array after bootstrapping allows us to
detect any remaining live access to $wgHooks without breaking
functionality.

The plan is to have the fake array emit deprecation warnings in the 1.40
release, and make it throw exceptions in later releases.
See Iddcb760cf8961316d6527e81b9aa968657d8354c for the deprecation
warnings.

Bug: T331602
Change-Id: I0ebba9a29f81b0d86ad8fd84d478fb244f9e9c15
2023-03-09 10:20:44 +01:00

89 lines
1.8 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 ) {
$this->handlers = $this->hookContainer->getLegacyHandlers( $this->name );
}
return $this->handlers[$offset] ?? null;
}
#[\ReturnTypeWillChange]
public function getIterator() {
if ( $this->handlers === null ) {
$this->handlers = $this->hookContainer->getLegacyHandlers( $this->name );
}
return new \ArrayIterator( $this->handlers );
}
}