Loading core/lib/Drupal/Core/Extension/ModuleHandler.php +11 −2 Original line number Diff line number Diff line Loading @@ -620,8 +620,17 @@ protected function getHookOrderingRules(string $hook): array { * hook_module_implements_alter(). */ protected function reOrderModulesForAlter(array $modules, string $hook): array { // Order by module order first. $modules = array_intersect(array_keys($this->moduleList), $modules); // Order by module order first, this preserves expected order for alter // hooks implemented on behalf of other modules. The module that hooks // implementations in kernel test classes are grouped by is 'core'. Since // 'core' is not actually a module, add 'core' as a key to the module list, // so core implementations are not filtered out. 'Core' is added last to // match how kernel test hooks are added last by KernelTestCompilerPass. // @todo Determine whether 'core' should still be ordered last by default // when any service, including in the Drupal\Core namespace, can have // hook implementations. // @see https://www.drupal.org/i/3481903. $modules = array_intersect(array_keys($this->moduleList + ['core' => '']), $modules); // Alter expects the module list to be in the keys. $implementations = array_fill_keys($modules, FALSE); // Let modules adjust the order solely based on the primary hook. This Loading core/tests/Drupal/KernelTests/Core/Hook/KernelTestHooksTest.php 0 → 100644 +62 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\KernelTests\Core\Hook; use Drupal\Core\Hook\Attribute\Hook; use Drupal\KernelTests\KernelTestBase; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; /** * Tests that hook implementations in Kernel test classes are executed. */ #[Group('Hook')] #[RunTestsInSeparateProcesses] class KernelTestHooksTest extends KernelTestBase { /** * Invoke hooks and alter hooks and confirm implementations are executed. */ public function testHookMethodExecution(): void { // Invoke a hook and confirm hookTestHook() executed. $values = \Drupal::moduleHandler()->invokeAll('test_hook'); $this->assertSame([static::class . '::hookTestHook'], $values); // Invoke alter hooks, with multiple types of related hooks and confirm that // both hookTestHookAlter() and hookTestVariantHookAlter() executed. $alterHooks = ['test_hook', 'test_variant_hook']; \Drupal::moduleHandler()->alter($alterHooks, $values); $this->assertSame([ static::class . '::hookTestHook', static::class . '::hookTestHookAlter', static::class . '::hookTestVariantHookAlter', ], $values); } /** * Implements hook_test_hook(). */ #[Hook('test_hook')] public function hookTestHook(): string { return __METHOD__; } /** * Implements hook_test_hook_alter(). */ #[Hook('test_hook_alter')] public function hookTestHookAlter(array &$values): void { $values[] = __METHOD__; } /** * Implements hook_test_variant_hook_alter(). */ #[Hook('test_variant_hook_alter')] public function hookTestVariantHookAlter(array &$values): void { $values[] = __METHOD__; } } Loading
core/lib/Drupal/Core/Extension/ModuleHandler.php +11 −2 Original line number Diff line number Diff line Loading @@ -620,8 +620,17 @@ protected function getHookOrderingRules(string $hook): array { * hook_module_implements_alter(). */ protected function reOrderModulesForAlter(array $modules, string $hook): array { // Order by module order first. $modules = array_intersect(array_keys($this->moduleList), $modules); // Order by module order first, this preserves expected order for alter // hooks implemented on behalf of other modules. The module that hooks // implementations in kernel test classes are grouped by is 'core'. Since // 'core' is not actually a module, add 'core' as a key to the module list, // so core implementations are not filtered out. 'Core' is added last to // match how kernel test hooks are added last by KernelTestCompilerPass. // @todo Determine whether 'core' should still be ordered last by default // when any service, including in the Drupal\Core namespace, can have // hook implementations. // @see https://www.drupal.org/i/3481903. $modules = array_intersect(array_keys($this->moduleList + ['core' => '']), $modules); // Alter expects the module list to be in the keys. $implementations = array_fill_keys($modules, FALSE); // Let modules adjust the order solely based on the primary hook. This Loading
core/tests/Drupal/KernelTests/Core/Hook/KernelTestHooksTest.php 0 → 100644 +62 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\KernelTests\Core\Hook; use Drupal\Core\Hook\Attribute\Hook; use Drupal\KernelTests\KernelTestBase; use PHPUnit\Framework\Attributes\Group; use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses; /** * Tests that hook implementations in Kernel test classes are executed. */ #[Group('Hook')] #[RunTestsInSeparateProcesses] class KernelTestHooksTest extends KernelTestBase { /** * Invoke hooks and alter hooks and confirm implementations are executed. */ public function testHookMethodExecution(): void { // Invoke a hook and confirm hookTestHook() executed. $values = \Drupal::moduleHandler()->invokeAll('test_hook'); $this->assertSame([static::class . '::hookTestHook'], $values); // Invoke alter hooks, with multiple types of related hooks and confirm that // both hookTestHookAlter() and hookTestVariantHookAlter() executed. $alterHooks = ['test_hook', 'test_variant_hook']; \Drupal::moduleHandler()->alter($alterHooks, $values); $this->assertSame([ static::class . '::hookTestHook', static::class . '::hookTestHookAlter', static::class . '::hookTestVariantHookAlter', ], $values); } /** * Implements hook_test_hook(). */ #[Hook('test_hook')] public function hookTestHook(): string { return __METHOD__; } /** * Implements hook_test_hook_alter(). */ #[Hook('test_hook_alter')] public function hookTestHookAlter(array &$values): void { $values[] = __METHOD__; } /** * Implements hook_test_variant_hook_alter(). */ #[Hook('test_variant_hook_alter')] public function hookTestVariantHookAlter(array &$values): void { $values[] = __METHOD__; } }