From 2fb90e7711bee6d36c0c267757d64d409661e696 Mon Sep 17 00:00:00 2001 From: Joe Gilliland-Lloyd <6943710+joegl@users.noreply.github.com> Date: Tue, 17 Sep 2024 14:50:16 -0500 Subject: [PATCH] Apply patch to load modules when middleware or cache invokes hooks (#1624) * Apply patch to load modules when middleware or cache invokes hooks. --- composer.json | 1 + patches/core-mr-6976.patch | 95 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 patches/core-mr-6976.patch diff --git a/composer.json b/composer.json index 2b1bb2762..da577c7d6 100644 --- a/composer.json +++ b/composer.json @@ -239,6 +239,7 @@ "https://www.drupal.org/project/drupal/issues/2981837": "https://www.drupal.org/files/issues/2019-05-22/findMigrationDependencies-null-process-value-2981837-5.patch", "https://www.drupal.org/project/drupal/issues/1349080": "https://git.drupalcode.org/project/drupal/-/commit/c271adbb22f28a66ff4321b2fb7f86f20fe0c838.patch", "https://www.drupal.org/project/drupal/issues/3306916": "https://www.drupal.org/files/issues/2023-12-19/3306916-18.patch", + "https://www.drupal.org/project/drupal/issues/3207813: ModuleHandler skips all hook implementations when invoked before the module files have been loaded": "patches/core-mr-6976.patch", "views form null fix": "patches/core-views.patch", "CKEditor 5 headings plugin paragraph label change": "patches/ckeditor5-paragraph-rename.patch", "Allow hs group blocks in layout_builder": "patches/layout_builder-allow-hs-blocks.patch", diff --git a/patches/core-mr-6976.patch b/patches/core-mr-6976.patch new file mode 100644 index 000000000..44835eaab --- /dev/null +++ b/patches/core-mr-6976.patch @@ -0,0 +1,95 @@ +From d46e4fd798c45bdebd311592f60a01596d154339 Mon Sep 17 00:00:00 2001 +From: solideogloria <39064-solideogloria@users.noreply.drupalcode.org> +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 +