TYPO3  7.6
FrontendController.php
Go to the documentation of this file.
1 <?php
2 namespace TYPO3\CMS\Form\Controller;
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
7  * It is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License, either version 2
9  * of the License, or any later version.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
25 
30 {
34  protected $formBuilder;
35 
39  protected $validationBuilder;
40 
44  protected $sessionUtility;
45 
49  protected $formUtility;
50 
56  protected $typoscript = array();
57 
63  protected $skipValidation = false;
64 
68  protected $controllerContext;
69 
73  protected $configuration;
74 
79  public function injectSessionUtility(\TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility)
80  {
81  $this->sessionUtility = $sessionUtility;
82  }
83 
89  protected function initializeAction()
90  {
91  $this->configuration = Configuration::create()->setTypoScript($this->settings['typoscript']);
92  $this->formUtility = FormUtility::create($this->configuration);
93  $this->validationBuilder = ValidationBuilder::create($this->configuration);
94  $this->validationBuilder->setFormUtility($this->formUtility);
95  $this->formBuilder = FormBuilder::create($this->configuration);
96  $this->formBuilder->setValidationBuilder($this->validationBuilder);
97  $this->formBuilder->setFormUtility($this->formUtility);
98  $this->typoscript = $this->settings['typoscript'];
99 
100  // uploaded file storage
101  $this->sessionUtility->initSession($this->configuration->getPrefix());
102  // move the incoming "formPrefix" data to the $model argument
103  // now we can validate the $model argument
104  if ($this->request->hasArgument($this->configuration->getPrefix())) {
105  $this->skipValidation = false;
106  $argument = $this->request->getArgument($this->configuration->getPrefix());
107  $this->request->setArgument('model', $argument);
108  } else {
109  // If there are more forms at a page we have to skip
110  // the validation of not submitted forms
111  $this->skipValidation = true;
112  $this->request->setArgument('model', array());
113  }
114  }
115 
121  protected function initializeShowAction()
122  {
123  // set validation errors
124  $validationResults = $this->request->getOriginalRequestMappingResults()->forProperty('model');
125  if (!$validationResults->hasErrors()) {
126  // If there are errors, the rules already build
127  // but if there are errors, we need to build the rules here,
128  // because of the mandatory message rendering
129  $this->validationBuilder->buildRules();
130  return;
131  }
132  $this->formBuilder->setValidationErrors($validationResults);
133  }
134 
140  protected function initializeConfirmationAction()
141  {
142  $this->prepareValidations();
143  }
144 
150  protected function initializeProcessAction()
151  {
152  $this->prepareValidations();
153  }
154 
161  protected function buildControllerContext()
162  {
163  $controllerContext = ControllerContext::extend(parent::buildControllerContext())
164  ->setConfiguration($this->configuration);
165  $this->formBuilder->setControllerContext($controllerContext);
166  return $controllerContext;
167  }
168 
176  public function showAction(ValidationElement $incomingData = null)
177  {
178  if ($incomingData !== null) {
179  $this->controllerContext->setValidationElement($incomingData);
180  }
181  $form = $this->formBuilder->buildModel();
182  $this->view->assign('model', $form);
183  }
184 
192  public function confirmationAction(ValidationElement $model)
193  {
194  $this->skipForeignFormProcessing();
195 
196  if (count($model->getIncomingFields()) === 0) {
197  $this->sessionUtility->destroySession();
198  $this->forward('show');
199  }
200  $this->controllerContext->setValidationElement($model);
201  $form = $this->formBuilder->buildModel();
202  // store uploaded files
203  $this->sessionUtility->storeSession();
204  $this->view->assign('model', $form);
205 
206  $message = $this->formUtility->renderItem(
207  $this->typoscript['confirmation.']['message.'],
208  $this->typoscript['confirmation.']['message'],
209  LocalizationUtility::translate('tx_form_view_confirmation.message', 'form')
210  );
211  $this->view->assign('message', $message);
212  }
213 
221  {
222  $this->skipForeignFormProcessing();
223 
224  if ($this->request->hasArgument('confirmation-true')) {
225  $this->forward('process', null, null, array($this->configuration->getPrefix() => $this->request->getArgument('model')));
226  } else {
227  $this->sessionUtility->destroySession();
228  $this->forward('show', null, null, array('incomingData' => $this->request->getArgument('model')));
229  }
230  }
231 
240  public function processAction(ValidationElement $model)
241  {
242  $this->skipForeignFormProcessing();
243 
244  $this->controllerContext->setValidationElement($model);
245  $form = $this->formBuilder->buildModel();
246  $postProcessorTypoScript = array();
247  if (isset($this->typoscript['postProcessor.'])) {
248  $postProcessorTypoScript = $this->typoscript['postProcessor.'];
249  }
250 
252  $postProcessor = $this->objectManager->get(
253  \TYPO3\CMS\Form\PostProcess\PostProcessor::class,
254  $form, $postProcessorTypoScript
255  );
256  $postProcessor->setControllerContext($this->controllerContext);
257 
258  // @todo What is happening here?
259  $content = $postProcessor->process();
260  $this->sessionUtility->destroySession();
261  $this->forward('afterProcess', null, null, array('postProcessorContent' => $content));
262  }
263 
270  public function afterProcessAction($postProcessorContent)
271  {
272  $this->view->assign('postProcessorContent', $postProcessorContent);
273  }
274 
286  protected function skipForeignFormProcessing()
287  {
288  if (
289  !$this->request->hasArgument($this->configuration->getPrefix())
290  && !$this->sessionUtility->getSessionData()
291  ) {
292  $this->forward('show');
293  }
294  }
295 
302  protected function prepareValidations()
303  {
304  if ($this->skipValidation || !$this->arguments->hasArgument('model')) {
305  return;
306  }
307 
308  $this->validationBuilder->buildRules($this->request->getArgument('model'));
309  $this->setDynamicValidation($this->validationBuilder->getRules());
310  $this->skipValidation = false;
311  }
312 
320  protected function setDynamicValidation(array $toValidate = array())
321  {
322  // build custom validation chain
324  $validatorResolver = $this->objectManager->get(\TYPO3\CMS\Extbase\Validation\ValidatorResolver::class);
325 
327  $modelValidator = $validatorResolver->createValidator(\TYPO3\CMS\Form\Domain\Validator\ValidationElementValidator::class);
328  foreach ($toValidate as $propertyName => $validations) {
329  foreach ($validations as $validation) {
330  if (empty($validation['validator'])) {
331  throw new \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException('Invalid validate configuration for ' . $propertyName . ': Could not resolve class name for validator "' . $validation['validatorName'] . '".', 1441893777);
332  }
333  $modelValidator->addPropertyValidator($propertyName, $validation['validator']);
334  }
335  }
336 
337  if ($modelValidator->countPropertyValidators()) {
339  $baseConjunctionValidator = $this->arguments->getArgument('model')->getValidator();
340  if ($baseConjunctionValidator === null) {
341  $baseConjunctionValidator = $validatorResolver->createValidator(\TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator::class);
342  $this->arguments->getArgument('model')->setValidator($baseConjunctionValidator);
343  }
344  $baseConjunctionValidator->addValidator($modelValidator);
345  }
346  }
347 }