getAttribute('site')) instanceof Site && ($configuration = $site->getConfiguration()['routes'] ?? null) ) { $path = ltrim($request->getUri()->getPath(), '/'); $routeConfig = $this->getApplicableStaticRoute($configuration, $site, $path); if (is_array($routeConfig)) { try { [$content, $contentType] = $this->resolveByType($request, $site, $routeConfig['type'], $routeConfig); } catch (InvalidRouteArgumentsException $e) { return new Response('Invalid route', 404, ['Content-Type' => 'text/plain']); } return new HtmlResponse($content, 200, ['Content-Type' => $contentType]); } } return $handler->handle($request); } /** * Find the proper configuration for the static route in the static route configuration. Mainly: * - needs to have a valid "route" property * - needs to have a "type" * * @param array $staticRouteConfiguration the "routes" part of the site configuration * @param Site $site the current site where the configuration is based on * @param string $uriPath the path of the current request - used to match the "route" value of a single static route * @return array|null the configuration for the static route that matches, or null if no route is given */ protected function getApplicableStaticRoute(array $staticRouteConfiguration, Site $site, string $uriPath): ?array { $routeNames = array_map(static function (?string $route) use ($site) { if ($route === null || $route === '') { return null; } return ltrim(trim($site->getBase()->getPath(), '/') . '/' . ltrim($route, '/'), '/'); }, array_column($staticRouteConfiguration, 'route')); // Remove empty routes which would throw an error (could happen within creating a false route in the GUI) $routeNames = array_filter($routeNames); if (in_array($uriPath, $routeNames, true)) { $key = array_search($uriPath, $routeNames, true); // Only allow routes with a type "given" if (isset($staticRouteConfiguration[$key]['type'])) { return $staticRouteConfiguration[$key]; } } return null; } protected function getFromFile(File $file): array { $content = $file->getContents(); $contentType = $file->getMimeType(); return [$content, $contentType]; } protected function getFromUri(string $uri): array { $response = $this->requestFactory->request($uri); $contentType = 'text/plain; charset=utf-8'; $content = ''; if ($response->getStatusCode() === 200) { $content = $response->getBody()->getContents(); $contentType = $response->getHeader('Content-Type'); } return [$content, $contentType]; } protected function getPageUri(ServerRequestInterface $request, Site $site, array $urlParams): string { $parameters = []; // Add additional parameters, if set via TypoLink if (isset($urlParams['parameters'])) { parse_str($urlParams['parameters'], $parameters); } $parameters['type'] = $urlParams['pagetype'] ?? 0; $parameters['_language'] = $request->getAttribute('language', null); $uri = $site->getRouter()->generateUri( (int)($urlParams['pageuid'] ?? 0), $parameters, '', RouterInterface::ABSOLUTE_URL ); return (string)$uri; } /** * @throws InvalidRouteArgumentsException */ protected function resolveByType(ServerRequestInterface $request, Site $site, string $type, array $routeConfig): array { switch ($type) { case 'staticText': if (!isset($routeConfig['content']) || !is_string($routeConfig['content'])) { throw new \InvalidArgumentException('A static route of type "staticText" must have a content defined.', 1704704705); } $content = $routeConfig['content']; $contentType = 'text/plain; charset=utf-8'; break; case 'uri': $urlParams = $this->linkService->resolve($routeConfig['source']); if ($urlParams['type'] === 'url' || $urlParams['type'] === 'page') { $uri = $urlParams['url'] ?? $this->getPageUri($request, $site, $urlParams); [$content, $contentType] = $this->getFromUri($uri); } elseif ($urlParams['type'] === 'file') { [$content, $contentType] = $this->getFromFile($urlParams['file']); } else { throw new \InvalidArgumentException('Can only handle URIs of type page, url or file.', 1537348076); } break; case 'asset': if (!($routeConfig['asset'] ?? null)) { throw new \InvalidArgumentException('A static route of type "asset" must have an asset defined.', 1721134959); } try { $resource = $this->systemResourceFactory->createResource($routeConfig['asset']); if (!$resource instanceof SystemResourceInterface) { throw new \InvalidArgumentException(sprintf('The asset "%s" (resolved to "%s") is not a system resource.', $routeConfig['asset'], $resource), 1758785685); } } catch (SystemResourceException $e) { throw new \InvalidArgumentException(sprintf('Could not resolve asset "%s"', $routeConfig['asset']), 1721134960, $e); } $content = $resource->getContents(); $contentType = $resource->getMimeType(); break; default: throw new \InvalidArgumentException( 'Can only handle static file configurations with type uri, staticText or asset', 1537348083 ); } return [$content, $contentType]; } }