diff --git a/typo3/sysext/frontend/Classes/PageErrorHandler/FluidPageErrorHandler.php b/typo3/sysext/core/Classes/Error/PageErrorHandler/FluidPageErrorHandler.php similarity index 98% rename from typo3/sysext/frontend/Classes/PageErrorHandler/FluidPageErrorHandler.php rename to typo3/sysext/core/Classes/Error/PageErrorHandler/FluidPageErrorHandler.php index 074af5a8f5d905b155a061a9f7078c5edebd991e..80aa76d32f4aad196f73d2023799cc4160182203 100644 --- a/typo3/sysext/frontend/Classes/PageErrorHandler/FluidPageErrorHandler.php +++ b/typo3/sysext/core/Classes/Error/PageErrorHandler/FluidPageErrorHandler.php @@ -1,7 +1,7 @@ <?php declare(strict_types = 1); -namespace TYPO3\CMS\Frontend\PageErrorHandler; +namespace TYPO3\CMS\Core\Error\PageErrorHandler; /* * This file is part of the TYPO3 CMS project. diff --git a/typo3/sysext/core/Classes/Error/PageErrorHandler/InvalidPageErrorHandlerException.php b/typo3/sysext/core/Classes/Error/PageErrorHandler/InvalidPageErrorHandlerException.php new file mode 100644 index 0000000000000000000000000000000000000000..2e2cb66d6071e3b4c64be224227c14bf884028e0 --- /dev/null +++ b/typo3/sysext/core/Classes/Error/PageErrorHandler/InvalidPageErrorHandlerException.php @@ -0,0 +1,27 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Error\PageErrorHandler; + +/* + * 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\Error\Exception; + +/** + * Is typically used, when a site configuration has a page-error handler configured but this does not implement + * the PageErrorHandlerInterface + */ +class InvalidPageErrorHandlerException extends Exception +{ +} diff --git a/typo3/sysext/frontend/Classes/PageErrorHandler/PageContentErrorHandler.php b/typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php similarity index 92% rename from typo3/sysext/frontend/Classes/PageErrorHandler/PageContentErrorHandler.php rename to typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php index 3e5a32c2174ab90c21d08ad985b5f888bd286b60..c68900382f1cfe90f061a023a39dcc5056732747 100644 --- a/typo3/sysext/frontend/Classes/PageErrorHandler/PageContentErrorHandler.php +++ b/typo3/sysext/core/Classes/Error/PageErrorHandler/PageContentErrorHandler.php @@ -1,7 +1,7 @@ <?php declare(strict_types = 1); -namespace TYPO3\CMS\Frontend\PageErrorHandler; +namespace TYPO3\CMS\Core\Error\PageErrorHandler; /* * This file is part of the TYPO3 CMS project. @@ -23,7 +23,6 @@ use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\LinkHandling\LinkService; use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Install\FolderStructure\Exception\InvalidArgumentException; /** * Renders the content of a page to be displayed (also in relation to language etc) @@ -46,13 +45,13 @@ class PageContentErrorHandler implements PageErrorHandlerInterface * PageContentErrorHandler constructor. * @param int $statusCode * @param array $configuration - * @throws InvalidArgumentException + * @throws \InvalidArgumentException */ public function __construct(int $statusCode, array $configuration) { $this->statusCode = $statusCode; if (empty($configuration['errorContentSource'])) { - throw new InvalidArgumentException('PageContentErrorHandler needs to have a proper link set.', 1522826413); + throw new \InvalidArgumentException('PageContentErrorHandler needs to have a proper link set.', 1522826413); } $this->errorHandlerConfiguration = $configuration; } diff --git a/typo3/sysext/frontend/Classes/PageErrorHandler/PageErrorHandlerInterface.php b/typo3/sysext/core/Classes/Error/PageErrorHandler/PageErrorHandlerInterface.php similarity index 77% rename from typo3/sysext/frontend/Classes/PageErrorHandler/PageErrorHandlerInterface.php rename to typo3/sysext/core/Classes/Error/PageErrorHandler/PageErrorHandlerInterface.php index 82d52a2841a71956735766dd2581a914aaf6de49..29baa6b22758a3acc281cc6cf3280d484bc10cef 100644 --- a/typo3/sysext/frontend/Classes/PageErrorHandler/PageErrorHandlerInterface.php +++ b/typo3/sysext/core/Classes/Error/PageErrorHandler/PageErrorHandlerInterface.php @@ -1,6 +1,7 @@ <?php declare(strict_types = 1); -namespace TYPO3\CMS\Frontend\PageErrorHandler; + +namespace TYPO3\CMS\Core\Error\PageErrorHandler; /* * This file is part of the TYPO3 CMS project. @@ -19,8 +20,9 @@ use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; /** - * Page error handler interface - * Should be implemented by all custom PHP-related Page Error Handlers. + * Page error handler interface, used to jump in for Frontend-related calls + * + * Needs to be implemented by all custom PHP-related Page Error Handlers. */ interface PageErrorHandlerInterface { diff --git a/typo3/sysext/core/Classes/Site/Entity/Site.php b/typo3/sysext/core/Classes/Site/Entity/Site.php index 36205a03dba1920224397e51eddb88d51a11337c..5e55433209f682bd9650d6f57fa3dc71212c74a2 100644 --- a/typo3/sysext/core/Classes/Site/Entity/Site.php +++ b/typo3/sysext/core/Classes/Site/Entity/Site.php @@ -16,10 +16,11 @@ namespace TYPO3\CMS\Core\Site\Entity; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Error\PageErrorHandler\FluidPageErrorHandler; +use TYPO3\CMS\Core\Error\PageErrorHandler\InvalidPageErrorHandlerException; +use TYPO3\CMS\Core\Error\PageErrorHandler\PageContentErrorHandler; +use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Frontend\PageErrorHandler\FluidPageErrorHandler; -use TYPO3\CMS\Frontend\PageErrorHandler\PageContentErrorHandler; -use TYPO3\CMS\Frontend\PageErrorHandler\PageErrorHandlerInterface; /** * Entity representing a single site with available languages @@ -171,27 +172,28 @@ class Site /** * Returns a ready-to-use error handler, to be used within the ErrorController * - * @param int $type + * @param int $statusCode * @return PageErrorHandlerInterface * @throws \RuntimeException + * @throws InvalidPageErrorHandlerException */ - public function getErrorHandler(int $type): PageErrorHandlerInterface + public function getErrorHandler(int $statusCode): PageErrorHandlerInterface { - $errorHandler = $this->errorHandlers[$type]; - switch ($errorHandler['errorHandler']) { + $errorHandlerConfiguration = $this->errorHandlers[$statusCode] ?? null; + switch ($errorHandlerConfiguration['errorHandler']) { case self::ERRORHANDLER_TYPE_FLUID: - return new FluidPageErrorHandler($type, $errorHandler); + return GeneralUtility::makeInstance(FluidPageErrorHandler::class, $statusCode, $errorHandlerConfiguration); case self::ERRORHANDLER_TYPE_PAGE: - return new PageContentErrorHandler($type, $errorHandler); + return GeneralUtility::makeInstance(PageContentErrorHandler::class, $statusCode, $errorHandlerConfiguration); case self::ERRORHANDLER_TYPE_PHP: + $handler = GeneralUtility::makeInstance($errorHandlerConfiguration['errorPhpClassFQCN'], $statusCode, $errorHandlerConfiguration); // Check if the interface is implemented - $handler = GeneralUtility::makeInstance($errorHandler['errorPhpClassFQCN'], $type, $errorHandler); if (!($handler instanceof PageErrorHandlerInterface)) { - // @todo throw new exception + throw new InvalidPageErrorHandlerException('The configured error handler "' . (string)$errorHandlerConfiguration['errorPhpClassFQCN'] . '" for status code ' . $statusCode . ' must implement the PageErrorHandlerInterface.', 1527432330); } return $handler; } - throw new \RuntimeException('Not implemented', 1522495914); + throw new \RuntimeException('No error handler given for the status code "' . $statusCode . '".', 1522495914); } /** diff --git a/typo3/sysext/core/Tests/Unit/Site/Entity/SiteTest.php b/typo3/sysext/core/Tests/Unit/Site/Entity/SiteTest.php new file mode 100644 index 0000000000000000000000000000000000000000..91a697c1155a09aebcf7f37b5d2e8aa8b076b2c6 --- /dev/null +++ b/typo3/sysext/core/Tests/Unit/Site/Entity/SiteTest.php @@ -0,0 +1,116 @@ +<?php +declare(strict_types = 1); + +namespace TYPO3\CMS\Core\Tests\Unit\Site\Entity; + +/* + * 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\Backend\Utility\BackendUtility; +use TYPO3\CMS\Core\Error\PageErrorHandler\FluidPageErrorHandler; +use TYPO3\CMS\Core\Error\PageErrorHandler\InvalidPageErrorHandlerException; +use TYPO3\CMS\Core\Error\PageErrorHandler\PageContentErrorHandler; +use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface; +use TYPO3\CMS\Core\Site\Entity\Site; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; + +class SiteTest extends UnitTestCase +{ + /** + * @test + */ + public function getErrorHandlerReturnsConfiguredErrorHandler() + { + $subject = new Site('aint-misbehaving', 13, [ + 'languages' => [], + 'errorHandling' => [ + [ + 'errorCode' => 123, + 'errorHandler' => 'Fluid', + ], + [ + 'errorCode' => 124, + 'errorContentSource' => 123, + 'errorHandler' => 'Page' + ], + [ + 'errorCode' => 125, + 'errorHandler' => 'PHP', + 'errorContentSource' => 123, + 'errorPhpClassFQCN' => PageContentErrorHandler::class + ] + ] + ]); + + $fluidProphecy = $this->prophesize(FluidPageErrorHandler::class); + GeneralUtility::addInstance(FluidPageErrorHandler::class, $fluidProphecy->reveal()); + + $this->assertEquals(true, $subject->getErrorHandler(123) instanceof PageErrorHandlerInterface); + $this->assertEquals(true, $subject->getErrorHandler(124) instanceof PageErrorHandlerInterface); + $this->assertEquals(true, $subject->getErrorHandler(125) instanceof PageErrorHandlerInterface); + } + + /** + * @test + */ + public function getErrorHandlerThrowsExceptionOnInvalidErrorHandler() + { + $this->expectException(InvalidPageErrorHandlerException::class); + $this->expectExceptionCode(1527432330); + $this->expectExceptionMessage('The configured error handler "' . BackendUtility::class . '" for status code 404 must implement the PageErrorHandlerInterface.'); + $subject = new Site('aint-misbehaving', 13, [ + 'languages' => [], + 'errorHandling' => [ + [ + 'errorCode' => 404, + 'errorHandler' => 'PHP', + 'errorPhpClassFQCN' => BackendUtility::class + ], + ] + ]); + $subject->getErrorHandler(404); + } + + /** + * @test + */ + public function getErrorHandlerThrowsExceptionWhenNoErrorHandlerIsConfigured() + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionCode(1522495914); + $this->expectExceptionMessage('No error handler given for the status code "404".'); + $subject = new Site('aint-misbehaving', 13, ['languages' => []]); + $subject->getErrorHandler(404); + } + + /** + * @test + */ + public function getErrorHandlerThrowsExceptionWhenNoErrorHandlerForStatusCodeIsConfigured() + { + $this->expectException(\RuntimeException::class); + $this->expectExceptionCode(1522495914); + $this->expectExceptionMessage('No error handler given for the status code "404".'); + $subject = new Site('aint-misbehaving', 13, [ + 'languages' => [], + 'errorHandling' => [ + [ + 'errorCode' => 403, + 'errorHandler' => 'Does it really matter?' + ], + ] + ]); + $subject->getErrorHandler(404); + } +}