From 81f055eb1cabb12c36f99c96675b1b9991d2d168 Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Tue, 8 Oct 2024 14:50:21 +0100 Subject: [PATCH] Issue #3477329 by phenaproxima, thejimbirch, b_sharpe: Recipe validation should always treat required modules as installed --- core/lib/Drupal/Core/Recipe/Recipe.php | 11 ++++++++++- .../KernelTests/Core/Recipe/RecipeTest.php | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/core/lib/Drupal/Core/Recipe/Recipe.php b/core/lib/Drupal/Core/Recipe/Recipe.php index 89e7b0ed742d..c9f5f055932c 100644 --- a/core/lib/Drupal/Core/Recipe/Recipe.php +++ b/core/lib/Drupal/Core/Recipe/Recipe.php @@ -383,14 +383,23 @@ private static function validateConfigActions(mixed $value, ExecutionContextInte $configurator = new RecipeConfigurator($recipe_being_validated['recipes'] ?? [], $include_path); + /** @var \Drupal\Core\Extension\ModuleExtensionList $module_list */ + $module_list = \Drupal::service('extension.list.module'); // The config provider must either be an already-installed module or theme, // or an extension being installed by this recipe or a recipe it depends on. $all_extensions = [ - ...array_keys(\Drupal::service('extension.list.module')->getAllInstalledInfo()), + ...array_keys($module_list->getAllInstalledInfo()), ...array_keys(\Drupal::service('extension.list.theme')->getAllInstalledInfo()), ...$recipe_being_validated['install'] ?? [], ...$configurator->listAllExtensions(), ]; + // Explicitly treat required modules as installed, even if Drupal isn't + // installed yet, because we know they WILL be installed. + foreach ($module_list->getAllAvailableInfo() as $name => $info) { + if (!empty($info['required'])) { + $all_extensions[] = $name; + } + } if (!in_array($config_provider, $all_extensions, TRUE)) { $context->addViolation('Config actions cannot be applied to %config_name because the %config_provider extension is not installed, and is not installed by this recipe or any of the recipes it depends on.', [ diff --git a/core/tests/Drupal/KernelTests/Core/Recipe/RecipeTest.php b/core/tests/Drupal/KernelTests/Core/Recipe/RecipeTest.php index 9db4abe5709c..b63861276ff3 100644 --- a/core/tests/Drupal/KernelTests/Core/Recipe/RecipeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Recipe/RecipeTest.php @@ -8,6 +8,7 @@ use Drupal\Core\Recipe\RecipeFileException; use Drupal\Core\Recipe\RecipePreExistingConfigException; use Drupal\Core\Recipe\RecipeRunner; +use Drupal\FunctionalTests\Core\Recipe\RecipeTestTrait; use Drupal\KernelTests\KernelTestBase; /** @@ -16,6 +17,8 @@ */ class RecipeTest extends KernelTestBase { + use RecipeTestTrait; + /** * {@inheritdoc} */ @@ -80,4 +83,19 @@ public function testExampleRecipe(): void { $this->assertSame($this->config('text.settings')->get('default_summary_length'), 700); } + public function testImplicitlyRequiredModule(): void { + $this->disableModules(['user']); + $recipe = $this->createRecipe([ + 'name' => 'Actions on config from required module', + 'config' => [ + 'actions' => [ + 'user.role.authenticated' => [ + 'grantPermission' => 'access administration pages', + ], + ], + ], + ]); + $this->assertIsObject($recipe); + } + } -- GitLab