You are here

private function ComponentSectionForm::getCompomentElement in Module Builder 8.3

1 call to ComponentSectionForm::getCompomentElement()
ComponentSectionForm::XelementCompound in src/Form/ComponentSectionForm.php
Set form element properties specific to compound component properties.

File

src/Form/ComponentSectionForm.php, line 1146

Class

ComponentSectionForm
Generic form for entering a section of data for a component.

Namespace

Drupal\module_builder\Form

Code

private function getCompomentElement($form_state, $property_address, $value_address, $form_value_address) {
  $component_element = [];
  $properties = NestedArray::getValue(static::$componentDataInfo, $property_address);

  // TODO: should this be carried through? Check whether preparing a compound
  // property can set values in the array.
  $component_data = [];
  foreach ($properties as $property_name => &$property_info) {

    // Prepare the single property: get options, default value, etc.
    $this->codeBuilderTaskHandlerGenerate
      ->prepareComponentDataProperty($property_name, $property_info, $component_data);

    // Skip the properties that we're not showing on this form section.
    if (!empty($property_info['hidden'])) {
      continue;
    }

    // Add the name of the current property to the address arrays.
    $property_component_address = $property_address;
    $property_component_address[] = $property_name;
    $property_value_address = $value_address;
    $property_value_address[] = $property_name;
    $property_form_value_address = $form_value_address;
    $property_form_value_address[] = $property_name;

    // Create a basic form element for the property.
    $property_element = [
      '#title' => $property_info['label'],
      '#required' => $property_info['required'],
      '#mb_property_address' => $property_component_address,
      '#mb_value_address' => $property_value_address,
      // Explicitly set this so we control the structure of the form
      // submission values. In particular, we don't want to have to pick data
      // out from the the structure the 'table' element would create.
      '#parents' => $property_form_value_address,
    ];
    if (isset($property_info['description'])) {
      $property_element['#description'] = $property_info['description'];
    }

    // Add description to properties that can get defaults filled in by
    // DCB in processing.
    if (!empty($property_info['process_default'])) {
      $property_element['#required'] = FALSE;
      $property_element['#description'] = (isset($property_element['#description']) ? $property_element['#description'] . ' ' : '') . t("Leave blank for a default value.");
    }

    // Determine the default value to present in the form element.
    // (Compound elements don't have a default value as they are just
    // containers, but we use the count of the array we get to determine how
    // many deltas to show.)
    $key_exists = NULL;
    $form_default_value = NestedArray::getValue($this->moduleEntityData, array_slice($property_form_value_address, 1), $key_exists);

    // If there is no value set in the module entity data, take the default
    // value that prepareComponentDataProperty() set.
    if (!$key_exists) {
      $form_default_value = $component_data[$property_name];
      if ($property_info['format'] == 'compound') {

        // Bit of a hack: for compound properties, zap the prepared default.
        // The problem is that this will cause a child element to appear in
        // the form, rather than starting with a zero delta.
        // This happens for example with the PHPUnit test component, where
        // the prepared default for the test_modules property tries to set a
        // module name derived from the test class name.
        // This will be fixed in DCB 3.3.x when we get the ability to do
        // defaults in JS.
        $form_default_value = [];
      }
    }

    // The type of the form element depends on the format of the component data
    // property.
    $format = $property_info['format'];
    $format_method = 'element' . ucfirst($format);
    if (!method_exists($this, $format_method)) {
      throw new \Exception("No method '{$format_method}' exists to handle property '{$property_name}' with format '{$format}'.");
      continue;
    }
    $handling = $this
      ->{$format_method}($property_element, $form_state, $property_info, $form_default_value);
    $property_form_value_address_key = implode(':', $property_form_value_address);
    $form_state
      ->set([
      'element_handling',
      $property_form_value_address_key,
    ], $handling);
    $component_element[$property_name] = $property_element;
  }
  return $component_element;
}