diff --git a/includes/HookContainer/HookRunner.php b/includes/HookContainer/HookRunner.php index 45d16168ecf..5b8e0fda0e4 100644 --- a/includes/HookContainer/HookRunner.php +++ b/includes/HookContainer/HookRunner.php @@ -35,6 +35,7 @@ class HookRunner implements \MediaWiki\Auth\Hook\SecuritySensitiveOperationStatusHook, \MediaWiki\Auth\Hook\UserLoggedInHook, \MediaWiki\Block\Hook\AbortAutoblockHook, + \MediaWiki\Block\Hook\GetAllBlockActionsHook, \MediaWiki\Block\Hook\GetUserBlockHook, \MediaWiki\Block\Hook\PerformRetroactiveAutoblockHook, \MediaWiki\Cache\Hook\BacklinkCacheGetConditionsHook, @@ -1826,6 +1827,14 @@ class HookRunner implements ); } + public function onGetAllBlockActions( &$actions ) { + return $this->container->run( + 'GetAllBlockActions', + [ &$actions ], + [ 'abortable' => false ] + ); + } + public function onGetAutoPromoteGroups( $user, &$promote ) { return $this->container->run( 'GetAutoPromoteGroups', diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 6536eeaf467..ba4409f97af 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -214,7 +214,7 @@ return [ }, 'BlockActionInfo' => static function ( MediaWikiServices $services ) : BlockActionInfo { - return new BlockActionInfo(); + return new BlockActionInfo( $services->getHookContainer() ); }, 'BlockErrorFormatter' => static function ( MediaWikiServices $services ) : BlockErrorFormatter { diff --git a/includes/block/BlockActionInfo.php b/includes/block/BlockActionInfo.php index 966f3456659..db27c3e227d 100644 --- a/includes/block/BlockActionInfo.php +++ b/includes/block/BlockActionInfo.php @@ -20,6 +20,9 @@ namespace MediaWiki\Block; +use MediaWiki\HookContainer\HookContainer; +use MediaWiki\HookContainer\HookRunner; + /** * Defines the actions that can be blocked by a partial block. They are * always blocked by a sitewide block. @@ -34,6 +37,8 @@ namespace MediaWiki\Block; * @since 1.37 */ class BlockActionInfo { + /** @var HookRunner */ + private $hookRunner; /** @var int */ private const ACTION_UPLOAD = 1; @@ -55,11 +60,29 @@ class BlockActionInfo { 'upload' => self::ACTION_UPLOAD, ]; + /** + * @param HookContainer $hookContainer + */ + public function __construct( HookContainer $hookContainer ) { + $this->hookRunner = new HookRunner( $hookContainer ); + } + + /** + * Cache the array of actions + * @var int[]|null + */ + private $allBlockActions = null; + /** * @return int[] */ public function getAllBlockActions() : array { - return self::CORE_BLOCK_ACTIONS; + // Don't run the hook multiple times in the same request + if ( !$this->allBlockActions ) { + $this->allBlockActions = self::CORE_BLOCK_ACTIONS; + $this->hookRunner->onGetAllBlockActions( $this->allBlockActions ); + } + return $this->allBlockActions; } } diff --git a/includes/block/Hook/GetAllBlockActionsHook.php b/includes/block/Hook/GetAllBlockActionsHook.php new file mode 100644 index 00000000000..df115599c6e --- /dev/null +++ b/includes/block/Hook/GetAllBlockActionsHook.php @@ -0,0 +1,22 @@ +hookContainer = $this->createHookContainer(); + } + + /** + * @covers ::getAllBlockActions + */ + public function testAddBlockAction() { + $this->hookContainer->register( + 'GetAllBlockActions', + static function ( array &$actions ) { + $actions[ 'test' ] = 100; + } + ); + $blockActionInfo = new BlockActionInfo( $this->hookContainer ); + $blockActions = $blockActionInfo->getAllBlockActions(); + + // Confirm new action is added + $this->assertContains( 100, $blockActions ); + } + +}