For coders TYPO3 Tech Corner

[PHP] Modern example for 403 and 404 handling in TYPO3

[PHP] Modern example for 403 and 404 handling in TYPO3

config.yaml:

base: 'https://%env(HOST)%/' baseVariants: { } errorHandling: - errorCode: '403' errorHandler: PHP errorPhpClassFQCN: Vendor\Sitepackage\PageHandler\NotAuthorized - errorCode: '404' errorHandler: PHP errorPhpClassFQCN: Vendor\Sitepackage\PageHandler\NotFound

NotAuthorized.php:

<?php declare(strict_types=1); namespace Vendor\Sitepackage\PageHandler; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface; use TYPO3\CMS\Core\Http\RedirectResponse; use TYPO3\CMS\Core\Http\Uri; use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Class NotAuthorized * to show a login page (in fitting language) and redirect to page after login * @noinspection PhpUnused */ class NotAuthorized implements PageErrorHandlerInterface { /** * @var int */ protected $pageLoginUid = 167; /** * @var ServerRequestInterface */ protected $request = null; /** * @param ServerRequestInterface $request * @param string $message * @param array $reasons * @return ResponseInterface */ public function handlePageError( ServerRequestInterface $request, string $message, array $reasons = [] ): ResponseInterface { $this->request = $request; return new RedirectResponse($this->getLoginUrl(), 302); } /** * @return string */ protected function getLoginUrl(): string { /** @var Site $site */ $siteFinder = GeneralUtility::makeInstance(SiteFinder::class); $site = $siteFinder->getSiteByPageId($this->pageLoginUid); /** @var Uri $uri */ $uri = $site->getRouter()->generateUri( $this->pageLoginUid, [ '_language' => $this->getLanguageIdentifier(), 'redirect_url' => $this->request->getUri()->__toString() ] ); return $uri->__toString(); } /** * @return int */ protected function getLanguageIdentifier(): int { /** @var SiteLanguage $language */ $language = $this->request->getAttribute('language'); return $language->getLanguageId(); } }

NotFound.php:

<?php declare(strict_types=1); namespace Vendor\Sitepackage\PageHandler; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface; use TYPO3\CMS\Core\Http\HtmlResponse; use TYPO3\CMS\Core\Http\RequestFactory; use TYPO3\CMS\Core\Http\Uri; use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Core\Site\Entity\SiteLanguage; use TYPO3\CMS\Core\Utility\GeneralUtility; /** * Class NotFound * to show a 404 page (in fitting language) * @noinspection PhpUnused */ class NotFound implements PageErrorHandlerInterface { /** * @var int */ protected $pageNotFoundUid = 133525; /** * @var ServerRequestInterface */ protected $request = null; /** * @param ServerRequestInterface $request * @param string $message * @param array $reasons * @return ResponseInterface * @throws RequestFailedException */ public function handlePageError( ServerRequestInterface $request, string $message, array $reasons = [] ): ResponseInterface { $this->request = $request; return new HtmlResponse($this->getPageNotFoundContent(), 404); } /** * @return string * @throws RequestFailedException */ protected function getPageNotFoundContent(): string { $url = $this->getPageNotFoundUrl(); $requestFactory = GeneralUtility::makeInstance(RequestFactory::class); /** @var ResponseInterface $response */ $response = $requestFactory->request($url, 'GET'); if ($response->getStatusCode() === 200) { if (strpos($response->getHeaderLine('Content-Type'), 'text/html') === 0) { return $response->getBody()->getContents(); } } throw new \LogicException('Could not read content of ' . $url, 1594134183); } /** * @return string */ protected function getPageNotFoundUrl(): string { /** @var Site $site */ $site = $this->request->getAttribute('site'); /** @var Uri $uri */ $uri = $site->getRouter()->generateUri($this->pageNotFoundUid, ['_language' => $this->getLanguageIdentifier()]); return $uri->__toString(); } /** * @return int */ protected function getLanguageIdentifier(): int { /** @var SiteLanguage $language */ $language = $this->request->getAttribute('language'); return $language->getLanguageId(); } }

Back

"Code faster, look at the time" - does this sound familiar to you?

How about time and respect for code quality? Working in a team? Automated tests?

Join us