Version 1
[yaffs-website] / web / core / modules / views / src / Form / ViewsForm.php
1 <?php
2
3 namespace Drupal\views\Form;
4
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;
12 use Drupal\Core\Url;
13 use Drupal\views\ViewExecutable;
14 use Symfony\Component\DependencyInjection\ContainerInterface;
15 use Symfony\Component\HttpFoundation\RequestStack;
16
17 /**
18  * Provides a base class for single- or multistep view forms.
19  *
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.
24  */
25 class ViewsForm implements FormInterface, ContainerInjectionInterface {
26   use DependencySerializationTrait;
27
28   /**
29    * The class resolver to get the subform form objects.
30    *
31    * @var \Drupal\Core\DependencyInjection\ClassResolverInterface
32    */
33   protected $classResolver;
34
35   /**
36    * The request stack.
37    *
38    * @var \Symfony\Component\HttpFoundation\RequestStack
39    */
40   protected $requestStack;
41
42   /**
43    * The url generator to generate the form action.
44    *
45    * @var \Drupal\Core\Routing\UrlGeneratorInterface
46    */
47   protected $urlGenerator;
48
49   /**
50    * The ID of the view.
51    *
52    * @var string
53    */
54   protected $viewId;
55
56   /**
57    * The ID of the active view's display.
58    *
59    * @var string
60    */
61   protected $viewDisplayId;
62
63   /**
64    * The arguments passed to the active view.
65    *
66    * @var string[]
67    */
68   protected $viewArguments;
69
70   /**
71    * Constructs a ViewsForm object.
72    *
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
78    *   The request stack.
79    * @param string $view_id
80    *   The ID of the view.
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.
85    */
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;
93   }
94
95   /**
96    * {@inheritdoc}
97    */
98   public static function create(ContainerInterface $container, $view_id = NULL, $view_display_id = NULL, array $view_args = NULL) {
99     return new static(
100       $container->get('class_resolver'),
101       $container->get('url_generator'),
102       $container->get('request_stack'),
103       $view_id,
104       $view_display_id,
105       $view_args
106     );
107   }
108
109   /**
110    * Returns a string for the form's base ID.
111    *
112    * @return string
113    *   The string identifying the form's base ID.
114    */
115   public function getBaseFormId() {
116     $parts = [
117       'views_form',
118       $this->viewId,
119       $this->viewDisplayId,
120     ];
121
122     return implode('_', $parts);
123   }
124
125   /**
126    * {@inheritdoc}
127    */
128   public function getFormId() {
129     $parts = [
130       $this->getBaseFormId(),
131     ];
132
133     if (!empty($this->viewArguments)) {
134       // Append the passed arguments to ensure form uniqueness.
135       $parts = array_merge($parts, $this->viewArguments);
136     }
137
138     return implode('_', $parts);
139   }
140
141   /**
142    * {@inheritdoc}
143    */
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);
148     }
149     $form_state->set(['step_controller', 'views_form_views_form'], 'Drupal\views\Form\ViewsFormMainForm');
150
151     // Add the base form ID.
152     $form_state->addBuildInfo('base_form_id', $this->getBaseFormId());
153
154     $form = [];
155
156     $query = $this->requestStack->getCurrentRequest()->query->all();
157     $query = UrlHelper::filterQueryParameters($query, [], '');
158
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,
162     // etc.
163     $form['show_view_elements'] = [
164       '#type' => 'value',
165       '#value' => ($step == 'views_form_views_form') ? TRUE : FALSE,
166     ];
167
168     $form_object = $this->getFormObject($form_state);
169     $form += $form_object->buildForm($form, $form_state, $view, $output);
170
171     return $form;
172   }
173
174   /**
175    * {@inheritdoc}
176    */
177   public function validateForm(array &$form, FormStateInterface $form_state) {
178     $form_object = $this->getFormObject($form_state);
179     $form_object->validateForm($form, $form_state);
180   }
181
182   /**
183    * {@inheritdoc}
184    */
185   public function submitForm(array &$form, FormStateInterface $form_state) {
186     $form_object = $this->getFormObject($form_state);
187     $form_object->submitForm($form, $form_state);
188   }
189
190   /**
191    * Returns the object used to build the step form.
192    *
193    * @param \Drupal\Core\Form\FormStateInterface $form_state
194    *   The form_state of the current form.
195    *
196    * @return \Drupal\Core\Form\FormInterface
197    *   The form object to use.
198    */
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);
203   }
204
205 }