You are here

public function OverviewTerms::submitForm in Drupal 8

Same name and namespace in other branches
  1. 9 core/modules/taxonomy/src/Form/OverviewTerms.php \Drupal\taxonomy\Form\OverviewTerms::submitForm()
  2. 10 core/modules/taxonomy/src/Form/OverviewTerms.php \Drupal\taxonomy\Form\OverviewTerms::submitForm()

Form submission handler.

Rather than using a textfield or weight field, this form depends entirely upon the order of form elements on the page to determine new weights.

Because there might be hundreds or thousands of taxonomy terms that need to be ordered, terms are weighted from 0 to the number of terms in the vocabulary, rather than the standard -10 to 10 scale. Numbers are sorted lowest to highest, but are not necessarily sequential. Numbers may be skipped when a term has children so that reordering is minimal when a child is added or removed from a term.

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 FormInterface::submitForm

File

core/modules/taxonomy/src/Form/OverviewTerms.php, line 525

Class

OverviewTerms
Provides terms overview form for a taxonomy vocabulary.

Namespace

Drupal\taxonomy\Form

Code

public function submitForm(array &$form, FormStateInterface $form_state) {

  // Sort term order based on weight.
  uasort($form_state
    ->getValue('terms'), [
    'Drupal\\Component\\Utility\\SortArray',
    'sortByWeightElement',
  ]);
  $vocabulary = $form_state
    ->get([
    'taxonomy',
    'vocabulary',
  ]);
  $changed_terms = [];
  $tree = $this->storageController
    ->loadTree($vocabulary
    ->id(), 0, NULL, TRUE);
  if (empty($tree)) {
    return;
  }

  // Build a list of all terms that need to be updated on previous pages.
  $weight = 0;
  $term = $tree[0];
  while ($term
    ->id() != $form['#first_tid']) {
    if ($term->parents[0] == 0 && $term
      ->getWeight() != $weight) {
      $term
        ->setWeight($weight);
      $changed_terms[$term
        ->id()] = $term;
    }
    $weight++;
    $term = $tree[$weight];
  }

  // Renumber the current page weights and assign any new parents.
  $level_weights = [];
  foreach ($form_state
    ->getValue('terms') as $tid => $values) {
    if (isset($form['terms'][$tid]['#term'])) {
      $term = $form['terms'][$tid]['#term'];

      // Give terms at the root level a weight in sequence with terms on previous pages.
      if ($values['term']['parent'] == 0 && $term
        ->getWeight() != $weight) {
        $term
          ->setWeight($weight);
        $changed_terms[$term
          ->id()] = $term;
      }
      elseif ($values['term']['parent'] > 0) {
        $level_weights[$values['term']['parent']] = isset($level_weights[$values['term']['parent']]) ? $level_weights[$values['term']['parent']] + 1 : 0;
        if ($level_weights[$values['term']['parent']] != $term
          ->getWeight()) {
          $term
            ->setWeight($level_weights[$values['term']['parent']]);
          $changed_terms[$term
            ->id()] = $term;
        }
      }

      // Update any changed parents.
      if ($values['term']['parent'] != $term->parents[0]) {
        $term->parent->target_id = $values['term']['parent'];
        $changed_terms[$term
          ->id()] = $term;
      }
      $weight++;
    }
  }

  // Build a list of all terms that need to be updated on following pages.
  for ($weight; $weight < count($tree); $weight++) {
    $term = $tree[$weight];
    if ($term->parents[0] == 0 && $term
      ->getWeight() != $weight) {
      $term->parent->target_id = $term->parents[0];
      $term
        ->setWeight($weight);
      $changed_terms[$term
        ->id()] = $term;
    }
  }
  if (!empty($changed_terms)) {
    $pending_term_ids = $this->storageController
      ->getTermIdsWithPendingRevisions();

    // Force a form rebuild if any of the changed terms has a pending
    // revision.
    if (array_intersect_key(array_flip($pending_term_ids), $changed_terms)) {
      $this
        ->messenger()
        ->addError($this
        ->t('The terms with updated parents have been modified by another user, the changes could not be saved.'));
      $form_state
        ->setRebuild();
      return;
    }

    // Save all updated terms.
    foreach ($changed_terms as $term) {
      $term
        ->save();
    }
    $this
      ->messenger()
      ->addStatus($this
      ->t('The configuration options have been saved.'));
  }
}