You are here

public static function WebformElementComposite::validateWebformElementComposite in Webform 6.x

Same name and namespace in other branches
  1. 8.5 src/Element/WebformElementComposite.php \Drupal\webform\Element\WebformElementComposite::validateWebformElementComposite()

Validates a webform element composite (builder) element.

File

src/Element/WebformElementComposite.php, line 271

Class

WebformElementComposite
Provides a element for the composite elements.

Namespace

Drupal\webform\Element

Code

public static function validateWebformElementComposite(&$element, FormStateInterface $form_state, &$complete_form) {

  /** @var \Drupal\webform\Plugin\WebformElementManagerInterface $element_manager */
  $element_manager = \Drupal::service('plugin.manager.webform.element');
  $elements_value = NestedArray::getValue($form_state
    ->getValues(), $element['elements']['#parents']);

  // Check for duplicate keys.
  $keys = [];
  foreach ($elements_value as $element_value) {
    $key = $element_value['key'];
    if (isset($keys[$key])) {
      $form_state
        ->setError($element, t('Duplicate key found. The %key key must only be assigned on one element.', [
        '%key' => $key,
      ]));
      return;
    }
    $keys[$key] = $key;
  }

  // Convert the $elements value which is a simple associative array into a
  // render array.
  $elements = [];
  foreach ($elements_value as $element_value) {
    $key = $element_value['key'];
    unset($element_value['key']);

    // Remove empty strings from array.
    $element_value = array_filter($element_value, function ($value) {
      return $value !== '';
    });

    // Unset empty required or case to boolean.
    if (empty($element_value['required'])) {
      unset($element_value['required']);
    }
    else {
      $element_value['required'] = TRUE;
    }

    // Limit value keys to supported element properties.
    // This removes options from elements that don't support #options.
    if (isset($element_value['type'])) {
      foreach ($element_value as $property_name => $property_value) {
        if (!in_array($property_name, [
          'type',
          'custom',
        ])) {

          /** @var \Drupal\webform\Plugin\WebformElementInterface $element_plugin */
          $element_plugin = $element_manager
            ->createInstance($element_value['type']);
          if (!$element_plugin
            ->hasProperty($property_name)) {
            unset($element_value[$property_name]);
          }
        }
      }
    }
    if (isset($element_value['custom'])) {
      if ($element_value['custom']) {
        $custom = Yaml::decode($element_value['custom']);
        if ($custom && is_array($custom)) {
          $element_value += $custom;
        }
      }
      unset($element_value['custom']);
    }
    $elements[$key] = WebformArrayHelper::addPrefix($element_value);
  }
  foreach ($elements as $composite_element_key => $composite_element) {
    if (!isset($composite_element['#type'])) {
      continue;
    }

    /** @var \Drupal\webform\Plugin\WebformElementInterface $element_plugin */
    $element_plugin = $element_manager
      ->getElementInstance($composite_element);
    $t_args = [
      '%title' => isset($composite_element['#title']) ? $composite_element['#title'] : $composite_element_key,
      '@type' => $composite_element['#type'],
    ];

    // Make sure #options is set for composite element's that require #options.
    if ($element_plugin
      ->hasProperty('options') && empty($composite_element['#options'])) {
      $form_state
        ->setError($element, t('Options for %title is required.', $t_args));
    }

    // Make sure element is not storing multiple values.
    if ($element_plugin
      ->hasMultipleValues($composite_element)) {
      $form_state
        ->setError($element, t('Multiple value is not supported for %title (@type).', $t_args));
    }
  }
  $form_state
    ->setValueForElement($element['elements'], NULL);
  $element['#value'] = $elements;
  $form_state
    ->setValueForElement($element, $elements);
}