3 namespace Drupal\views\Form;
5 use Drupal\Component\Utility\UrlHelper;
6 use Drupal\Core\DependencyInjection\ClassResolverInterface;
7 use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
8 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
9 use Drupal\Core\Form\FormInterface;
10 use Drupal\Core\Form\FormStateInterface;
11 use Drupal\Core\Routing\UrlGeneratorInterface;
13 use Drupal\views\ViewExecutable;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15 use Symfony\Component\HttpFoundation\RequestStack;
18 * Provides a base class for single- or multistep view forms.
20 * This class only dispatches logic to the form for the current step. The form
21 * is always assumed to be multistep, even if it has only one step (which by
22 * default is \Drupal\views\Form\ViewsFormMainForm). That way it is actually
23 * possible for modules to have a multistep form if they need to.
25 class ViewsForm implements FormInterface, ContainerInjectionInterface {
26 use DependencySerializationTrait;
29 * The class resolver to get the subform form objects.
31 * @var \Drupal\Core\DependencyInjection\ClassResolverInterface
33 protected $classResolver;
38 * @var \Symfony\Component\HttpFoundation\RequestStack
40 protected $requestStack;
43 * The url generator to generate the form action.
45 * @var \Drupal\Core\Routing\UrlGeneratorInterface
47 protected $urlGenerator;
57 * The ID of the active view's display.
61 protected $viewDisplayId;
64 * The arguments passed to the active view.
68 protected $viewArguments;
71 * Constructs a ViewsForm object.
73 * @param \Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
74 * The class resolver to get the subform form objects.
75 * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
76 * The url generator to generate the form action.
77 * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
79 * @param string $view_id
81 * @param string $view_display_id
82 * The ID of the active view's display.
83 * @param string[] $view_args
84 * The arguments passed to the active view.
86 public function __construct(ClassResolverInterface $class_resolver, UrlGeneratorInterface $url_generator, RequestStack $requestStack, $view_id, $view_display_id, array $view_args) {
87 $this->classResolver = $class_resolver;
88 $this->urlGenerator = $url_generator;
89 $this->requestStack = $requestStack;
90 $this->viewId = $view_id;
91 $this->viewDisplayId = $view_display_id;
92 $this->viewArguments = $view_args;
98 public static function create(ContainerInterface $container, $view_id = NULL, $view_display_id = NULL, array $view_args = NULL) {
100 $container->get('class_resolver'),
101 $container->get('url_generator'),
102 $container->get('request_stack'),
110 * Returns a string for the form's base ID.
113 * The string identifying the form's base ID.
115 public function getBaseFormId() {
119 $this->viewDisplayId,
122 return implode('_', $parts);
128 public function getFormId() {
130 $this->getBaseFormId(),
133 if (!empty($this->viewArguments)) {
134 // Append the passed arguments to ensure form uniqueness.
135 $parts = array_merge($parts, $this->viewArguments);
138 return implode('_', $parts);
144 public function buildForm(array $form, FormStateInterface $form_state, ViewExecutable $view = NULL, $output = []) {
145 if (!$step = $form_state->get('step')) {
146 $step = 'views_form_views_form';
147 $form_state->set('step', $step);
149 $form_state->set(['step_controller', 'views_form_views_form'], 'Drupal\views\Form\ViewsFormMainForm');
151 // Add the base form ID.
152 $form_state->addBuildInfo('base_form_id', $this->getBaseFormId());
156 $query = $this->requestStack->getCurrentRequest()->query->all();
157 $query = UrlHelper::filterQueryParameters($query, [], '');
159 $options = ['query' => $query];
160 $form['#action'] = $view->hasUrl() ? $view->getUrl()->setOptions($options)->toString() : Url::fromRoute('<current>')->setOptions($options)->toString();
161 // Tell the preprocessor whether it should hide the header, footer, pager,
163 $form['show_view_elements'] = [
165 '#value' => ($step == 'views_form_views_form') ? TRUE : FALSE,
168 $form_object = $this->getFormObject($form_state);
169 $form += $form_object->buildForm($form, $form_state, $view, $output);
177 public function validateForm(array &$form, FormStateInterface $form_state) {
178 $form_object = $this->getFormObject($form_state);
179 $form_object->validateForm($form, $form_state);
185 public function submitForm(array &$form, FormStateInterface $form_state) {
186 $form_object = $this->getFormObject($form_state);
187 $form_object->submitForm($form, $form_state);
191 * Returns the object used to build the step form.
193 * @param \Drupal\Core\Form\FormStateInterface $form_state
194 * The form_state of the current form.
196 * @return \Drupal\Core\Form\FormInterface
197 * The form object to use.
199 protected function getFormObject(FormStateInterface $form_state) {
200 // If this is a class, instantiate it.
201 $form_step_class = $form_state->get(['step_controller', $form_state->get('step')]) ?: 'Drupal\views\Form\ViewsFormMainForm';
202 return $this->classResolver->getInstanceFromDefinition($form_step_class);