-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Apply patch to load modules when middleware or cache invokes hooks (#…
…1624) * Apply patch to load modules when middleware or cache invokes hooks.
- Loading branch information
Showing
2 changed files
with
96 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
From d46e4fd798c45bdebd311592f60a01596d154339 Mon Sep 17 00:00:00 2001 | ||
From: solideogloria <[email protected]> | ||
Date: Fri, 8 Mar 2024 09:11:09 -0600 | ||
Subject: [PATCH] Add changes from patch 27. | ||
|
||
--- | ||
.../Drupal/Core/Extension/ModuleHandler.php | 17 +++++++++++++ | ||
.../Core/Extension/ModuleHandlerTest.php | 24 ++++++++++++++++++- | ||
2 files changed, 40 insertions(+), 1 deletion(-) | ||
|
||
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php | ||
index 61e2f638fe50..fceca545870c 100644 | ||
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php | ||
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php | ||
@@ -629,6 +629,12 @@ protected function getImplementationInfo($hook) { | ||
protected function buildImplementationInfo($hook) { | ||
$implementations = []; | ||
$hook_info = $this->getHookInfo(); | ||
+ | ||
+ // In case it's an early stage and the hook info was loaded from cache, the | ||
+ // module files are not yet loaded at this point and discovery below | ||
+ // produces an empty list. | ||
+ $this->loadAll(); | ||
+ | ||
foreach ($this->moduleList as $module => $extension) { | ||
$include_file = isset($hook_info[$hook]['group']) && $this->loadInclude($module, 'inc', $module . '.' . $hook_info[$hook]['group']); | ||
// Since $this->implementsHook() may needlessly try to load the include | ||
@@ -678,6 +684,17 @@ protected function buildImplementationInfo($hook) { | ||
* from the cache. | ||
*/ | ||
protected function verifyImplementations(&$implementations, $hook) { | ||
+ // Under certain circumstances the module files are not yet loaded. This | ||
+ // happens for example when invoking a hook inside the constructor of a | ||
+ // http_middleware service; these services are constructed very early as | ||
+ // a dependency of http_kernel service. A more concrete example is a | ||
+ // middleware service using the entity_type.manager. Most of the times | ||
+ // the entity type information is retrieved from cache (stored in the | ||
+ // discovery cache bin). When this cache however is missing, hooks | ||
+ // like hook_entity_type_build() and hook_entity_type_alter() need to be | ||
+ // invoked at this early stage. | ||
+ $this->loadAll(); | ||
+ | ||
$all_valid = TRUE; | ||
foreach ($implementations as $module => $group) { | ||
// If this hook implementation is stored in a lazy-loaded file, include | ||
diff --git a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php | ||
index 456cd998b08d..65dbfc3863ef 100644 | ||
--- a/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php | ||
+++ b/core/tests/Drupal/Tests/Core/Extension/ModuleHandlerTest.php | ||
@@ -396,6 +396,7 @@ function (callable $hook, string $module) use (&$implementors) { | ||
* Tests getImplementations. | ||
* | ||
* @covers ::invokeAllWith | ||
+ * @covers ::verifyImplementations | ||
*/ | ||
public function testCachedGetImplementationsMissingMethod() { | ||
$this->cacheBackend->expects($this->exactly(1)) | ||
@@ -422,7 +423,6 @@ public function testCachedGetImplementationsMissingMethod() { | ||
]) | ||
->onlyMethods(['buildImplementationInfo']) | ||
->getMock(); | ||
- $module_handler->load('module_handler_test'); | ||
|
||
$module_handler->expects($this->never())->method('buildImplementationInfo'); | ||
$implementors = []; | ||
@@ -538,4 +538,26 @@ public function testGetModuleDirectories() { | ||
$this->assertEquals(['node' => $this->root . '/core/modules/node'], $module_handler->getModuleDirectories()); | ||
} | ||
|
||
+ /** | ||
+ * Tests that modules are included in case of a partial cache miss. | ||
+ * | ||
+ * @covers ::hasImplementations | ||
+ * @covers ::getImplementationInfo | ||
+ * @covers ::buildImplementationInfo | ||
+ */ | ||
+ public function testMissingHookImplementationCache() { | ||
+ // Simulate missing cache entry for hook implementations, but existing one | ||
+ // for hook info. | ||
+ $this->cacheBackend | ||
+ ->expects($this->exactly(2)) | ||
+ ->method('get') | ||
+ ->willReturnMap([ | ||
+ ['hook_info', FALSE, (object) ['data' => []]], | ||
+ ['module_implements', FALSE, FALSE], | ||
+ ]); | ||
+ | ||
+ $module_handler = $this->getModuleHandler(); | ||
+ $this->assertTrue($module_handler->hasImplementations('hook', 'module_handler_test')); | ||
+ } | ||
+ | ||
} | ||
-- | ||
GitLab | ||
|