TYPO3 CMS  TYPO3_7-6
FrontendController.php
Go to the documentation of this file.
1 <?php
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 = [];
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', []);
113  }
114  }
115 
121  protected function initializeShowAction()
122  {
123  $validationResults = $this->request->getOriginalRequestMappingResults()->forProperty('model');
124  $this->validationBuilder->buildRules();
125  if ($validationResults->hasErrors()) {
126  $this->formBuilder->setValidationErrors($validationResults);
127  }
128  }
129 
135  protected function initializeConfirmationAction()
136  {
137  $this->prepareValidations();
138  }
139 
145  protected function initializeProcessAction()
146  {
147  $this->prepareValidations();
148  }
149 
156  protected function buildControllerContext()
157  {
158  $controllerContext = ControllerContext::extend(parent::buildControllerContext())
159  ->setConfiguration($this->configuration);
160  $this->formBuilder->setControllerContext($controllerContext);
161  return $controllerContext;
162  }
163 
171  public function showAction(ValidationElement $incomingData = null)
172  {
173  if ($incomingData !== null) {
174  $this->controllerContext->setValidationElement($incomingData);
175  }
176  $form = $this->formBuilder->buildModel();
177  $this->view->assign('model', $form);
178  }
179 
187  public function confirmationAction(ValidationElement $model)
188  {
189  $this->skipForeignFormProcessing();
190 
191  if (count($model->getIncomingFields()) === 0) {
192  $this->sessionUtility->destroySession();
193  $this->forward('show');
194  }
195  $this->controllerContext->setValidationElement($model);
196  $form = $this->formBuilder->buildModel();
197  // store uploaded files
198  $this->sessionUtility->storeSession();
199  $this->view->assign('model', $form);
200 
201  $message = $this->formUtility->renderItem(
202  $this->typoscript['confirmation.']['message.'],
203  $this->typoscript['confirmation.']['message'],
204  LocalizationUtility::translate('tx_form_view_confirmation.message', 'form')
205  );
206  $this->view->assign('message', $message);
207  }
208 
216  {
217  $this->skipForeignFormProcessing();
218 
219  if ($this->request->hasArgument('confirmation-true')) {
220  $this->forward('process', null, null, [$this->configuration->getPrefix() => $this->request->getArgument('model')]);
221  } else {
222  $this->sessionUtility->destroySession();
223  $this->forward('show', null, null, ['incomingData' => $this->request->getArgument('model')]);
224  }
225  }
226 
235  public function processAction(ValidationElement $model)
236  {
237  $this->skipForeignFormProcessing();
238 
239  $this->controllerContext->setValidationElement($model);
240  $form = $this->formBuilder->buildModel();
241  $postProcessorTypoScript = [];
242  if (isset($this->typoscript['postProcessor.'])) {
243  $postProcessorTypoScript = $this->typoscript['postProcessor.'];
244  }
245 
247  $postProcessor = $this->objectManager->get(
248  \TYPO3\CMS\Form\PostProcess\PostProcessor::class,
249  $form, $postProcessorTypoScript
250  );
251  $postProcessor->setControllerContext($this->controllerContext);
252 
253  // @todo What is happening here?
254  $content = $postProcessor->process();
255  $this->sessionUtility->destroySession();
256  $this->forward('afterProcess', null, null, ['postProcessorContent' => $content]);
257  }
258 
265  public function afterProcessAction($postProcessorContent)
266  {
267  $this->view->assign('postProcessorContent', $postProcessorContent);
268  }
269 
281  protected function skipForeignFormProcessing()
282  {
283  if (
284  !$this->request->hasArgument($this->configuration->getPrefix())
285  && !$this->sessionUtility->getSessionData()
286  ) {
287  $this->forward('show');
288  }
289  }
290 
297  protected function prepareValidations()
298  {
299  if ($this->skipValidation || !$this->arguments->hasArgument('model')) {
300  return;
301  }
302 
303  $this->validationBuilder->buildRules($this->request->getArgument('model'));
304  $this->setDynamicValidation($this->validationBuilder->getRules());
305  $this->skipValidation = false;
306  }
307 
315  protected function setDynamicValidation(array $toValidate = [])
316  {
317  // build custom validation chain
319  $validatorResolver = $this->objectManager->get(\TYPO3\CMS\Extbase\Validation\ValidatorResolver::class);
320 
322  $modelValidator = $validatorResolver->createValidator(\TYPO3\CMS\Form\Domain\Validator\ValidationElementValidator::class);
323  foreach ($toValidate as $propertyName => $validations) {
324  foreach ($validations as $validation) {
325  if (empty($validation['validator'])) {
326  throw new \TYPO3\CMS\Extbase\Validation\Exception\NoSuchValidatorException('Invalid validate configuration for ' . $propertyName . ': Could not resolve class name for validator "' . $validation['validatorName'] . '".', 1441893777);
327  }
328  $modelValidator->addPropertyValidator($propertyName, $validation['validator']);
329  }
330  }
331 
332  if ($modelValidator->countPropertyValidators()) {
334  $baseConjunctionValidator = $this->arguments->getArgument('model')->getValidator();
335  if ($baseConjunctionValidator === null) {
336  $baseConjunctionValidator = $validatorResolver->createValidator(\TYPO3\CMS\Extbase\Validation\Validator\ConjunctionValidator::class);
337  $this->arguments->getArgument('model')->setValidator($baseConjunctionValidator);
338  }
339  $baseConjunctionValidator->addValidator($modelValidator);
340  }
341  }
342 }
static translate($key, $extensionName, $arguments=null)
dispatchConfirmationButtonClickAction(ValidationElement $model)
injectSessionUtility(\TYPO3\CMS\Form\Utility\SessionUtility $sessionUtility)
showAction(ValidationElement $incomingData=null)
forward($actionName, $controllerName=null, $extensionName=null, array $arguments=null)
static extend(\TYPO3\CMS\Extbase\Mvc\Controller\ControllerContext $source)