You are here

private function ModuleBuilderComponentFormBase::getCompomentElement in Module Builder 7.2

Builds the form element for a component.

This builds the root level form element, or an element for any part of the property info array that is an array of properties. This is recursed into by elementCompound().

Parameters

array $property_address: The property address for the component. This is an array that gives the location of this component's properties list in the complete property info array in static::$componentDataInfo. For the root, this will be an empty array; for a child compound property this will be an address of the form parent->properties->child->properties.

array $value_address: The value address for the form element to be created. This is similar to the property address, but will include items for compound property deltas. This ensures that buttons and item counts in form storage are unique for compound elements which are themselves children of multi-valued compound elements.

$form_value_address: The form values address for the component. This is used to set the #parents property on the form element we create, so that the form values structure matches the original data structure. This is different again from the other two addresses, as it does not include a level for the 'properties' array, but does include deltas.

Return value

array The form array for the component's element.

2 calls to ModuleBuilderComponentFormBase::getCompomentElement()
ModuleBuilderComponentFormBase::componentPropertiesForm in includes/module_builder.form.inc
Add form elements for the specified component properties.
ModuleBuilderComponentFormBase::elementCompound in includes/module_builder.form.inc
Set form element properties specific to compound component properties.

File

includes/module_builder.form.inc, line 193

Class

ModuleBuilderComponentFormBase
Backport of ComponentFormBase from 8.x-3.x version.

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;

    // D7: there's no existing data, as modules are not stored.
    // $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} for {$property_name}.");
      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;
}