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

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

(cherry picked from commit 5db48676)
parent 1f559ea8
No related branches found
No related tags found
21 merge requests!12227Issue #3181946 by jonmcl, mglaman,!12079Issue #3523476 by matthiasm11: Add empty check on operator,!12024Fix: DocBlock comment for return value of Drupal\Core\Database\Connection::transactionManager(),!11974Draft: Issue #3495165 by catch, joeyroth, berdir, texas-bronius: Better warning...,!11934Issue #3520997: DefaultLazyPluginCollection unnecessarily instantiates plugins when sorting collection,!11887Issue #3520065: The migrate Row class API is incomplete,!11636Draft: Issue #3515643 by macsim: fieldNameExists method is inconsistent,!11515Issue #3480419 by mondrake, smustgrave, catch: Method...,!11380Issue #3490698 by catch, spokje: Bump MINIMUM_STABILITY back to 'stable' when...,!11281Use Drupal Core Leadership terminology in MAINTAINERS.txt,!11239Issue #3507548: Allow workspace changes listing to show all items, without a pager,!11238Fix issue #3051797,!11213Issue #3506743 by tomislav.matokovic: Increasing the color contrast for the navigation block title against the background of the navigation sidebar to at least 4.5:1,!11147Draft: Try to avoid manually setting required cache contexts,!11108Issue #3490298 by nicxvan: Profiles can be missed in OOP hooks,!11093Drupal on MongoDB 11.1.x,!11017Issue #3502540: Add date filter for moderated content.,!11009Issue #3486972 migrate feed icon,!10999Cleaning up Taxonomy hooks and updating baseline.,!10977Issue #3501457: Fix path used in a A11y Test Admin,!10881Issue #3489329 by mfb, casey: symfony/http-foundation commit 32310ff breaks PathValidator
Pipeline #391828 canceled
Pipeline: drupal

#391829

    ......@@ -4,6 +4,8 @@
    namespace Drupal\Core\Recipe;
    use Drupal\Core\Config\Action\ConfigActionException;
    use Drupal\Core\Config\ConfigManagerInterface;
    use Drupal\Core\Config\FileStorage;
    use Drupal\Core\Config\InstallStorage;
    use Drupal\Core\Config\StorageInterface;
    ......@@ -93,11 +95,14 @@ protected static function processInstall(InstallConfigurator $install, StorageIn
    * The recipe being applied.
    */
    protected static function processConfiguration(Recipe $recipe): void {
    /** @var \Drupal\Core\Config\ConfigManagerInterface $config_manager */
    $config_manager = \Drupal::service(ConfigManagerInterface::class);
    $config_installer = new RecipeConfigInstaller(
    \Drupal::service('config.factory'),
    \Drupal::service('config.storage'),
    \Drupal::service('config.typed'),
    \Drupal::service('config.manager'),
    $config_manager,
    \Drupal::service('event_dispatcher'),
    NULL,
    \Drupal::service('extension.path.resolver'));
    ......@@ -118,6 +123,13 @@ protected static function processConfiguration(Recipe $recipe): void {
    /** @var \Drupal\Core\Config\Action\ConfigActionManager $config_action_manager */
    $config_action_manager = \Drupal::service('plugin.manager.config_action');
    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) {
    $config_action_manager->applyAction($action_id, $config_name, static::replaceInputValues($data, $replace));
    }
    ......
    ......@@ -6,6 +6,7 @@
    use Drupal\Component\Uuid\UuidInterface;
    use Drupal\contact\Entity\ContactForm;
    use Drupal\Core\Config\Action\ConfigActionException;
    use Drupal\Core\Recipe\ConsoleInputCollector;
    use Drupal\Core\Recipe\InputCollectorInterface;
    use Drupal\Core\Recipe\Recipe;
    ......@@ -14,6 +15,7 @@
    use Drupal\Core\TypedData\TypedDataInterface;
    use Drupal\FunctionalTests\Core\Recipe\RecipeTestTrait;
    use Drupal\KernelTests\KernelTestBase;
    use Drupal\node\Entity\NodeType;
    use Symfony\Component\Console\Input\InputInterface;
    use Symfony\Component\Console\Style\StyleInterface;
    use Symfony\Component\Validator\Exception\ValidationFailedException;
    ......@@ -229,4 +231,45 @@ public function testLiterals(): void {
    $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:
    # Depend on another recipe in order to prove that we can collect input
    # from recipes that depend on other recipes.
    - no_extensions
    install:
    - node
    input:
    owner:
    data_type: string
    ......@@ -27,8 +29,17 @@ input:
    default:
    source: value
    value: false
    node_type:
    data_type: string
    description: 'The ID of a node type to create'
    default:
    source: value
    value: 'test'
    config:
    actions:
    node.type.${node_type}:
    createIfNotExists:
    name: Test Content Type
    system.site:
    simpleConfigUpdate:
    name: "${owner}'s Turf"
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment