You are here

public function WebformUiEntityElementsForm::validateForm in Webform 6.x

Same name and namespace in other branches
  1. 8.5 modules/webform_ui/src/WebformUiEntityElementsForm.php \Drupal\webform_ui\WebformUiEntityElementsForm::validateForm()

Form validation handler.

Parameters

array $form: An associative array containing the structure of the form.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

Overrides FormBase::validateForm

File

modules/webform_ui/src/WebformUiEntityElementsForm.php, line 149

Class

WebformUiEntityElementsForm
Webform manage elements UI form.

Namespace

Drupal\webform_ui

Code

public function validateForm(array &$form, FormStateInterface $form_state) {
  parent::validateForm($form, $form_state);

  /** @var \Drupal\webform\WebformInterface $webform */
  $webform = $this
    ->getEntity();

  // Get raw flattened elements that will be used to rebuild element's YAML
  // hierarchy.
  $elements_flattened = $webform
    ->getElementsDecodedAndFlattened();

  // Get the reordered elements and sort them by weight.
  $webform_ui_elements = $form_state
    ->getValue('webform_ui_elements') ?: [];
  uasort($webform_ui_elements, [
    'Drupal\\Component\\Utility\\SortArray',
    'sortByWeightElement',
  ]);

  // Make sure the reordered element keys and match the existing element keys.
  if (array_diff_key($webform_ui_elements, $elements_flattened)) {
    $form_state
      ->setError($form['webform_ui_elements'], $this
      ->t('The elements have been unexpectedly altered. Please try again'));
  }

  // Validate parent key and add children to ordered elements.
  foreach ($webform_ui_elements as $key => $table_element) {

    // Validate parent key.
    if ($parent_key = $table_element['parent_key']) {

      // Validate missing parent key.
      if (!isset($elements_flattened[$parent_key])) {
        $form_state
          ->setError($form['webform_ui_elements'][$key]['parent']['parent_key'], $this
          ->t('Parent %parent_key does not exist.', [
          '%parent_key' => $parent_key,
        ]));
        continue;
      }

      // Validate the parent keys and make sure there
      // are no recursive parents.
      $parent_keys = [
        $key,
      ];
      $current_parent_key = $parent_key;
      while ($current_parent_key) {
        if (in_array($current_parent_key, $parent_keys)) {
          $form_state
            ->setError($form['webform_ui_elements'][$key]['parent']['parent_key'], $this
            ->t('Parent %parent_key key is not valid.', [
            '%parent_key' => $parent_key,
          ]));
          break;
        }
        $parent_keys[] = $current_parent_key;
        $current_parent_key = isset($webform_ui_elements[$current_parent_key]['parent_key']) ? $webform_ui_elements[$current_parent_key]['parent_key'] : NULL;
      }
    }

    // Set #required or remove the property.
    $is_conditionally_required = isset($elements_flattened[$key]['#states']) && array_intersect_key($this->requiredStates, $elements_flattened[$key]['#states']);
    if ($is_conditionally_required) {

      // Always unset conditionally required elements.
      unset($elements_flattened[$key]['#required']);
    }
    elseif (isset($webform_ui_elements[$key]['required'])) {
      if (empty($webform_ui_elements[$key]['required'])) {
        unset($elements_flattened[$key]['#required']);
      }
      else {
        $elements_flattened[$key]['#required'] = TRUE;
      }
    }

    // Add this key to the parent's children.
    $webform_ui_elements[$parent_key]['children'][$key] = $key;
  }
  if ($form_state
    ->hasAnyErrors()) {
    return;
  }

  // Rebuild elements to reflect new hierarchy.
  $elements_updated = [];

  // Preserve the original elements root properties.
  $elements_original = Yaml::decode($webform
    ->get('elements')) ?: [];
  foreach ($elements_original as $key => $value) {
    if (WebformElementHelper::property($key)) {
      $elements_updated[$key] = $value;
    }
  }
  $this
    ->buildUpdatedElementsRecursive($elements_updated, '', $webform_ui_elements, $elements_flattened);

  // Update the webform's elements.
  $webform
    ->setUpdating()
    ->setElements($elements_updated);

  // Validate only elements required, hierarchy, and rendering.
  $validate_options = [
    'required' => TRUE,
    'yaml' => FALSE,
    'array' => FALSE,
    'names' => FALSE,
    'properties' => FALSE,
    'submissions' => FALSE,
    'hierarchy' => TRUE,
    'rendering' => TRUE,
  ];
  if ($this->elementsValidator
    ->validate($webform, $validate_options)) {
    $form_state
      ->setErrorByName(NULL, $this
      ->t('There has been error validating the elements.'));
  }
}