ViewsForm.php 5.49 KB
Newer Older
1 2 3 4 5 6 7 8 9
<?php

/**
 * @file
 * Contains \Drupal\views\Form\ViewsForm.
 */

namespace Drupal\views\Form;

10
use Drupal\Component\Utility\UrlHelper;
11
use Drupal\Core\Controller\ControllerResolverInterface;
12
use Drupal\Core\DependencyInjection\ClassResolverInterface;
13
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
14
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
15
use Drupal\Core\Form\FormInterface;
16
use Drupal\Core\Form\FormStateInterface;
17 18 19
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\views\ViewExecutable;
use Symfony\Component\DependencyInjection\ContainerInterface;
20
use Symfony\Component\HttpFoundation\RequestStack;
21 22 23 24 25 26 27 28 29

/**
 * Provides a base class for single- or multistep view forms.
 *
 * This class only dispatches logic to the form for the current step. The form
 * is always assumed to be multistep, even if it has only one step (which by
 * default is \Drupal\views\Form\ViewsFormMainForm). That way it is actually
 * possible for modules to have a multistep form if they need to.
 */
30 31
class ViewsForm implements FormInterface, ContainerInjectionInterface {
  use DependencySerializationTrait;
32 33

  /**
34
   * The class resolver to get the subform form objects.
35
   *
36
   * @var \Drupal\Core\DependencyInjection\ClassResolverInterface
37
   */
38
  protected $classResolver;
39 40

  /**
41
   * The request stack.
42
   *
43
   * @var \Symfony\Component\HttpFoundation\RequestStack
44
   */
45
  protected $requestStack;
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

  /**
   * The url generator to generate the form action.
   *
   * @var \Drupal\Core\Routing\UrlGeneratorInterface
   */
  protected $urlGenerator;

  /**
   * The ID of the view.
   *
   * @var string
   */
  protected $viewId;

  /**
   * The ID of the active view's display.
   *
   * @var string
   */
  protected $viewDisplayId;

  /**
   * Constructs a ViewsForm object.
   *
71 72
   * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $controller_resolver
   *   The class resolver to get the subform form objects.
73 74
   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
   *   The url generator to generate the form action.
75 76
   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
   *   The request stack.
77 78 79 80 81
   * @param string $view_id
   *   The ID of the view.
   * @param string $view_display_id
   *   The ID of the active view's display.
   */
82
  public function __construct(ClassResolverInterface $controller_resolver, UrlGeneratorInterface $url_generator, RequestStack $requestStack, $view_id, $view_display_id) {
83
    $this->classResolver = $controller_resolver;
84
    $this->urlGenerator = $url_generator;
85
    $this->requestStack = $requestStack;
86 87 88 89 90 91 92 93 94 95 96
    $this->viewId = $view_id;
    $this->viewDisplayId = $view_display_id;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, $view_id = NULL, $view_display_id = NULL) {
    return new static(
      $container->get('controller_resolver'),
      $container->get('url_generator'),
97
      $container->get('request_stack'),
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
      $view_id,
      $view_display_id
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormID() {
    $parts = array(
      'views_form',
      $this->viewId,
      $this->viewDisplayId,
    );

    return implode('_', $parts);
  }

  /**
   * {@inheritdoc}
   */
119
  public function buildForm(array $form, FormStateInterface $form_state, ViewExecutable $view = NULL, $output = NULL) {
120 121 122 123 124 125 126 127 128 129 130
    $form_state['step'] = isset($form_state['step']) ? $form_state['step'] : 'views_form_views_form';
    $form_state['step_controller']['views_form_views_form'] = 'Drupal\views\Form\ViewsFormMainForm';

    // Cache the built form to prevent it from being rebuilt prior to validation
    // and submission, which could lead to data being processed incorrectly,
    // because the views rows (and thus, the form elements as well) have changed
    // in the meantime.
    $form_state['cache'] = TRUE;

    $form = array();

131
    $query = $this->requestStack->getCurrentRequest()->query->all();
132
    $query = UrlHelper::filterQueryParameters($query, array(), '');
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149

    $form['#action'] = $this->urlGenerator->generateFromPath($view->getUrl(), array('query' => $query));
    // Tell the preprocessor whether it should hide the header, footer, pager...
    $form['show_view_elements'] = array(
      '#type' => 'value',
      '#value' => ($form_state['step'] == 'views_form_views_form') ? TRUE : FALSE,
    );

    $form_object = $this->getFormObject($form_state);
    $form += $form_object->buildForm($form, $form_state, $view, $output);

    return $form;
  }

  /**
   * {@inheritdoc}
   */
150
  public function validateForm(array &$form, FormStateInterface $form_state) {
151 152 153 154 155 156 157
    $form_object = $this->getFormObject($form_state);
    $form_object->validateForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
158
  public function submitForm(array &$form, FormStateInterface $form_state) {
159 160 161 162 163 164 165
    $form_object = $this->getFormObject($form_state);
    $form_object->submitForm($form, $form_state);
  }

  /**
   * Returns the object used to build the step form.
   *
166
   * @param \Drupal\Core\Form\FormStateInterface $form_state
167 168 169 170 171
   *   The form_state of the current form.
   *
   * @return \Drupal\Core\Form\FormInterface
   *   The form object to use.
   */
172
  protected function getFormObject(FormStateInterface $form_state) {
173 174
    // If this is a class, instantiate it.
    $form_step_class = isset($form_state['step_controller'][$form_state['step']]) ? $form_state['step_controller'][$form_state['step']] : 'Drupal\views\Form\ViewsFormMainForm';
175
    return $this->classResolver->getInstanceFromDefinition($form_step_class);
176 177 178
  }

}