Skip to content

Instantly share code, notes, and snippets.

@bmack
Last active June 4, 2021 12:53
Show Gist options
  • Select an option

  • Save bmack/06bb00bfee09b7c5b79fd981c64fa9c9 to your computer and use it in GitHub Desktop.

Select an option

Save bmack/06bb00bfee09b7c5b79fd981c64fa9c9 to your computer and use it in GitHub Desktop.

Revisions

  1. bmack revised this gist Jul 10, 2019. 1 changed file with 2 additions and 1 deletion.
    3 changes: 2 additions & 1 deletion LocalPageErrorHandler.php
    Original file line number Diff line number Diff line change
    @@ -51,7 +51,8 @@ public function handlePageError(ServerRequestInterface $request, string $message
    }

    if ($targetDetails['type'] === 'page') {
    return $this->buildSubRequest($request, (int)$targetDetails['pageuid']);
    $response = $this->buildSubRequest($request, (int)$targetDetails['pageuid']);
    return $response->withStatusCode($this->statusCode);
    }
    if ($targetDetails['type'] !== 'url') {
    return new HtmlResponse('Big fail', $this->statusCode);
  2. bmack revised this gist May 27, 2019. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion LocalPageErrorHandler.php
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    <?php
    namespace B13\SiteB13\PageErrorHandler;
    namespace B13\AnyProject\PageErrorHandler;

    /*
    * This file is part of a b13 extension.
  3. bmack created this gist May 27, 2019.
    124 changes: 124 additions & 0 deletions LocalPageErrorHandler.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,124 @@
    <?php
    namespace B13\SiteB13\PageErrorHandler;

    /*
    * This file is part of a b13 extension.
    *
    * 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.
    */

    use Psr\Http\Message\ResponseInterface;
    use Psr\Http\Message\ServerRequestInterface;
    use TYPO3\CMS\Core\Cache\CacheManager;
    use TYPO3\CMS\Core\Error\PageErrorHandler\PageContentErrorHandler;
    use TYPO3\CMS\Core\Exception\SiteNotFoundException;
    use TYPO3\CMS\Core\Http\HtmlResponse;
    use TYPO3\CMS\Core\Http\MiddlewareDispatcher;
    use TYPO3\CMS\Core\Http\MiddlewareStackResolver;
    use TYPO3\CMS\Core\LinkHandling\LinkService;
    use TYPO3\CMS\Core\Package\PackageManager;
    use TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException;
    use TYPO3\CMS\Core\Service\DependencyOrderingService;
    use TYPO3\CMS\Core\Site\Entity\Site;
    use TYPO3\CMS\Core\Site\SiteFinder;
    use TYPO3\CMS\Core\Utility\GeneralUtility;
    use TYPO3\CMS\Frontend\Http\RequestHandler;

    /**
    * Does not execute a CURL request for internal pages. Just set it up in an extension
    * and refer to it in your Site Configuration (PHP Error Handler)
    */
    class LocalPageErrorHandler extends PageContentErrorHandler
    {

    /**
    * @param ServerRequestInterface $request
    * @param string $message
    * @param array $reasons
    * @return ResponseInterface
    * @throws \RuntimeException
    */
    public function handlePageError(ServerRequestInterface $request, string $message, array $reasons = []): ResponseInterface
    {
    $targetDetails = $this->resolveDetails($this->errorHandlerConfiguration['errorContentSource']);
    if ($targetDetails['type'] !== 'page' && $targetDetails['type'] !== 'url') {
    throw new \InvalidArgumentException('PageContentErrorHandler can only handle TYPO3 urls of types "page" or "url"', 1522826609);
    }

    if ($targetDetails['type'] === 'page') {
    return $this->buildSubRequest($request, (int)$targetDetails['pageuid']);
    }
    if ($targetDetails['type'] !== 'url') {
    return new HtmlResponse('Big fail', $this->statusCode);
    }
    $resolvedUrl = $targetDetails['url'];
    try {
    $content = null;
    $report = [];
    if ($resolvedUrl !== (string)$request->getUri()) {
    $content = GeneralUtility::getUrl($resolvedUrl, 0, null, $report);
    if ($content === false && ((int)$report['error'] === -1 || (int)$report['error'] > 200)) {
    throw new \RuntimeException('Error handler could not fetch error page "' . $resolvedUrl . '", reason: ' . $report['message'], 1544172838);
    }
    }
    } catch (InvalidRouteArgumentsException | SiteNotFoundException $e) {
    $content = 'Invalid error handler configuration: ' . $this->errorHandlerConfiguration['errorContentSource'];
    }
    return new HtmlResponse($content, $this->statusCode);
    }

    /**
    * @param ServerRequestInterface $request
    * @param int $pageId
    * @return ResponseInterface
    * @throws SiteNotFoundException
    * @throws \TYPO3\CMS\Core\Cache\Exception\InvalidDataException
    * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
    * @throws \TYPO3\CMS\Core\Exception
    */
    protected function buildSubRequest(ServerRequestInterface $request, int $pageId): ResponseInterface
    {
    $site = $request->getAttribute('site', null);
    if (!$site instanceof Site) {
    $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageId);
    $request = $request->withAttribute('site', $site);
    }
    $request = $request->withQueryParams(['id' => $pageId]);
    $dispatcher = $this->buildDispatcher();
    return $dispatcher->handle($request);
    }

    /**
    * @param string $typoLinkUrl
    * @return array
    */
    protected function resolveDetails(string $typoLinkUrl): array
    {
    $linkService = GeneralUtility::makeInstance(LinkService::class);
    return $linkService->resolve($typoLinkUrl);
    }

    /**
    * @return MiddlewareDispatcher
    * @throws \TYPO3\CMS\Core\Cache\Exception\InvalidDataException
    * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
    * @throws \TYPO3\CMS\Core\Exception
    */
    protected function buildDispatcher()
    {
    $requestHandler = GeneralUtility::makeInstance(RequestHandler::class);
    $resolver = new MiddlewareStackResolver(
    GeneralUtility::makeInstance(PackageManager::class),
    GeneralUtility::makeInstance(DependencyOrderingService::class),
    GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_core')
    );

    $middlewares = $resolver->resolve('frontend');
    return new MiddlewareDispatcher($requestHandler, $middlewares);
    }
    }