Issue #3486462 by nicxvan: Support #Hook for several hooks called by ModuleInstaller

(cherry picked from commit 2c9e1fa9e2)
merge-requests/10171/head
Lee Rowlands 2024-11-12 09:54:00 +10:00
parent ac590ac6d5
commit 5330cfd881
No known key found for this signature in database
GPG Key ID: 2B829A3DF9204DC4
9 changed files with 94 additions and 26 deletions

View File

@ -1658,12 +1658,7 @@
* - hook_module_implements_alter()
*
* Install hooks:
* - hook_cache_flush()
* - hook_install()
* - hook_module_preinstall()
* - hook_module_preuninstall()
* - hook_modules_installed()
* - hook_modules_uninstalled()
* - hook_post_update_NAME()
* - hook_schema()
* - hook_uninstall()
@ -2255,8 +2250,6 @@ function hook_layout_alter(&$definitions) {
/**
* Flush all persistent and static caches.
*
* Only procedural implementations are supported for this hook.
*
* This hook asks your module to clear all of its static caches,
* in order to ensure a clean environment for subsequently
* invoked data rebuilds.

View File

@ -725,7 +725,7 @@ class ModuleInstaller implements ModuleInstallerInterface {
protected function invokeAll($hook, $args = []): void {
$this->moduleHandler->loadAll();
foreach ($this->moduleHandler->getModuleList() as $module => $extension) {
$this->invoke($module, $hook, $args);
$this->moduleHandler->invoke($module, $hook, $args);
}
}

View File

@ -163,8 +163,6 @@ function hook_system_info_alter(array &$info, \Drupal\Core\Extension\Extension $
/**
* Perform necessary actions before a module is installed.
*
* Only procedural implementations are supported for this hook.
*
* @param string $module
* The name of the module about to be installed.
* @param bool $is_syncing
@ -182,8 +180,6 @@ function hook_module_preinstall($module, bool $is_syncing) {
/**
* Perform necessary actions after modules are installed.
*
* Only procedural implementations are supported for this hook.
*
* This function differs from hook_install() in that it gives all other modules
* a chance to perform actions when a module is installed, whereas
* hook_install() is only called on the module actually being installed. See
@ -267,8 +263,6 @@ function hook_install($is_syncing): void {
/**
* Perform necessary actions before a module is uninstalled.
*
* Only procedural implementations are supported for this hook.
*
* @param string $module
* The name of the module about to be uninstalled.
* @param bool $is_syncing
@ -285,8 +279,6 @@ function hook_module_preuninstall($module, bool $is_syncing) {
/**
* Perform necessary actions after modules are uninstalled.
*
* Only procedural implementations are supported for this hook.
*
* This function differs from hook_uninstall() in that it gives all other
* modules a chance to perform actions when a module is uninstalled, whereas
* hook_uninstall() is only called on the module actually being uninstalled.

View File

@ -66,12 +66,7 @@ namespace Drupal\Core\Hook\Attribute;
* - hook_module_implements_alter()
*
* Install hooks:
* - hook_cache_flush()
* - hook_install()
* - hook_module_preinstall()
* - hook_module_preuninstall()
* - hook_modules_installed()
* - hook_modules_uninstalled()
* - hook_post_update_NAME()
* - hook_schema()
* - hook_uninstall()

View File

@ -334,14 +334,9 @@ class HookCollectorPass implements CompilerPassInterface {
*/
public static function checkForProceduralOnlyHooks(Hook $hook, string $class): void {
$staticDenyHooks = [
'cache_flush',
'hook_info',
'install',
'module_implements_alter',
'module_preinstall',
'module_preuninstall',
'modules_installed',
'modules_uninstalled',
'requirements',
'schema',
'uninstall',

View File

@ -0,0 +1,5 @@
name: 'Hooks in ModuleInstaller'
type: module
description: 'Test hooks invoked when modules are installed or uninstalled.'
package: Testing
version: VERSION

View File

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace Drupal\respond_install_uninstall_hook_test\Hook;
use Drupal\Core\Hook\Attribute\Hook;
/**
* Hook implementations for respond_install_uninstall_hook_test.
*/
class OtherModuleInstalledHooks {
/**
* Implements hook_module_preinstall().
*/
#[Hook('module_preinstall')]
public function modulePreinstall(): void {
// Set a global value we can check in test code.
$GLOBALS['hook_module_preinstall'] = 'hook_module_preinstall';
}
/**
* Implements hook_modules_installed().
*/
#[Hook('modules_installed')]
public function modulesInstalled(): void {
// Set a global value we can check in test code.
$GLOBALS['hook_modules_installed'] = 'hook_modules_installed';
}
}

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Drupal\respond_install_uninstall_hook_test\Hook;
use Drupal\Core\Hook\Attribute\Hook;
/**
* Hook implementations for respond_install_uninstall_hook_test.
*/
class OtherModuleUninstalledHooks {
/**
* Implements hook_module_preuninstall().
*/
#[Hook('module_preuninstall')]
public function modulePreuninstall(): void {
// Set a global value we can check in test code.
$GLOBALS['hook_module_preuninstall'] = 'hook_module_preuninstall';
}
/**
* Implements hook_modules_uninstalled().
*/
#[Hook('modules_uninstalled')]
public function modulesUninstall(): void {
// Set a global value we can check in test code.
$GLOBALS['hook_modules_uninstalled'] = 'hook_modules_uninstalled';
}
/**
* Implements hook_cache_flush().
*/
#[Hook('cache_flush')]
public function cacheFlush(): void {
// Set a global value we can check in test code.
$GLOBALS['hook_cache_flush'] = 'hook_cache_flush';
}
}

View File

@ -91,6 +91,21 @@ class ModuleInstallerTest extends KernelTestBase {
$this->assertTrue($module_installer->install(['module_test']));
}
/**
* Ensure that hooks reacting to install or uninstall are invoked.
*/
public function testInvokingRespondentHooks(): void {
$module_installer = $this->container->get('module_installer');
$this->assertTrue($module_installer->install(['respond_install_uninstall_hook_test']));
$this->assertTrue($module_installer->install(['cache_test']));
$this->assertTrue(isset($GLOBALS['hook_module_preinstall']));
$this->assertTrue(isset($GLOBALS['hook_modules_installed']));
$module_installer->uninstall(['cache_test']);
$this->assertTrue(isset($GLOBALS['hook_module_preuninstall']));
$this->assertTrue(isset($GLOBALS['hook_modules_uninstalled']));
$this->assertTrue(isset($GLOBALS['hook_cache_flush']));
}
/**
* Tests install with a module with an invalid core version constraint.
*