You are here

public function ViewsFormBase::getForm in Drupal 10

Same name and namespace in other branches
  1. 8 core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php \Drupal\views_ui\Form\Ajax\ViewsFormBase::getForm()
  2. 9 core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php \Drupal\views_ui\Form\Ajax\ViewsFormBase::getForm()

File

core/modules/views_ui/src/Form/Ajax/ViewsFormBase.php, line 87

Class

ViewsFormBase
Provides a base class for Views UI AJAX forms.

Namespace

Drupal\views_ui\Form\Ajax

Code

public function getForm(ViewEntityInterface $view, $display_id, $js) {

  /** @var \Drupal\Core\Form\FormStateInterface $form_state */
  $form_state = $this
    ->getFormState($view, $display_id, $js);
  $view = $form_state
    ->get('view');
  $form_key = $form_state
    ->get('form_key');

  // @todo Remove the need for this.
  \Drupal::moduleHandler()
    ->loadInclude('views_ui', 'inc', 'admin');

  // Reset the cache of IDs. Drupal rather aggressively prevents ID
  // duplication but this causes it to remember IDs that are no longer even
  // being used.
  Html::resetSeenIds();

  // check to see if this is the top form of the stack. If it is, pop
  // it off; if it isn't, the user clicked somewhere else and the stack is
  // now irrelevant.
  if (!empty($view->stack)) {
    $identifier = implode('-', array_filter([
      $form_key,
      $view
        ->id(),
      $display_id,
      $form_state
        ->get('type'),
      $form_state
        ->get('id'),
    ]));

    // Retrieve the first form from the stack without changing the integer keys,
    // as they're being used for the "2 of 3" progress indicator.
    reset($view->stack);
    $stack_key = key($view->stack);
    $top = current($view->stack);
    next($view->stack);
    unset($view->stack[$stack_key]);
    if (array_shift($top) != $identifier) {
      $view->stack = [];
    }
  }

  // Automatically remove the form cache if it is set and the key does
  // not match. This way navigating away from the form without hitting
  // update will work.
  if (isset($view->form_cache) && $view->form_cache['key'] !== $form_key) {
    unset($view->form_cache);
  }
  $form_class = get_class($form_state
    ->getFormObject());
  $response = $this
    ->ajaxFormWrapper($form_class, $form_state);

  // If the form has not been submitted, or was not set for rerendering, stop.
  if (!$form_state
    ->isSubmitted() || $form_state
    ->get('rerender')) {
    return $response;
  }

  // Sometimes we need to re-generate the form for multi-step type operations.
  if (!empty($view->stack)) {
    $stack = $view->stack;
    $top = array_shift($stack);

    // Build the new form state for the next form in the stack.
    $reflection = new \ReflectionClass($view::$forms[$top[1]]);
    $form_state = $reflection
      ->newInstanceArgs(array_slice($top, 3, 2))
      ->getFormState($view, $top[2], $form_state
      ->get('ajax'));
    $form_class = get_class($form_state
      ->getFormObject());
    $form_state
      ->setUserInput([]);
    $form_url = views_ui_build_form_url($form_state);
    if (!$form_state
      ->get('ajax')) {
      return new RedirectResponse($form_url
        ->setAbsolute()
        ->toString());
    }
    $form_state
      ->set('url', $form_url);
    $response = $this
      ->ajaxFormWrapper($form_class, $form_state);
  }
  elseif (!$form_state
    ->get('ajax')) {

    // if nothing on the stack, non-js forms just go back to the main view editor.
    $display_id = $form_state
      ->get('display_id');
    return new RedirectResponse(Url::fromRoute('entity.view.edit_display_form', [
      'view' => $view
        ->id(),
      'display_id' => $display_id,
    ], [
      'absolute' => TRUE,
    ])
      ->toString());
  }
  else {
    $response = new AjaxResponse();
    $response
      ->addCommand(new CloseModalDialogCommand());
    $response
      ->addCommand(new ShowButtonsCommand(!empty($view->changed)));
    $response
      ->addCommand(new TriggerPreviewCommand());
    if ($page_title = $form_state
      ->get('page_title')) {
      $response
        ->addCommand(new ReplaceTitleCommand($page_title));
    }
  }

  // If this form was for view-wide changes, there's no need to regenerate
  // the display section of the form.
  if ($display_id !== '') {
    \Drupal::entityTypeManager()
      ->getFormObject('view', 'edit')
      ->rebuildCurrentTab($view, $response, $display_id);
  }
  return $response;
}