aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/Route/CachingRouter.php50
-rw-r--r--lib/private/Route/Router.php46
2 files changed, 81 insertions, 15 deletions
diff --git a/lib/private/Route/CachingRouter.php b/lib/private/Route/CachingRouter.php
index 66bdacc89a8..edfbdc99c3a 100644
--- a/lib/private/Route/CachingRouter.php
+++ b/lib/private/Route/CachingRouter.php
@@ -23,6 +23,8 @@ use Symfony\Component\Routing\RouteCollection;
class CachingRouter extends Router {
protected ICache $cache;
+ protected array $legacyCreatedRoutes = [];
+
public function __construct(
ICacheFactory $cacheFactory,
LoggerInterface $logger,
@@ -104,4 +106,52 @@ class CachingRouter extends Router {
$this->eventLogger->end('cacheroute:match');
return $parameters;
}
+
+ /**
+ * @param array{action:mixed, ...} $parameters
+ */
+ protected function callLegacyActionRoute(array $parameters): void {
+ /*
+ * Closures cannot be serialized to cache, so for legacy routes calling an action we have to include the routes.php file again
+ */
+ $app = $parameters['app'];
+ $this->useCollection($app);
+ parent::requireRouteFile($parameters['route-file'], $app);
+ $collection = $this->getCollection($app);
+ $parameters['action'] = $collection->get($parameters['_route'])?->getDefault('action');
+ parent::callLegacyActionRoute($parameters);
+ }
+
+ /**
+ * Create a \OC\Route\Route.
+ * Deprecated
+ *
+ * @param string $name Name of the route to create.
+ * @param string $pattern The pattern to match
+ * @param array $defaults An array of default parameter values
+ * @param array $requirements An array of requirements for parameters (regexes)
+ */
+ public function create($name, $pattern, array $defaults = [], array $requirements = []): Route {
+ $this->legacyCreatedRoutes[] = $name;
+ return parent::create($name, $pattern, $defaults, $requirements);
+ }
+
+ /**
+ * Require a routes.php file
+ */
+ protected function requireRouteFile(string $file, string $appName): void {
+ $this->legacyCreatedRoutes = [];
+ parent::requireRouteFile($file, $appName);
+ foreach ($this->legacyCreatedRoutes as $routeName) {
+ $route = $this->collection?->get($routeName);
+ if ($route === null) {
+ /* Should never happen */
+ throw new \Exception("Could not find route $routeName");
+ }
+ if ($route->hasDefault('action')) {
+ $route->setDefault('route-file', $file);
+ $route->setDefault('app', $appName);
+ }
+ }
+ }
}
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index b0c355dcbee..5d0f46d6268 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -312,21 +312,11 @@ class Router implements IRouter {
$application = $this->getApplicationClass($caller[0]);
\OC\AppFramework\App::main($caller[1], $caller[2], $application->getContainer(), $parameters);
} elseif (isset($parameters['action'])) {
- $action = $parameters['action'];
- if (!is_callable($action)) {
- throw new \Exception('not a callable action');
- }
- unset($parameters['action']);
- unset($parameters['caller']);
- $this->eventLogger->start('route:run:call', 'Run callable route');
- call_user_func($action, $parameters);
- $this->eventLogger->end('route:run:call');
+ $this->logger->warning('Deprecated action route used', ['parameters' => $parameters]);
+ $this->callLegacyActionRoute($parameters);
} elseif (isset($parameters['file'])) {
- $param = $parameters;
- unset($param['_route']);
- $_GET = array_merge($_GET, $param);
- unset($param);
- include $parameters['file'];
+ $this->logger->debug('Deprecated file route used', ['parameters' => $parameters]);
+ $this->includeLegacyFileRoute($parameters);
} else {
throw new \Exception('no action available');
}
@@ -334,6 +324,32 @@ class Router implements IRouter {
}
/**
+ * @param array{file:mixed, ...} $parameters
+ */
+ protected function includeLegacyFileRoute(array $parameters): void {
+ $param = $parameters;
+ unset($param['_route']);
+ $_GET = array_merge($_GET, $param);
+ unset($param);
+ require_once $parameters['file'];
+ }
+
+ /**
+ * @param array{action:mixed, ...} $parameters
+ */
+ protected function callLegacyActionRoute(array $parameters): void {
+ $action = $parameters['action'];
+ if (!is_callable($action)) {
+ throw new \Exception('not a callable action');
+ }
+ unset($parameters['action']);
+ unset($parameters['caller']);
+ $this->eventLogger->start('route:run:call', 'Run callable route');
+ call_user_func($action, $parameters);
+ $this->eventLogger->end('route:run:call');
+ }
+
+ /**
* Get the url generator
*
* @return \Symfony\Component\Routing\Generator\UrlGenerator
@@ -496,7 +512,7 @@ class Router implements IRouter {
* @param string $file the route file location to include
* @param string $appName
*/
- private function requireRouteFile($file, $appName) {
+ protected function requireRouteFile(string $file, string $appName): void {
$this->setupRoutes(include $file, $appName);
}