[FEATURE] Render Error Pages via Fluid 48/47448/12
authorBenni Mack <benni@typo3.org>
Thu, 31 Mar 2016 05:35:26 +0000 (07:35 +0200)
committerAnja Leichsenring <aleichsenring@ab-softlab.de>
Wed, 3 Aug 2016 12:58:45 +0000 (14:58 +0200)
A new class called "ErrorPageController" is introduced
which sets up a Fluid standalone view to render the
actual error page as a Fluid template, instead of the
old marker-based approach, as the end of the marker-based
templates is near.

The ErrorpageMessage and AbstractStandaloneMessage
classes are deprecated now.

Resolves: #77164
Releases: master
Change-Id: Ib04c7b4d782671e7670af1d97d9f85247f235862
Reviewed-on: https://review.typo3.org/47448
Tested-by: Bamboo TYPO3com <info@typo3.com>
Reviewed-by: Susanne Moog <susanne.moog@typo3.org>
Tested-by: Susanne Moog <susanne.moog@typo3.org>
Reviewed-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: Anja Leichsenring <aleichsenring@ab-softlab.de>
typo3/sysext/core/Classes/Controller/ErrorPageController.php [new file with mode: 0644]
typo3/sysext/core/Classes/Error/ProductionExceptionHandler.php
typo3/sysext/core/Classes/Messaging/AbstractStandaloneMessage.php
typo3/sysext/core/Classes/Messaging/ErrorpageMessage.php
typo3/sysext/core/Documentation/Changelog/master/Deprecation-77164-ErrorpageMessageAndAbstractStandaloneMessage.rst [new file with mode: 0644]
typo3/sysext/core/Resources/Private/Templates/ErrorPage/Error.html [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Mail/MailerTest.php
typo3/sysext/frontend/Classes/Controller/TypoScriptFrontendController.php

diff --git a/typo3/sysext/core/Classes/Controller/ErrorPageController.php b/typo3/sysext/core/Classes/Controller/ErrorPageController.php
new file mode 100644 (file)
index 0000000..831ae92
--- /dev/null
@@ -0,0 +1,94 @@
+<?php
+declare (strict_types = 1);
+namespace TYPO3\CMS\Core\Controller;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Messaging\AbstractMessage;
+use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\PathUtility;
+use TYPO3Fluid\Fluid\Core\Rendering\RenderingContext;
+use TYPO3Fluid\Fluid\View\TemplatePaths;
+use TYPO3Fluid\Fluid\View\TemplateView;
+
+/**
+ * A class representing error messages shown on a page, rendered via fluid.
+ * Classic Example: "No pages are found on rootlevel"
+ */
+class ErrorPageController
+{
+    /**
+     * The view object
+     * @var TemplateView
+     */
+    protected $view;
+
+    /**
+     * The severity level
+     * @var int
+     */
+    protected $severity = AbstractMessage::ERROR;
+
+    /**
+     * Sets up the view
+     */
+    public function __construct()
+    {
+        $this->view = GeneralUtility::makeInstance(TemplateView::class);
+        $context = new RenderingContext($this->view);
+        $context->setControllerName('ErrorPage');
+        $context->setTemplatePaths(new TemplatePaths([
+            'templateRootPaths' => [
+                ExtensionManagementUtility::extPath('core', 'Resources/Private/Templates/ErrorPage/')
+            ]
+        ]));
+        $this->view->setRenderingContext($context);
+    }
+
+    /**
+     * Renders the view and returns the content
+     *
+     * @param string $title The title to be shown
+     * @param string $message The message to be shown
+     * @param int $severity The severity of the error, see AbstractMessage constants
+     * @param int $errorCode The error code to be referenced
+     * @return string the output of the view
+     */
+    public function errorAction(
+        string $title,
+        string $message,
+        int $severity = AbstractMessage::ERROR,
+        int $errorCode = 0): string
+    {
+        $this->severity = $severity;
+        $classes = [
+            AbstractMessage::NOTICE => 'notice',
+            AbstractMessage::INFO => 'information',
+            AbstractMessage::OK => 'ok',
+            AbstractMessage::WARNING => 'warning',
+            AbstractMessage::ERROR => 'error'
+        ];
+        $this->view->assign('severityCssClass', $classes[$this->severity]);
+        $this->view->assign('severity', $this->severity);
+        $this->view->assign('message', $message);
+        $this->view->assign('title', $title);
+        $this->view->assign('errorCodeUrlPrefix', TYPO3_URL_EXCEPTION);
+        $this->view->assign('errorCode', $errorCode);
+        $this->view->assign('logo', PathUtility::getAbsoluteWebPath(ExtensionManagementUtility::extPath('backend', 'Resources/Public/Images/typo3_orange.svg')));
+        $this->view->assign('cssFile', PathUtility::getAbsoluteWebPath(ExtensionManagementUtility::extPath('core', 'Resources/Public/Css/errorpage.css')));
+        $this->view->assign('copyrightYear', TYPO3_copyright_year);
+        return $this->view->render('Error');
+    }
+}
index b90a013..2f6f780 100644 (file)
@@ -13,6 +13,9 @@ namespace TYPO3\CMS\Core\Error;
  *
  * The TYPO3 project - inspiring people to share!
  */
+use TYPO3\CMS\Core\Controller\ErrorPageController;
+use TYPO3\CMS\Core\Messaging\AbstractMessage;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * A quite exception handler which catches but ignores any exception.
@@ -53,12 +56,12 @@ class ProductionExceptionHandler extends AbstractExceptionHandler
     {
         $this->sendStatusHeaders($exception);
         $this->writeLogEntries($exception, self::CONTEXT_WEB);
-        $messageObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
-            \TYPO3\CMS\Core\Messaging\ErrorpageMessage::class,
+        echo GeneralUtility::makeInstance(ErrorPageController::class)->errorAction(
+            $this->getTitle($exception),
             $this->getMessage($exception),
-            $this->getTitle($exception)
+            AbstractMessage::ERROR,
+            $this->discloseExceptionInformation($exception) ? $exception->getCode() : 0
         );
-        $messageObj->output();
     }
 
     /**
@@ -113,7 +116,7 @@ class ProductionExceptionHandler extends AbstractExceptionHandler
     protected function getTitle(\Throwable $exception)
     {
         if ($this->discloseExceptionInformation($exception) && method_exists($exception, 'getTitle') && $exception->getTitle() !== '') {
-            return htmlspecialchars($exception->getTitle());
+            return $exception->getTitle();
         } else {
             return $this->defaultTitle;
         }
@@ -128,14 +131,7 @@ class ProductionExceptionHandler extends AbstractExceptionHandler
     protected function getMessage(\Throwable $exception)
     {
         if ($this->discloseExceptionInformation($exception)) {
-            // Exception has an error code given
-            if ($exception->getCode() > 0) {
-                $moreInformationLink = '<p>More information regarding this error might be available <a href="'
-                    . TYPO3_URL_EXCEPTION . $exception->getCode() . '" target="_blank">online</a>.</p>';
-            } else {
-                $moreInformationLink = '';
-            }
-            return htmlspecialchars($exception->getMessage()) . $moreInformationLink;
+            return $exception->getMessage();
         } else {
             return $this->defaultMessage;
         }
index 268aa47..f8fc466 100644 (file)
@@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * Abstract class as base for standalone messages (error pages etc.)
+ * This class is deprecated since TYPO3 v8 in favor of the ErrorPageController, and will be removed in TYPO3 v9
  */
 abstract class AbstractStandaloneMessage extends AbstractMessage
 {
@@ -49,9 +50,11 @@ abstract class AbstractStandaloneMessage extends AbstractMessage
      * @param string $message Message
      * @param string $title Title
      * @param int $severity Severity, see class constants of AbstractMessage
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use the ErrorPageController instead
      */
     public function __construct($message = '', $title = '', $severity = AbstractMessage::ERROR)
     {
+        GeneralUtility::logDeprecatedFunction();
         if (!empty($message)) {
             $this->setMessage($message);
         }
index 73609e8..cd40bf1 100644 (file)
@@ -14,10 +14,12 @@ namespace TYPO3\CMS\Core\Messaging;
  * The TYPO3 project - inspiring people to share!
  */
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
  * A class representing error messages shown on a page.
  * Classic Example: "No pages are found on rootlevel"
+ * This class is deprecated since TYPO3 v8 in favor of the ErrorPageController, and will be removed in TYPO3 v9
  */
 class ErrorpageMessage extends AbstractStandaloneMessage
 {
@@ -27,9 +29,11 @@ class ErrorpageMessage extends AbstractStandaloneMessage
      * @param string $message The error message
      * @param string $title Title of the message, can be empty
      * @param int $severity Optional severity, must be either of AbstractMessage::INFO or related constants
+     * @deprecated since TYPO3 v8, will be removed in TYPO3 v9, use the ErrorPageController instead
      */
     public function __construct($message = '', $title = '', $severity = AbstractMessage::ERROR)
     {
+        GeneralUtility::logDeprecatedFunction();
         $this->setHtmlTemplate(ExtensionManagementUtility::siteRelPath('core') . 'Resources/Private/Templates/Page/Error.html');
         parent::__construct($message, $title, $severity);
     }
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Deprecation-77164-ErrorpageMessageAndAbstractStandaloneMessage.rst b/typo3/sysext/core/Documentation/Changelog/master/Deprecation-77164-ErrorpageMessageAndAbstractStandaloneMessage.rst
new file mode 100644 (file)
index 0000000..9f78f22
--- /dev/null
@@ -0,0 +1,26 @@
+====================================================================
+Deprecation: #77164 - ErrorpageMessage and AbstractStandaloneMessage
+====================================================================
+
+Description
+===========
+
+The two PHP classes ``ErrorpageMessage`` and ``AbstractStandaloneMessage`` have been marked as deprecated.
+
+
+Impact
+======
+
+Instantiating one of the PHP classes will trigger a deprecation log entry.
+
+
+Affected Installations
+======================
+
+Any TYPO3 instance using the two PHP classes directly because of a specialized error handling or exception handling method.
+
+
+Migration
+=========
+
+Use the new Fluid-based ErrorPageController class.
\ No newline at end of file
diff --git a/typo3/sysext/core/Resources/Private/Templates/ErrorPage/Error.html b/typo3/sysext/core/Resources/Private/Templates/ErrorPage/Error.html
new file mode 100644 (file)
index 0000000..daf70e6
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html xmlns:f="https://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
+<head>
+               <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+               <meta name="robots" content="noindex, follow">
+               <title>{title}</title>
+               <link rel="stylesheet" href="{cssFile}">
+       </head>
+       <body class="t3-message-page t3-{severityCssClass}page-message">
+               <div class="t3-error-wrap">
+                       <div class="t3-message-page-container">
+                               <div class="t3-message-page-logo">
+                                       <img src="{logo}" class="typo3-error-image" alt="TYPO3 logo">
+                               </div>
+                               <div class="callout callout-danger">
+                                       <div class="media">
+                                               <div class="media-left">
+                                                       <span class="fa-stack fa-lg callout-icon">
+                                                               <i class="fa fa-circle fa-stack-2x"></i>
+                                                               <i class="fa fa-exclamation-triangle fa-stack-1x"></i>
+                                                       </span>
+                                               </div>
+                                               <div class="media-body">
+                                                       <h4 class="alert-title">{title}</h4>
+                                                       <div class="callout-body">
+                                                               {message}
+                                                               <f:if condition="{errorCode} > 0">
+                                                                       <p>More information regarding this error might be available <a href="{errorCodeUrlPrefix}{errorCode}" target="_blank">online</a>.</p>
+                                                               </f:if>
+                                                       </div>
+                                               </div>
+                                       </div>
+                               </div>
+                               <div id="t3-footer">
+                                       <div id="t3-copyright-notice">
+                                               TYPO3 is an open source content management system. To maintain the quality of the system and to improve it, please help us by
+                                               donating.
+                                               Copyright &copy; {copyrightYear} Kasper Skårhøj. Extensions are copyright of their respective owners. Go to
+                                               <a href="https://typo3.org/">https://typo3.org/</a> for details.
+                                               TYPO3 CMS comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions.
+                                               Obstructing the appearance of this notice is prohibited by law.
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+       </body>
+</html>
+
index 62ef98c..d41b8a2 100644 (file)
@@ -59,26 +59,26 @@ class MailerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
     }
 
     /**
-     * Data provider for wrongConfigigurationThrowsException
+     * Data provider for wrongConfigurationThrowsException
      *
      * @return array Data sets
      */
-    public static function wrongConfigigurationProvider()
+    public static function wrongConfigurationProvider()
     {
         return array(
             'smtp but no host' => array(array('transport' => 'smtp')),
             'sendmail but no command' => array(array('transport' => 'sendmail')),
             'mbox but no file' => array(array('transport' => 'mbox')),
-            'no instance of Swift_Transport' => array(array('transport' => \TYPO3\CMS\Core\Messaging\ErrorpageMessage::class))
+            'no instance of Swift_Transport' => array(array('transport' => \TYPO3\CMS\Core\Controller\ErrorPageController::class))
         );
     }
 
     /**
      * @test
      * @param $settings
-     * @dataProvider wrongConfigigurationProvider
+     * @dataProvider wrongConfigurationProvider
      */
-    public function wrongConfigigurationThrowsException($settings)
+    public function wrongConfigurationThrowsException($settings)
     {
         $this->expectException(\TYPO3\CMS\Core\Exception::class);
         $this->expectExceptionCode(1291068569);
index d218bce..ecf0662 100644 (file)
@@ -19,6 +19,7 @@ use TYPO3\CMS\Backend\FrontendBackendUserAuthentication;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Charset\CharsetConverter;
+use TYPO3\CMS\Core\Controller\ErrorPageController;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\Error\Http\PageNotFoundException;
@@ -28,7 +29,6 @@ use TYPO3\CMS\Core\Localization\LocalizationFactory;
 use TYPO3\CMS\Core\Locking\Exception\LockAcquireWouldBlockException;
 use TYPO3\CMS\Core\Locking\LockFactory;
 use TYPO3\CMS\Core\Locking\LockingStrategyInterface;
-use TYPO3\CMS\Core\Messaging\ErrorpageMessage;
 use TYPO3\CMS\Core\Page\PageRenderer;
 use TYPO3\CMS\Core\Resource\StorageRepository;
 use TYPO3\CMS\Core\Service\DependencyOrderingService;
@@ -2017,11 +2017,10 @@ class TypoScriptFrontendController
         // Create response:
         // Simply boolean; Just shows TYPO3 error page with reason:
         if (strtolower($code) === 'true' || (string)$code === '1' || gettype($code) === 'boolean') {
-            $title = 'Page Not Found';
-            $message = 'The page did not exist or was inaccessible.' . ($reason ? ' Reason: ' . htmlspecialchars($reason) : '');
-            $messagePage = GeneralUtility::makeInstance(ErrorpageMessage::class, $message, $title);
-            $messagePage->output();
-            die;
+            echo GeneralUtility::makeInstance(ErrorPageController::class)->errorAction(
+                'Page Not Found',
+                'The page did not exist or was inaccessible.' . ($reason ? ' Reason: ' . $reason : '')
+            );
         } elseif (GeneralUtility::isFirstPartOfStr($code, 'USER_FUNCTION:')) {
             $funcRef = trim(substr($code, 14));
             $params = array(
@@ -2125,10 +2124,10 @@ class TypoScriptFrontendController
                 echo $content;
             }
         } else {
-            $title = 'Page Not Found';
-            $message = $reason ? 'Reason: ' . htmlspecialchars($reason) : 'Page cannot be found.';
-            $messagePage = GeneralUtility::makeInstance(ErrorpageMessage::class, $message, $title);
-            $messagePage->output();
+            echo GeneralUtility::makeInstance(ErrorPageController::class)->errorAction(
+                'Page Not Found',
+                $reason ? 'Reason: ' . $reason : 'Page cannot be found.'
+            );
         }
         die;
     }