You are here

protected function GroupContentMenuForm::submitOverviewForm in Group Content Menu 8

Submit handler for the menu overview form.

This function takes great care in saving parent items first, then items underneath them. Saving items in the incorrect order can break the tree.

1 call to GroupContentMenuForm::submitOverviewForm()
GroupContentMenuForm::save in src/Form/GroupContentMenuForm.php
Form submission handler for the 'save' action.

File

src/Form/GroupContentMenuForm.php, line 361

Class

GroupContentMenuForm
Form controller for Group menu instance edit forms.

Namespace

Drupal\group_content_menu\Form

Code

protected function submitOverviewForm(array $complete_form, FormStateInterface $form_state) {

  // Form API supports constructing and validating self-contained sections
  // within forms, but does not allow to handle the form section's submission
  // equally separated yet. Therefore, we use a $form_state key to point to
  // the parents of the form section.
  $parents = $form_state
    ->get('menu_overview_form_parents');
  $input = NestedArray::getValue($form_state
    ->getUserInput(), $parents);
  $form =& NestedArray::getValue($complete_form, $parents);

  // When dealing with saving menu items, the order in which these items are
  // saved is critical. If a changed child item is saved before its parent,
  // the child item could be saved with an invalid path past its immediate
  // parent. To prevent this, save items in the form in the same order they
  // are sent, ensuring parents are saved first, then their children.
  // See https://www.drupal.org/node/181126#comment-632270.
  $order = is_array($input) ? array_flip(array_keys($input)) : [];

  // Update our original form with the new order.
  $form = array_intersect_key(array_merge($order, $form), $form);
  $fields = [
    'weight',
    'parent',
    'enabled',
  ];
  $form_links = $form['links'];
  foreach (Element::children($form_links) as $id) {
    if (isset($form_links[$id]['#item'])) {
      $element = $form_links[$id];
      $updated_values = [];

      // Update any fields that have changed in this menu item.
      foreach ($fields as $field) {
        if ($element[$field]['#value'] !== $element[$field]['#default_value']) {
          $updated_values[$field] = $element[$field]['#value'];
        }
      }
      if ($updated_values) {

        // Use the ID from the actual plugin instance since the hidden value
        // in the form could be tampered with.
        $this->menuLinkManager
          ->updateDefinition($element['#item']->link
          ->getPLuginId(), $updated_values);
      }
    }
  }
}