[TASK] Use arrays in str_replace() calls
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Mvc / Controller / ActionController.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Mvc\Controller;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2010-2013 Extbase Team (http://forge.typo3.org/projects/typo3v4-mvc)
8 * Extbase is a backport of TYPO3 Flow. All credits go to the TYPO3 Flow team.
9 * All rights reserved
10 *
11 * This script is part of the TYPO3 project. The TYPO3 project is
12 * free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * The GNU General Public License can be found at
18 * http://www.gnu.org/copyleft/gpl.html.
19 * A copy is found in the textfile GPL.txt and important notices to the license
20 * from the author is found in LICENSE.txt distributed with these scripts.
21 *
22 *
23 * This script is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * This copyright notice MUST APPEAR in all copies of the script!
29 ***************************************************************/
30 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
31 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
32
33 /**
34 * A multi action controller. This is by far the most common base class for Controllers.
35 *
36 * @api
37 */
38 class ActionController extends \TYPO3\CMS\Extbase\Mvc\Controller\AbstractController {
39
40 /**
41 * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
42 * @inject
43 */
44 protected $reflectionService;
45
46 /**
47 * @var \TYPO3\CMS\Extbase\Service\CacheService
48 * @inject
49 */
50 protected $cacheService;
51
52 /**
53 * The current view, as resolved by resolveView()
54 *
55 * @var ViewInterface
56 * @api
57 */
58 protected $view = NULL;
59
60 /**
61 * Pattern after which the view object name is built if no Fluid template
62 * is found.
63 *
64 * @var string
65 * @api
66 * @deprecated since Extbase 6.2, will be removed two versions later
67 */
68 protected $viewObjectNamePattern = 'Tx_@extension_View_@controller_@action@format';
69
70 /**
71 * @var string
72 * @api
73 */
74 protected $namespacesViewObjectNamePattern = '@vendor\@extension\View\@controller\@action@format';
75
76 /**
77 * A list of formats and object names of the views which should render them.
78 *
79 * Example:
80 *
81 * array('html' => 'Tx_MyExtension_View_MyHtmlView', 'json' => 'F3...
82 *
83 * @var array
84 */
85 protected $viewFormatToObjectNameMap = array();
86
87 /**
88 * The default view object to use if none of the resolved views can render
89 * a response for the current request.
90 *
91 * @var string
92 * @api
93 */
94 protected $defaultViewObjectName = 'TYPO3\\CMS\\Fluid\\View\\TemplateView';
95
96 /**
97 * Name of the action method
98 *
99 * @var string
100 * @api
101 */
102 protected $actionMethodName = 'indexAction';
103
104 /**
105 * Name of the special error action method which is called in case of errors
106 *
107 * @var string
108 * @api
109 */
110 protected $errorMethodName = 'errorAction';
111
112 /**
113 * @var \TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService
114 * @inject
115 * @api
116 */
117 protected $mvcPropertyMappingConfigurationService;
118
119 /**
120 * Checks if the current request type is supported by the controller.
121 *
122 * If your controller only supports certain request types, either
123 * replace / modify the supporteRequestTypes property or override this
124 * method.
125 *
126 * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The current request
127 *
128 * @return boolean TRUE if this request type is supported, otherwise FALSE
129 */
130 public function canProcessRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request) {
131 return parent::canProcessRequest($request);
132 }
133
134 /**
135 * Handles a request. The result output is returned by altering the given response.
136 *
137 * @param \TYPO3\CMS\Extbase\Mvc\RequestInterface $request The request object
138 * @param \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response The response, modified by this handler
139 *
140 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException
141 * @return void
142 */
143 public function processRequest(\TYPO3\CMS\Extbase\Mvc\RequestInterface $request, \TYPO3\CMS\Extbase\Mvc\ResponseInterface $response) {
144 if (!$this->canProcessRequest($request)) {
145 throw new \TYPO3\CMS\Extbase\Mvc\Exception\UnsupportedRequestTypeException(get_class($this) . ' does not support requests of type "' . get_class($request) . '". Supported types are: ' . implode(' ', $this->supportedRequestTypes), 1187701131);
146 }
147 if ($response instanceof \TYPO3\CMS\Extbase\Mvc\Web\Response) {
148 $response->setRequest($request);
149 }
150 $this->request = $request;
151 $this->request->setDispatched(TRUE);
152 $this->response = $response;
153 $this->uriBuilder = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Mvc\\Web\\Routing\\UriBuilder');
154 $this->uriBuilder->setRequest($request);
155 $this->actionMethodName = $this->resolveActionMethodName();
156 $this->initializeActionMethodArguments();
157 $this->initializeActionMethodValidators();
158 $this->mvcPropertyMappingConfigurationService->initializePropertyMappingConfigurationFromRequest($request, $this->arguments);
159 $this->initializeAction();
160 $actionInitializationMethodName = 'initialize' . ucfirst($this->actionMethodName);
161 if (method_exists($this, $actionInitializationMethodName)) {
162 call_user_func(array($this, $actionInitializationMethodName));
163 }
164 $this->mapRequestArgumentsToControllerArguments();
165 $this->checkRequestHash();
166 $this->controllerContext = $this->buildControllerContext();
167 $this->view = $this->resolveView();
168 if ($this->view !== NULL) {
169 $this->initializeView($this->view);
170 }
171 $this->callActionMethod();
172 }
173
174 /**
175 * Implementation of the arguments initilization in the action controller:
176 * Automatically registers arguments of the current action
177 *
178 * Don't override this method - use initializeAction() instead.
179 *
180 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException
181 * @return void
182 * @see initializeArguments()
183 */
184 protected function initializeActionMethodArguments() {
185 $methodParameters = $this->reflectionService->getMethodParameters(get_class($this), $this->actionMethodName);
186 foreach ($methodParameters as $parameterName => $parameterInfo) {
187 $dataType = NULL;
188 if (isset($parameterInfo['type'])) {
189 $dataType = $parameterInfo['type'];
190 } elseif ($parameterInfo['array']) {
191 $dataType = 'array';
192 }
193 if ($dataType === NULL) {
194 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentTypeException('The argument type for parameter $' . $parameterName . ' of method ' . get_class($this) . '->' . $this->actionMethodName . '() could not be detected.', 1253175643);
195 }
196 $defaultValue = isset($parameterInfo['defaultValue']) ? $parameterInfo['defaultValue'] : NULL;
197 $this->arguments->addNewArgument($parameterName, $dataType, $parameterInfo['optional'] === FALSE, $defaultValue);
198 }
199 }
200
201 /**
202 * Adds the needed validators to the Arguments:
203 *
204 * - Validators checking the data type from the @param annotation
205 * - Custom validators specified with validate annotations.
206 * - Model-based validators (validate annotations in the model)
207 * - Custom model validator classes
208 *
209 * @return void
210 */
211 protected function initializeActionMethodValidators() {
212
213 if (!$this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper')) {
214 // @deprecated since Extbase 1.4.0, will be removed two versions after Extbase 6.1
215
216 $parameterValidators = $this->validatorResolver->buildMethodArgumentsValidatorConjunctions(get_class($this), $this->actionMethodName);
217 $dontValidateAnnotations = array();
218
219 $methodTagsValues = $this->reflectionService->getMethodTagsValues(get_class($this), $this->actionMethodName);
220 if (isset($methodTagsValues['dontvalidate'])) {
221 $dontValidateAnnotations = $methodTagsValues['dontvalidate'];
222 }
223
224 foreach ($this->arguments as $argument) {
225 $validator = $parameterValidators[$argument->getName()];
226 if (array_search('$' . $argument->getName(), $dontValidateAnnotations) === FALSE) {
227 $baseValidatorConjunction = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
228 if ($baseValidatorConjunction !== NULL) {
229 $validator->addValidator($baseValidatorConjunction);
230 }
231 }
232 $argument->setValidator($validator);
233 }
234 } else {
235 /**
236 * @todo: add validation group support
237 * (https://review.typo3.org/#/c/13556/4)
238 */
239
240 $actionMethodParameters = static::getActionMethodParameters($this->objectManager);
241 if (isset($actionMethodParameters[$this->actionMethodName])) {
242 $methodParameters = $actionMethodParameters[$this->actionMethodName];
243 } else {
244 $methodParameters = array();
245 }
246
247 /**
248 * @todo: add resolving of $actionValidateAnnotations and pass them to
249 * buildMethodArgumentsValidatorConjunctions as in TYPO3.Flow
250 */
251
252 $parameterValidators = $this->validatorResolver->buildMethodArgumentsValidatorConjunctions(get_class($this), $this->actionMethodName, $methodParameters);
253
254 foreach ($this->arguments as $argument) {
255 $validator = $parameterValidators[$argument->getName()];
256
257 $baseValidatorConjunction = $this->validatorResolver->getBaseValidatorConjunction($argument->getDataType());
258 if (count($baseValidatorConjunction) > 0) {
259 $validator->addValidator($baseValidatorConjunction);
260 }
261 $argument->setValidator($validator);
262 }
263 }
264 }
265
266 /**
267 * Resolves and checks the current action method name
268 *
269 * @return string Method name of the current action
270 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException if the action specified in the request object does not exist (and if there's no default action either).
271 */
272 protected function resolveActionMethodName() {
273 $actionMethodName = $this->request->getControllerActionName() . 'Action';
274 if (!method_exists($this, $actionMethodName)) {
275 throw new \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchActionException('An action "' . $actionMethodName . '" does not exist in controller "' . get_class($this) . '".', 1186669086);
276 }
277 return $actionMethodName;
278 }
279
280 /**
281 * Calls the specified action method and passes the arguments.
282 *
283 * If the action returns a string, it is appended to the content in the
284 * response object. If the action doesn't return anything and a valid
285 * view exists, the view is rendered automatically.
286 *
287 * @return void
288 * @api
289 */
290 protected function callActionMethod() {
291 if ($this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper')) {
292 // enabled since Extbase 1.4.0.
293 $preparedArguments = array();
294 foreach ($this->arguments as $argument) {
295 $preparedArguments[] = $argument->getValue();
296 }
297 $validationResult = $this->arguments->getValidationResults();
298 if (!$validationResult->hasErrors()) {
299 $this->signalSlotDispatcher->dispatch(__CLASS__, 'beforeCallActionMethod', array('controllerName' => get_class($this), 'actionMethodName' => $this->actionMethodName, 'preparedArguments' => $preparedArguments));
300 $actionResult = call_user_func_array(array($this, $this->actionMethodName), $preparedArguments);
301 } else {
302 $methodTagsValues = $this->reflectionService->getMethodTagsValues(get_class($this), $this->actionMethodName);
303 $ignoreValidationAnnotations = array();
304 if (isset($methodTagsValues['ignorevalidation'])) {
305 $ignoreValidationAnnotations = $methodTagsValues['ignorevalidation'];
306 }
307 // if there exists more errors than in ignoreValidationAnnotations_=> call error method
308 // else => call action method
309 $shouldCallActionMethod = TRUE;
310 foreach ($validationResult->getSubResults() as $argumentName => $subValidationResult) {
311 if (!$subValidationResult->hasErrors()) {
312 continue;
313 }
314 if (array_search('$' . $argumentName, $ignoreValidationAnnotations) !== FALSE) {
315 continue;
316 }
317 $shouldCallActionMethod = FALSE;
318 }
319 if ($shouldCallActionMethod) {
320 $this->signalSlotDispatcher->dispatch(__CLASS__, 'beforeCallActionMethod', array('controllerName' => get_class($this), 'actionMethodName' => $this->actionMethodName, 'preparedArguments' => $preparedArguments));
321 $actionResult = call_user_func_array(array($this, $this->actionMethodName), $preparedArguments);
322 } else {
323 $actionResult = call_user_func(array($this, $this->errorMethodName));
324 }
325 }
326 } else {
327 // @deprecated since Extbase 1.4.0, will be removed two versions after Extbase 6.1
328 $preparedArguments = array();
329 foreach ($this->arguments as $argument) {
330 $preparedArguments[] = $argument->getValue();
331 }
332 if ($this->argumentsMappingResults->hasErrors()) {
333 $actionResult = call_user_func(array($this, $this->errorMethodName));
334 } else {
335 $this->signalSlotDispatcher->dispatch(__CLASS__, 'beforeCallActionMethod', array('controllerName' => get_class($this), 'actionMethodName' => $this->actionMethodName, 'preparedArguments' => $preparedArguments));
336 $actionResult = call_user_func_array(array($this, $this->actionMethodName), $preparedArguments);
337 }
338 }
339 if ($actionResult === NULL && $this->view instanceof ViewInterface) {
340 $this->response->appendContent($this->view->render());
341 } elseif (is_string($actionResult) && strlen($actionResult) > 0) {
342 $this->response->appendContent($actionResult);
343 } elseif (is_object($actionResult) && method_exists($actionResult, '__toString')) {
344 $this->response->appendContent((string)$actionResult);
345 }
346 }
347
348 /**
349 * Prepares a view for the current action and stores it in $this->view.
350 * By default, this method tries to locate a view with a name matching
351 * the current action.
352 *
353 * @return string
354 * @api
355 */
356 protected function resolveView() {
357 $viewObjectName = $this->resolveViewObjectName();
358 if ($viewObjectName !== FALSE) {
359 /** @var $view ViewInterface */
360 $view = $this->objectManager->get($viewObjectName);
361 $this->setViewConfiguration($view);
362 if ($view->canRender($this->controllerContext) === FALSE) {
363 unset($view);
364 }
365 }
366 if (!isset($view) && $this->defaultViewObjectName != '') {
367 /** @var $view ViewInterface */
368 $view = $this->objectManager->get($this->defaultViewObjectName);
369 $this->setViewConfiguration($view);
370 if ($view->canRender($this->controllerContext) === FALSE) {
371 unset($view);
372 }
373 }
374 if (!isset($view)) {
375 $view = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Mvc\\View\\NotFoundView');
376 $view->assign('errorMessage', 'No template was found. View could not be resolved for action "'
377 . $this->request->getControllerActionName() . '" in class "' . $this->request->getControllerObjectName() . '"');
378 }
379 $view->setControllerContext($this->controllerContext);
380 if (method_exists($view, 'injectSettings')) {
381 $view->injectSettings($this->settings);
382 }
383 $view->initializeView();
384 // In FLOW3, solved through Object Lifecycle methods, we need to call it explicitely
385 $view->assign('settings', $this->settings);
386 // same with settings injection.
387 return $view;
388 }
389
390 /**
391 * @param ViewInterface $view
392 *
393 * @return void
394 */
395 protected function setViewConfiguration(ViewInterface $view) {
396 // Template Path Override
397 $extbaseFrameworkConfiguration = $this->configurationManager->getConfiguration(
398 ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK
399 );
400
401 // set TemplateRootPaths
402 $viewFunctionName = 'setTemplateRootPaths';
403 if (method_exists($view, $viewFunctionName)) {
404 $deprecatedSetting = 'templateRootPath';
405 $setting = 'templateRootPaths';
406 $parameter = $this->getViewProperty($extbaseFrameworkConfiguration, $setting, $deprecatedSetting);
407 // no need to bother if there is nothing to set
408 if ($parameter) {
409 $view->$viewFunctionName($parameter);
410 }
411 }
412
413 // set LayoutRootPaths
414 $viewFunctionName = 'setLayoutRootPaths';
415 if (method_exists($view, $viewFunctionName)) {
416 $deprecatedSetting = 'layoutRootPath';
417 $setting = 'layoutRootPaths';
418 $parameter = $this->getViewProperty($extbaseFrameworkConfiguration, $setting, $deprecatedSetting);
419 // no need to bother if there is nothing to set
420 if ($parameter) {
421 $view->$viewFunctionName($parameter);
422 }
423 }
424
425 // set PartialRootPaths
426 $viewFunctionName = 'setPartialRootPaths';
427 if (method_exists($view, $viewFunctionName)) {
428 $deprecatedSetting = 'partialRootPath';
429 $setting = 'partialRootPaths';
430 $parameter = $this->getViewProperty($extbaseFrameworkConfiguration, $setting, $deprecatedSetting);
431 // no need to bother if there is nothing to set
432 if ($parameter) {
433 $view->$viewFunctionName($parameter);
434 }
435 }
436 }
437
438 /**
439 * Handles the path resolving for *rootPath(s)
440 * singular one is deprecated and will be removed two versions after 6.2
441 * if deprecated setting is found, use it as the very last fallback target
442 *
443 * numerical arrays get ordered by key ascending
444 *
445 * @param array $extbaseFrameworkConfiguration
446 * @param string $setting parameter name from TypoScript
447 * @param string $deprecatedSetting parameter name from TypoScript
448 *
449 * @return array
450 */
451 protected function getViewProperty($extbaseFrameworkConfiguration, $setting, $deprecatedSetting = '') {
452
453 $values = array();
454
455 if (
456 !empty($extbaseFrameworkConfiguration['view'][$setting])
457 && is_array($extbaseFrameworkConfiguration['view'][$setting])
458 ) {
459 $values = \TYPO3\CMS\Extbase\Utility\ArrayUtility::sortArrayWithIntegerKeys($extbaseFrameworkConfiguration['view'][$setting]);
460 $values = array_reverse($values, TRUE);
461 }
462
463 // @todo remove handling of deprecatedSetting two versions after 6.2
464 if (
465 isset($extbaseFrameworkConfiguration['view'][$deprecatedSetting])
466 && strlen($extbaseFrameworkConfiguration['view'][$deprecatedSetting]) > 0
467 ) {
468 $values[] = $extbaseFrameworkConfiguration['view'][$deprecatedSetting];
469 }
470
471 return $values;
472 }
473
474 /**
475 * Determines the fully qualified view object name.
476 *
477 * @return mixed The fully qualified view object name or FALSE if no matching view could be found.
478 * @api
479 */
480 protected function resolveViewObjectName() {
481 $vendorName = $this->request->getControllerVendorName();
482
483 if ($vendorName !== NULL) {
484 $possibleViewName = str_replace('@vendor', $vendorName, $this->namespacesViewObjectNamePattern);
485 } else {
486 $possibleViewName = $this->viewObjectNamePattern;
487 }
488
489 $possibleViewName = str_replace(
490 array(
491 '@extension',
492 '@controller',
493 '@action'
494 ),
495 array(
496 $this->request->getControllerExtensionName(),
497 $this->request->getControllerName(),
498 ucfirst($this->request->getControllerActionName())
499 ),
500 $possibleViewName
501 );
502 $format = $this->request->getFormat();
503 $viewObjectName = str_replace('@format', ucfirst($format), $possibleViewName);
504 if (class_exists($viewObjectName) === FALSE) {
505 $viewObjectName = str_replace('@format', '', $possibleViewName);
506 }
507 if (isset($this->viewFormatToObjectNameMap[$format]) && class_exists($viewObjectName) === FALSE) {
508 $viewObjectName = $this->viewFormatToObjectNameMap[$format];
509 }
510 return class_exists($viewObjectName) ? $viewObjectName : FALSE;
511 }
512
513 /**
514 * Initializes the view before invoking an action method.
515 *
516 * Override this method to solve assign variables common for all actions
517 * or prepare the view in another way before the action is called.
518 *
519 * @param ViewInterface $view The view to be initialized
520 *
521 * @return void
522 * @api
523 */
524 protected function initializeView(ViewInterface $view) {
525 }
526
527 /**
528 * Initializes the controller before invoking an action method.
529 *
530 * Override this method to solve tasks which all actions have in
531 * common.
532 *
533 * @return void
534 * @api
535 */
536 protected function initializeAction() {
537 }
538
539 /**
540 * A special action which is called if the originally intended action could
541 * not be called, for example if the arguments were not valid.
542 *
543 * The default implementation sets a flash message, request errors and forwards back
544 * to the originating action. This is suitable for most actions dealing with form input.
545 *
546 * We clear the page cache by default on an error as well, as we need to make sure the
547 * data is re-evaluated when the user changes something.
548 *
549 * @return string
550 * @api
551 */
552 protected function errorAction() {
553 $this->clearCacheOnError();
554 if ($this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper')) {
555 $errorFlashMessage = $this->getErrorFlashMessage();
556 if ($errorFlashMessage !== FALSE) {
557 $errorFlashMessageObject = new \TYPO3\CMS\Core\Messaging\FlashMessage(
558 $errorFlashMessage,
559 '',
560 \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
561 );
562 $this->controllerContext->getFlashMessageQueue()->enqueue($errorFlashMessageObject);
563 }
564 $referringRequest = $this->request->getReferringRequest();
565 if ($referringRequest !== NULL) {
566 $originalRequest = clone $this->request;
567 $this->request->setOriginalRequest($originalRequest);
568 $this->request->setOriginalRequestMappingResults($this->arguments->getValidationResults());
569 $this->forward($referringRequest->getControllerActionName(), $referringRequest->getControllerName(), $referringRequest->getControllerExtensionName(), $referringRequest->getArguments());
570 }
571 $message = 'An error occurred while trying to call ' . get_class($this) . '->' . $this->actionMethodName . '().' . PHP_EOL;
572 return $message;
573 } else {
574 // @deprecated since Extbase 1.4.0, will be removed two versions after Extbase 6.1
575 $this->request->setErrors($this->argumentsMappingResults->getErrors());
576 $errorFlashMessage = $this->getErrorFlashMessage();
577 if ($errorFlashMessage !== FALSE) {
578 $errorFlashMessageObject = new \TYPO3\CMS\Core\Messaging\FlashMessage(
579 $errorFlashMessage,
580 '',
581 \TYPO3\CMS\Core\Messaging\FlashMessage::ERROR
582 );
583 $this->controllerContext->getFlashMessageQueue()->enqueue($errorFlashMessageObject);
584 }
585 $referrer = $this->request->getInternalArgument('__referrer');
586 if ($referrer !== NULL) {
587 $this->forward($referrer['actionName'], $referrer['controllerName'], $referrer['extensionName'], $this->request->getArguments());
588 }
589 $message = 'An error occurred while trying to call ' . get_class($this) . '->' . $this->actionMethodName . '().' . PHP_EOL;
590 return $message;
591 }
592 }
593
594 /**
595 * A template method for displaying custom error flash messages, or to
596 * display no flash message at all on errors. Override this to customize
597 * the flash message in your action controller.
598 *
599 * @return string The flash message or FALSE if no flash message should be set
600 * @api
601 */
602 protected function getErrorFlashMessage() {
603 return 'An error occurred while trying to call ' . get_class($this) . '->' . $this->actionMethodName . '()';
604 }
605
606 /**
607 * Checks the request hash (HMAC), if arguments have been touched by the property mapper.
608 *
609 * In case the @dontverifyrequesthash-Annotation has been set, this suppresses the exception.
610 *
611 * @return void
612 * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidOrNoRequestHashException In case request hash checking failed
613 * @deprecated since Extbase 1.4.0, will be removed two versions after Extbase 6.1
614 */
615 protected function checkRequestHash() {
616 if ($this->configurationManager->isFeatureEnabled('rewrittenPropertyMapper')) {
617 // If the new property mapper is enabled, the request hash is not needed anymore.
618 return;
619 }
620 if (!$this->request instanceof \TYPO3\CMS\Extbase\Mvc\Web\Request) {
621 return;
622 }
623 // We only want to check it for now for web requests.
624 if ($this->request->isHmacVerified()) {
625 return;
626 }
627 // all good
628 $verificationNeeded = FALSE;
629 foreach ($this->arguments as $argument) {
630 if ($argument->getOrigin() == \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_NEWLY_CREATED || $argument->getOrigin() == \TYPO3\CMS\Extbase\Mvc\Controller\Argument::ORIGIN_PERSISTENCE_AND_MODIFIED) {
631 $verificationNeeded = TRUE;
632 }
633 }
634 if ($verificationNeeded) {
635 $methodTagsValues = $this->reflectionService->getMethodTagsValues(get_class($this), $this->actionMethodName);
636 if (!isset($methodTagsValues['dontverifyrequesthash'])) {
637 throw new \TYPO3\CMS\Extbase\Mvc\Exception\InvalidOrNoRequestHashException('Request hash (HMAC) checking failed. The parameter __hmac was invalid or not set, and objects were modified.', 1255082824);
638 }
639 }
640 }
641
642 /**
643 * Clear cache of current page on error. Needed because we want a re-evaluation of the data.
644 * Better would be just do delete the cache for the error action, but that is not possible right now.
645 *
646 * @return void
647 */
648 protected function clearCacheOnError() {
649 $extbaseSettings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
650 if (isset($extbaseSettings['persistence']['enableAutomaticCacheClearing']) && $extbaseSettings['persistence']['enableAutomaticCacheClearing'] === '1') {
651 if (isset($GLOBALS['TSFE'])) {
652 $pageUid = $GLOBALS['TSFE']->id;
653 $this->cacheService->clearPageCache(array($pageUid));
654 }
655 }
656 }
657
658 /**
659 * Returns a map of action method names and their parameters.
660 *
661 * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager
662 *
663 * @return array Array of method parameters by action name
664 */
665 static public function getActionMethodParameters($objectManager) {
666 $reflectionService = $objectManager->get('TYPO3\CMS\Extbase\Reflection\ReflectionService');
667
668 $result = array();
669
670 $className = get_called_class();
671 $methodNames = get_class_methods($className);
672 foreach ($methodNames as $methodName) {
673 if (strlen($methodName) > 6 && strpos($methodName, 'Action', strlen($methodName) - 6) !== FALSE) {
674 $result[$methodName] = $reflectionService->getMethodParameters($className, $methodName);
675 }
676 }
677
678 return $result;
679 }
680 }