‪TYPO3CMS  ‪main
StaticRouteResolver.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ResponseInterface;
21 use Psr\Http\Message\ServerRequestInterface;
22 use Psr\Http\Server\MiddlewareInterface;
23 use Psr\Http\Server\RequestHandlerInterface;
32 
36 class ‪StaticRouteResolver implements MiddlewareInterface
37 {
38  public function ‪__construct(
39  protected readonly ‪RequestFactory $requestFactory,
40  protected readonly ‪LinkService $linkService
41  ) {}
42 
46  public function ‪process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
47  {
48  if (($site = $request->getAttribute('site')) instanceof ‪Site &&
49  ($configuration = $site->getConfiguration()['routes'] ?? null)
50  ) {
51  $path = ltrim($request->getUri()->getPath(), '/');
52  $routeConfig = $this->‪getApplicableStaticRoute($configuration, $site, $path);
53  if (is_array($routeConfig)) {
54  try {
55  [$content, $contentType] = $this->‪resolveByType($request, $site, $routeConfig['type'], $routeConfig);
57  return new ‪Response('Invalid route', 404, ['Content-Type' => 'text/plain']);
58  }
59 
60  return new ‪HtmlResponse($content, 200, ['Content-Type' => $contentType]);
61  }
62  }
63  return $handler->handle($request);
64  }
65 
76  protected function ‪getApplicableStaticRoute(array $staticRouteConfiguration, ‪Site $site, string $uriPath): ?array
77  {
78  $routeNames = array_map(static function (?string $route) use ($site) {
79  if ($route === null || $route === '') {
80  return null;
81  }
82  return ltrim(trim($site->‪getBase()->getPath(), '/') . '/' . ltrim($route, '/'), '/');
83  }, array_column($staticRouteConfiguration, 'route'));
84  // Remove empty routes which would throw an error (could happen within creating a false route in the GUI)
85  $routeNames = array_filter($routeNames);
86 
87  if (in_array($uriPath, $routeNames, true)) {
88  $key = array_search($uriPath, $routeNames, true);
89  // Only allow routes with a type "given"
90  if (isset($staticRouteConfiguration[$key]['type'])) {
91  return $staticRouteConfiguration[$key];
92  }
93  }
94  return null;
95  }
96 
97  protected function ‪getFromFile(‪File $file): array
98  {
99  $content = $file->‪getContents();
100  $contentType = $file->‪getMimeType();
101  return [$content, $contentType];
102  }
103 
104  protected function ‪getFromUri(string $uri): array
105  {
106  $response = $this->requestFactory->request($uri);
107  $contentType = 'text/plain; charset=utf-8';
108  $content = '';
109  if ($response->getStatusCode() === 200) {
110  $content = $response->getBody()->getContents();
111  $contentType = $response->getHeader('Content-Type');
112  }
113 
114  return [$content, $contentType];
115  }
116 
117  protected function ‪getPageUri(ServerRequestInterface $request, ‪Site $site, array $urlParams): string
118  {
119  $parameters = [];
120  // Add additional parameters, if set via TypoLink
121  if (isset($urlParams['parameters'])) {
122  parse_str($urlParams['parameters'], $parameters);
123  }
124  $parameters['type'] = $urlParams['pagetype'] ?? 0;
125  $parameters['_language'] = $request->getAttribute('language', null);
126  $uri = $site->‪getRouter()->generateUri(
127  (int)($urlParams['pageuid'] ?? 0),
128  $parameters,
129  '',
131  );
132  return (string)$uri;
133  }
134 
138  protected function ‪resolveByType(ServerRequestInterface $request, ‪Site $site, string $type, array $routeConfig): array
139  {
140  switch ($type) {
141  case 'staticText':
142  if (!isset($routeConfig['content']) || !is_string($routeConfig['content'])) {
143  throw new \InvalidArgumentException('A static route of type "staticText" must have a content defined.', 1704704705);
144  }
145  $content = $routeConfig['content'];
146  $contentType = 'text/plain; charset=utf-8';
147  break;
148  case 'uri':
149  $urlParams = $this->linkService->resolve($routeConfig['source']);
150  if ($urlParams['type'] === 'url' || $urlParams['type'] === 'page') {
151  $uri = $urlParams['url'] ?? $this->‪getPageUri($request, $site, $urlParams);
152  [$content, $contentType] = $this->‪getFromUri($uri);
153  } elseif ($urlParams['type'] === 'file') {
154  [$content, $contentType] = $this->‪getFromFile($urlParams['file']);
155  } else {
156  throw new \InvalidArgumentException('Can only handle URIs of type page, url or file.', 1537348076);
157  }
158 
159  break;
160  default:
161  throw new \InvalidArgumentException(
162  'Can only handle static file configurations with type uri or staticText.',
163  1537348083
164  );
165  }
166  return [$content, $contentType];
167  }
168 }
‪TYPO3\CMS\Core\Routing\RouterInterface
Definition: RouterInterface.php:28
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver
Definition: StaticRouteResolver.php:37
‪TYPO3\CMS\Core\Resource\File\getContents
‪getContents()
Definition: File.php:104
‪TYPO3\CMS\Core\Site\Entity\Site
Definition: Site.php:42
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver\getApplicableStaticRoute
‪array null getApplicableStaticRoute(array $staticRouteConfiguration, Site $site, string $uriPath)
Definition: StaticRouteResolver.php:76
‪TYPO3\CMS\Core\Http\Response
Definition: Response.php:32
‪TYPO3\CMS\Frontend\Middleware
Definition: BackendUserAuthenticator.php:18
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver\getPageUri
‪getPageUri(ServerRequestInterface $request, Site $site, array $urlParams)
Definition: StaticRouteResolver.php:117
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Core\Routing\InvalidRouteArgumentsException
Definition: InvalidRouteArgumentsException.php:25
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver\resolveByType
‪resolveByType(ServerRequestInterface $request, Site $site, string $type, array $routeConfig)
Definition: StaticRouteResolver.php:138
‪TYPO3\CMS\Core\Resource\AbstractFile\getMimeType
‪non empty string getMimeType()
Definition: AbstractFile.php:257
‪TYPO3\CMS\Core\Http\RequestFactory
Definition: RequestFactory.php:30
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver\getFromFile
‪getFromFile(File $file)
Definition: StaticRouteResolver.php:97
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver\__construct
‪__construct(protected readonly RequestFactory $requestFactory, protected readonly LinkService $linkService)
Definition: StaticRouteResolver.php:38
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver\process
‪process(ServerRequestInterface $request, RequestHandlerInterface $handler)
Definition: StaticRouteResolver.php:46
‪TYPO3\CMS\Core\Routing\RouterInterface\ABSOLUTE_URL
‪const ABSOLUTE_URL
Definition: RouterInterface.php:32
‪TYPO3\CMS\Frontend\Middleware\StaticRouteResolver\getFromUri
‪getFromUri(string $uri)
Definition: StaticRouteResolver.php:104
‪TYPO3\CMS\Core\Site\Entity\Site\getRouter
‪getRouter(Context $context=null)
Definition: Site.php:346
‪TYPO3\CMS\Core\Http\HtmlResponse
Definition: HtmlResponse.php:28
‪TYPO3\CMS\Core\Site\Entity\Site\getBase
‪getBase()
Definition: Site.php:181