Skip to content
Snippets Groups Projects
Unverified Commit 5db48676 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3497061 by phenaproxima, alexpott: Allow recipe input values in array keys

parent 0348fc51
No related branches found
No related tags found
No related merge requests found
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
namespace Drupal\Core\Recipe; namespace Drupal\Core\Recipe;
use Drupal\Core\Config\Action\ConfigActionException;
use Drupal\Core\Config\ConfigManagerInterface;
use Drupal\Core\Config\FileStorage; use Drupal\Core\Config\FileStorage;
use Drupal\Core\Config\InstallStorage; use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\StorageInterface; use Drupal\Core\Config\StorageInterface;
...@@ -93,11 +95,14 @@ protected static function processInstall(InstallConfigurator $install, StorageIn ...@@ -93,11 +95,14 @@ protected static function processInstall(InstallConfigurator $install, StorageIn
* The recipe being applied. * The recipe being applied.
*/ */
protected static function processConfiguration(Recipe $recipe): void { protected static function processConfiguration(Recipe $recipe): void {
/** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
$config_manager = \Drupal::service(ConfigManagerInterface::class);
$config_installer = new RecipeConfigInstaller( $config_installer = new RecipeConfigInstaller(
\Drupal::service('config.factory'), \Drupal::service('config.factory'),
\Drupal::service('config.storage'), \Drupal::service('config.storage'),
\Drupal::service('config.typed'), \Drupal::service('config.typed'),
\Drupal::service('config.manager'), $config_manager,
\Drupal::service('event_dispatcher'), \Drupal::service('event_dispatcher'),
NULL, NULL,
\Drupal::service('extension.path.resolver')); \Drupal::service('extension.path.resolver'));
...@@ -118,6 +123,13 @@ protected static function processConfiguration(Recipe $recipe): void { ...@@ -118,6 +123,13 @@ protected static function processConfiguration(Recipe $recipe): void {
/** @var \Drupal\Core\Config\Action\ConfigActionManager $config_action_manager */ /** @var \Drupal\Core\Config\Action\ConfigActionManager $config_action_manager */
$config_action_manager = \Drupal::service('plugin.manager.config_action'); $config_action_manager = \Drupal::service('plugin.manager.config_action');
foreach ($config->config['actions'] as $config_name => $actions) { foreach ($config->config['actions'] as $config_name => $actions) {
// If this config name contains an input value, it must begin with the
// config prefix of a known entity type.
if (str_contains($config_name, '${') && empty($config_manager->getEntityTypeIdByName($config_name))) {
throw new ConfigActionException("The entity type for the config name '$config_name' could not be identified.");
}
$config_name = str_replace($keys, $replace, $config_name);
foreach ($actions as $action_id => $data) { foreach ($actions as $action_id => $data) {
$config_action_manager->applyAction($action_id, $config_name, static::replaceInputValues($data, $replace)); $config_action_manager->applyAction($action_id, $config_name, static::replaceInputValues($data, $replace));
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
use Drupal\Component\Uuid\UuidInterface; use Drupal\Component\Uuid\UuidInterface;
use Drupal\contact\Entity\ContactForm; use Drupal\contact\Entity\ContactForm;
use Drupal\Core\Config\Action\ConfigActionException;
use Drupal\Core\Recipe\ConsoleInputCollector; use Drupal\Core\Recipe\ConsoleInputCollector;
use Drupal\Core\Recipe\InputCollectorInterface; use Drupal\Core\Recipe\InputCollectorInterface;
use Drupal\Core\Recipe\Recipe; use Drupal\Core\Recipe\Recipe;
...@@ -14,6 +15,7 @@ ...@@ -14,6 +15,7 @@
use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\FunctionalTests\Core\Recipe\RecipeTestTrait; use Drupal\FunctionalTests\Core\Recipe\RecipeTestTrait;
use Drupal\KernelTests\KernelTestBase; use Drupal\KernelTests\KernelTestBase;
use Drupal\node\Entity\NodeType;
use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Style\StyleInterface; use Symfony\Component\Console\Style\StyleInterface;
use Symfony\Component\Validator\Exception\ValidationFailedException; use Symfony\Component\Validator\Exception\ValidationFailedException;
...@@ -229,4 +231,45 @@ public function testLiterals(): void { ...@@ -229,4 +231,45 @@ public function testLiterals(): void {
$this->assertSame('int is 1234, bool is and float is 3.141', $config->get('slogan')); $this->assertSame('int is 1234, bool is and float is 3.141', $config->get('slogan'));
} }
/**
* Tests using input values in entity IDs for config actions.
*/
public function testInputInConfigEntityIds(): void {
$this->assertFalse(\Drupal::moduleHandler()->moduleExists('node'));
$collector = new class () implements InputCollectorInterface {
/**
* {@inheritdoc}
*/
public function collectValue(string $name, DataDefinitionInterface $definition, mixed $default_value): mixed {
return $default_value;
}
};
$recipe = Recipe::createFromDirectory('core/tests/fixtures/recipes/input_test');
$recipe->input->collectAll($collector);
RecipeRunner::processRecipe($recipe);
$this->assertInstanceOf(NodeType::class, NodeType::load('test'));
// Using an input placeholder in a non-identifying part of the config entity
// ID should cause an exception.
$recipe = $this->createRecipe([
'name' => 'Invalid use of an input in config entity ID',
'config' => [
'actions' => [
'node.${anything}.test' => [
'createIfNotExists' => [
'id' => 'test',
],
],
],
],
]);
$recipe->input->collectAll($collector);
$this->expectException(ConfigActionException::class);
$this->expectExceptionMessage("The entity type for the config name 'node.\${anything}.test' could not be identified.");
RecipeRunner::processRecipe($recipe);
}
} }
...@@ -3,6 +3,8 @@ recipes: ...@@ -3,6 +3,8 @@ recipes:
# Depend on another recipe in order to prove that we can collect input # Depend on another recipe in order to prove that we can collect input
# from recipes that depend on other recipes. # from recipes that depend on other recipes.
- no_extensions - no_extensions
install:
- node
input: input:
owner: owner:
data_type: string data_type: string
...@@ -27,8 +29,17 @@ input: ...@@ -27,8 +29,17 @@ input:
default: default:
source: value source: value
value: false value: false
node_type:
data_type: string
description: 'The ID of a node type to create'
default:
source: value
value: 'test'
config: config:
actions: actions:
node.type.${node_type}:
createIfNotExists:
name: Test Content Type
system.site: system.site:
simpleConfigUpdate: simpleConfigUpdate:
name: "${owner}'s Turf" name: "${owner}'s Turf"
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment