Unverified Commit d5b74381 authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3539822 by mxr576, phenaproxima, alexpott: Recipe installer fails when...

Issue #3539822 by mxr576, phenaproxima, alexpott: Recipe installer fails when programmatically providing input to dependent recipes

(cherry picked from commit 149ab99e)
parent acd99ccc
Loading
Loading
Loading
Loading
Loading
+7 −10
Original line number Diff line number Diff line
@@ -25,11 +25,11 @@ final class InputConfigurator {
  private array $data = [];

  /**
   * The collected input values.
   * The collected input values, or NULL if none have been collected yet.
   *
   * @var mixed[]
   * @var mixed[]|null
   */
  private array $values = [];
  private ?array $values = NULL;

  /**
   * @param array<string, array<string, mixed>> $definitions
@@ -96,7 +96,7 @@ public function getDataDefinitions(): array {
   *   The collected input values, keyed by name.
   */
  public function getValues(): array {
    return $this->values;
    return $this->values ?? [];
  }

  /**
@@ -131,23 +131,20 @@ public function describeAll(): array {
   * @throws \Symfony\Component\Validator\Exception\ValidationFailedException
   *   Thrown if any of the collected values violate their validation
   *   constraints.
   * @throws \LogicException
   *   Thrown if input values have already been collected for this recipe.
   */
  public function collectAll(InputCollectorInterface $collector, array &$processed = []): void {
    // Don't bother collecting values for a recipe we've already seen.
    if (in_array($this->prefix, $processed, TRUE)) {
    if (in_array($this->prefix, $processed, TRUE) || is_array($this->values)) {
      return;
    }
    if ($this->values) {
      throw new \LogicException('Input values cannot be changed once they have been set.');
    }

    // First, collect values for the recipe's dependencies.
    /** @var \Drupal\Core\Recipe\Recipe $dependency */
    foreach ($this->dependencies->recipes as $dependency) {
      $dependency->input->collectAll($collector, $processed);
    }

    $this->values = [];
    foreach ($this->data as $key => $data) {
      $definition = $data->getDataDefinition();

+3 −2
Original line number Diff line number Diff line
@@ -29,8 +29,9 @@ public function testRecipeInputViaForm(): void {
    $this->drupalGet('/form-test/recipe-input');

    $assert_session = $this->assertSession();
    // There should only be two nested input elements on the page: the two
    // defined by the input_test recipe.
    // There should only be two nested input elements on the page: the one
    // defined by the input_test recipe and the other defined by its dependency,
    // the create_node_type recipe.
    $assert_session->elementsCount('css', 'input[name*="["]', 2);
    // The default value and description should be visible.
    $assert_session->fieldValueEquals('input_test[owner]', 'Dries Buytaert');
+15 −0
Original line number Diff line number Diff line
name: Create node type
install:
  - node
input:
  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
+2 −13
Original line number Diff line number Diff line
name: Input Test
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
  # from dependent recipes as well.
  - create_node_type
input:
  owner:
    data_type: string
@@ -29,17 +27,8 @@ 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"