aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan-Hendrik Willms <tleilax+studip@gmail.com>2025-07-10 10:48:34 +0200
committerJan-Hendrik Willms <tleilax+studip@gmail.com>2025-07-10 10:48:34 +0200
commit7f557a0d69924597be5ca6b3aa8495ed26460429 (patch)
treeeaa918393753dca1ac74177c83bee7ed3c1d78b0
parent1284a27e6cf95a55f8cce006a670396045ca2e7a (diff)
add legacy route director that should fix all forum links, fixes #5698
Closes #5698 Merge request studip/studip!4326
-rw-r--r--lib/classes/StudipDispatcher.php32
-rw-r--r--lib/middleware/LegacyRedirectorMiddleware.php105
-rw-r--r--public/dispatch.php4
3 files changed, 128 insertions, 13 deletions
diff --git a/lib/classes/StudipDispatcher.php b/lib/classes/StudipDispatcher.php
index 10799c7..a54c45c 100644
--- a/lib/classes/StudipDispatcher.php
+++ b/lib/classes/StudipDispatcher.php
@@ -90,19 +90,25 @@ class StudipDispatcher extends Trails\Dispatcher
return $this->container->make($class, ['dispatcher' => $this]);
}
- public function getRouteCallable($uri)
+ public function getRouteCallable($uri): callable
{
- $uri = $this->clean_request_uri((string) $uri);
- [$controller_path, $unconsumed] = '' === $uri ? $this->default_route() : $this->parse($uri);
- $controller = $this->load_controller($controller_path);
- return function (
- \Psr\Http\Message\ServerRequestInterface $request,
- \Psr\Http\Message\ResponseInterface $response,
- array $args
- ) use ($controller, $unconsumed): \Psr\Http\Message\ResponseInterface {
- $controller->injectResponse($response);
- $response = $controller->perform($unconsumed);
- return $response->getPsrResponse();
- } ;
+ try {
+ $uri = $this->clean_request_uri((string) $uri);
+ [$controller_path, $unconsumed] = '' === $uri ? $this->default_route() : $this->parse($uri);
+ $controller = $this->load_controller($controller_path);
+ return function (
+ \Psr\Http\Message\ServerRequestInterface $request,
+ \Psr\Http\Message\ResponseInterface $response,
+ array $args
+ ) use ($controller, $unconsumed): \Psr\Http\Message\ResponseInterface {
+ $controller->injectResponse($response);
+ $response = $controller->perform($unconsumed);
+ return $response->getPsrResponse();
+ } ;
+ } catch (Exception $e) {
+ return function () use ($e) {
+ throw $e;
+ };
+ }
}
}
diff --git a/lib/middleware/LegacyRedirectorMiddleware.php b/lib/middleware/LegacyRedirectorMiddleware.php
new file mode 100644
index 0000000..5b9960c
--- /dev/null
+++ b/lib/middleware/LegacyRedirectorMiddleware.php
@@ -0,0 +1,105 @@
+<?php
+namespace Studip\Middleware;
+
+use Forum\ForumTopic;
+use NotificationCenter;
+use Psr\Http\Message\ResponseFactoryInterface;
+use Psr\Http\Message\{ResponseInterface as Response,
+ ServerRequestInterface as Request,
+ UriInterface
+};
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+use Slim\App;
+
+final class LegacyRedirectorMiddleware implements MiddlewareInterface
+{
+ private array $legacyRoutes = [];
+
+ public function __construct(
+ private readonly App $app,
+ private readonly ResponseFactoryInterface $response_factory
+ ) {
+ $this->addLegacyRoute(
+ '#^course/forum/index/index#',
+ [$this, 'redirectForumPost']
+ );
+
+ NotificationCenter::postNotification('LEGACY_REDIRECTOR_DID_CREATE', $this);
+ }
+
+ public function addLegacyRoute(string $route, callable $handler): void
+ {
+ $this->legacyRoutes[$route] = $handler;
+ }
+
+ public function process(Request $request, RequestHandlerInterface $handler): Response
+ {
+ $path = $this->getRelativePath($request);
+
+ foreach ($this->legacyRoutes as $legacyRoute => $routeHandler) {
+ if ($this->routeMatches($path, $legacyRoute)) {
+ /** @var UriInterface $newUri */
+ $newUri = $routeHandler($request);
+
+ $response = $this->response_factory->createResponse(301);
+ $response->getBody()->write('');
+ return $response->withHeader('Location', (string) $newUri);
+ }
+ }
+
+ return $handler->handle($request);
+ }
+
+ private function getRelativePath(Request $request): string
+ {
+ $basePath = $this->app->getBasePath();
+ $fullPath = $request->getUri()->getPath();
+
+ return ltrim(substr($fullPath, strlen($basePath)), '/');
+ }
+
+ private function routeMatches(string $path, string $route): bool
+ {
+ if (str_starts_with($route, '#') && str_ends_with($route, '#')) {
+ return preg_match($route, $path);
+ }
+
+ return str_starts_with($path, $route);
+ }
+
+ private function redirectForumPost(Request $request): UriInterface
+ {
+ $uri = $request->getUri();
+ $range_id = $request->getQueryParams()['cid'];
+ $forum_id = explode('/', $this->getRelativePath($request))[4] ?? null;
+
+ if ($forum_id === $range_id) {
+ $redirectUri = $uri->withPath(
+ str_replace(
+ 'course/forum/index/index/' . $forum_id,
+ 'course/forum/topics',
+ $uri->getPath()
+ )
+ );
+ } elseif (ForumTopic::exists($forum_id)) {
+ $redirectUri = $uri->withPath(
+ str_replace(
+ 'course/forum/index/index',
+ 'course/forum/topics/show',
+ $uri->getPath()
+ )
+ );
+ } else {
+ $redirectUri = $uri->withPath(
+ str_replace(
+ 'course/forum/index/index',
+ 'course/forum/discussions/show',
+ $uri->getPath()
+ )
+ );
+ }
+
+ return $redirectUri;
+ }
+}
diff --git a/public/dispatch.php b/public/dispatch.php
index c5c2b93..d2ebdaf 100644
--- a/public/dispatch.php
+++ b/public/dispatch.php
@@ -31,6 +31,10 @@ $app->setBasePath($GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP'] . 'dispatch.php');
$studip_dispatcher = app(\Trails\Dispatcher::class);
$route_callable = $studip_dispatcher->getRouteCallable(Request::pathInfo());
$app->any(Request::pathInfo(), $route_callable);
+
+// Add legacy director so links shall not break
+$app->add(Studip\Middleware\LegacyRedirectorMiddleware::class);
+
NotificationCenter::postNotification('SLIM_BEFORE_RUN', $app);
$app->run();
NotificationCenter::postNotification('SLIM_AFTER_RUN', $app);