[TASK] Decouple responsibilities in default errorAction() 44/26944/6
authorHelmut Hummel <helmut.hummel@typo3.org>
Thu, 18 Dec 2014 09:48:38 +0000 (10:48 +0100)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Sat, 20 Dec 2014 09:46:01 +0000 (10:46 +0100)
The default Extbase ActionController::errorAction does a lot
of different things, which makes it hard to customize a controller
to a desired behavior without copying all or some of its code.

Extracting the different responsibilities to separate methods
simplifies such customizations.

Resolves: #55178
Releases: master
Change-Id: I324a504c745649eec11eec65d4e6a718a5e434bd
Reviewed-on: http://review.typo3.org/26944
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php

index efd1efa..5ac3579 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Extbase\Mvc\Controller;
 
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
+use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
 use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
 use TYPO3\CMS\Extbase\Mvc\Web\Request as WebRequest;
 use TYPO3\CMS\Extbase\Utility\ArrayUtility;
@@ -489,24 +490,39 @@ class ActionController extends AbstractController {
         */
        protected function errorAction() {
                $this->clearCacheOnError();
+               $this->addErrorFlashMessage();
+               $this->forwardToReferringRequest();
+
+               return $this->getFlattenedValidationErrorMessage();
+       }
+
+       /**
+        * Clear cache of current page on error. Needed because we want a re-evaluation of the data.
+        * Better would be just do delete the cache for the error action, but that is not possible right now.
+        *
+        * @return void
+        */
+       protected function clearCacheOnError() {
+               $extbaseSettings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
+               if (isset($extbaseSettings['persistence']['enableAutomaticCacheClearing']) && $extbaseSettings['persistence']['enableAutomaticCacheClearing'] === '1') {
+                       if (isset($GLOBALS['TSFE'])) {
+                               $pageUid = $GLOBALS['TSFE']->id;
+                               $this->cacheService->clearPageCache(array($pageUid));
+                       }
+               }
+       }
+
+       /**
+        * If an error occurred during this request, this adds a flash message describing the error to the flash
+        * message container.
+        *
+        * @return void
+        */
+       protected function addErrorFlashMessage() {
                $errorFlashMessage = $this->getErrorFlashMessage();
                if ($errorFlashMessage !== FALSE) {
-                       $errorFlashMessageObject = new FlashMessage(
-                               $errorFlashMessage,
-                               '',
-                               FlashMessage::ERROR
-                       );
-                       $this->controllerContext->getFlashMessageQueue()->enqueue($errorFlashMessageObject);
+                       $this->addFlashMessage($errorFlashMessage, '', FlashMessage::ERROR);
                }
-               $referringRequest = $this->request->getReferringRequest();
-               if ($referringRequest !== NULL) {
-                       $originalRequest = clone $this->request;
-                       $this->request->setOriginalRequest($originalRequest);
-                       $this->request->setOriginalRequestMappingResults($this->arguments->getValidationResults());
-                       $this->forward($referringRequest->getControllerActionName(), $referringRequest->getControllerName(), $referringRequest->getControllerExtensionName(), $referringRequest->getArguments());
-               }
-               $message = 'An error occurred while trying to call ' . get_class($this) . '->' . $this->actionMethodName . '().' . PHP_EOL;
-               return $message;
        }
 
        /**
@@ -522,22 +538,41 @@ class ActionController extends AbstractController {
        }
 
        /**
-        * Clear cache of current page on error. Needed because we want a re-evaluation of the data.
-        * Better would be just do delete the cache for the error action, but that is not possible right now.
+        * If information on the request before the current request was sent, this method forwards back
+        * to the originating request. This effectively ends processing of the current request, so do not
+        * call this method before you have finished the necessary business logic!
         *
         * @return void
+        * @throws StopActionException
         */
-       protected function clearCacheOnError() {
-               $extbaseSettings = $this->configurationManager->getConfiguration(ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
-               if (isset($extbaseSettings['persistence']['enableAutomaticCacheClearing']) && $extbaseSettings['persistence']['enableAutomaticCacheClearing'] === '1') {
-                       if (isset($GLOBALS['TSFE'])) {
-                               $pageUid = $GLOBALS['TSFE']->id;
-                               $this->cacheService->clearPageCache(array($pageUid));
-                       }
+       protected function forwardToReferringRequest() {
+               $referringRequest = $this->request->getReferringRequest();
+               if ($referringRequest !== NULL) {
+                       $originalRequest = clone $this->request;
+                       $this->request->setOriginalRequest($originalRequest);
+                       $this->request->setOriginalRequestMappingResults($this->arguments->getValidationResults());
+                       $this->forward(
+                               $referringRequest->getControllerActionName(),
+                               $referringRequest->getControllerName(),
+                               $referringRequest->getControllerExtensionName(),
+                               $referringRequest->getArguments()
+                       );
                }
        }
 
        /**
+        * Returns a string with a basic error message about validation failure.
+        * We may add all validation error messages to a log file in the future,
+        * but for security reasons (@see #54074) we do not return these here.
+        *
+        * @return string
+        */
+       protected function getFlattenedValidationErrorMessage() {
+               $outputMessage = 'Validation failed while trying to call ' . get_class($this) . '->' . $this->actionMethodName . '().' . PHP_EOL;
+               return $outputMessage;
+       }
+
+       /**
         * Returns a map of action method names and their parameters.
         *
         * @param \TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager