aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Route/Router.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Route/Router.php')
-rw-r--r--lib/private/Route/Router.php148
1 files changed, 102 insertions, 46 deletions
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index b04b6a4d21c..90225212e9a 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -53,10 +53,10 @@ class Router implements IRouter {
public function __construct(
protected LoggerInterface $logger,
IRequest $request,
- private IConfig $config,
- private IEventLogger $eventLogger,
+ protected IConfig $config,
+ protected IEventLogger $eventLogger,
private ContainerInterface $container,
- private IAppManager $appManager,
+ protected IAppManager $appManager,
) {
$baseUrl = \OC::$WEBROOT;
if (!($config->getSystemValue('htaccess.IgnoreFrontController', false) === true || getenv('front_controller_active') === 'true')) {
@@ -74,6 +74,14 @@ class Router implements IRouter {
$this->root = $this->getCollection('root');
}
+ public function setContext(RequestContext $context): void {
+ $this->context = $context;
+ }
+
+ public function getRouteCollection() {
+ return $this->root;
+ }
+
/**
* Get the files to load the routes from
*
@@ -82,7 +90,7 @@ class Router implements IRouter {
public function getRoutingFiles() {
if ($this->routingFiles === null) {
$this->routingFiles = [];
- foreach (\OC_APP::getEnabledApps() as $app) {
+ foreach ($this->appManager->getEnabledApps() as $app) {
try {
$appPath = $this->appManager->getAppPath($app);
$file = $appPath . '/appinfo/routes.php';
@@ -102,50 +110,50 @@ class Router implements IRouter {
*
* @param null|string $app
*/
- public function loadRoutes($app = null) {
+ public function loadRoutes(?string $app = null, bool $skipLoadingCore = false): void {
if (is_string($app)) {
- $app = \OC_App::cleanAppId($app);
+ $app = $this->appManager->cleanAppId($app);
}
$requestedApp = $app;
if ($this->loaded) {
return;
}
+ $this->eventLogger->start('route:load:' . $requestedApp, 'Loading Routes for ' . $requestedApp);
if (is_null($app)) {
$this->loaded = true;
$routingFiles = $this->getRoutingFiles();
+
+ $this->eventLogger->start('route:load:attributes', 'Loading Routes from attributes');
+ foreach ($this->appManager->getEnabledApps() as $enabledApp) {
+ $this->loadAttributeRoutes($enabledApp);
+ }
+ $this->eventLogger->end('route:load:attributes');
} else {
if (isset($this->loadedApps[$app])) {
return;
}
- $appPath = \OC_App::getAppPath($app);
- $file = $appPath . '/appinfo/routes.php';
- if ($appPath !== false && file_exists($file)) {
- $routingFiles = [$app => $file];
- } else {
+ try {
+ $appPath = $this->appManager->getAppPath($app);
+ $file = $appPath . '/appinfo/routes.php';
+ if (file_exists($file)) {
+ $routingFiles = [$app => $file];
+ } else {
+ $routingFiles = [];
+ }
+ } catch (AppPathNotFoundException) {
$routingFiles = [];
}
- }
- $this->eventLogger->start('route:load:' . $requestedApp, 'Loading Routes for ' . $requestedApp);
- if ($requestedApp !== null && in_array($requestedApp, \OC_App::getEnabledApps())) {
- $routes = $this->getAttributeRoutes($requestedApp);
- if (count($routes) > 0) {
- $this->useCollection($requestedApp);
- $this->setupRoutes($routes, $requestedApp);
- $collection = $this->getCollection($requestedApp);
- $this->root->addCollection($collection);
-
- // Also add the OCS collection
- $collection = $this->getCollection($requestedApp . '.ocs');
- $collection->addPrefix('/ocsapp');
- $this->root->addCollection($collection);
+ if ($this->appManager->isEnabledForUser($app)) {
+ $this->loadAttributeRoutes($app);
}
}
+ $this->eventLogger->start('route:load:files', 'Loading Routes from files');
foreach ($routingFiles as $app => $file) {
if (!isset($this->loadedApps[$app])) {
- if (!\OC_App::isAppLoaded($app)) {
+ if (!$this->appManager->isAppLoaded($app)) {
// app MUST be loaded before app routes
// try again next time loadRoutes() is called
$this->loaded = false;
@@ -158,16 +166,18 @@ class Router implements IRouter {
$this->root->addCollection($collection);
// Also add the OCS collection
- $collection = $this->getCollection($app.'.ocs');
+ $collection = $this->getCollection($app . '.ocs');
$collection->addPrefix('/ocsapp');
$this->root->addCollection($collection);
}
}
- if (!isset($this->loadedApps['core'])) {
+ $this->eventLogger->end('route:load:files');
+
+ if (!$skipLoadingCore && !isset($this->loadedApps['core'])) {
$this->loadedApps['core'] = true;
$this->useCollection('root');
$this->setupRoutes($this->getAttributeRoutes('core'), 'core');
- require_once __DIR__ . '/../../../core/routes.php';
+ $this->requireRouteFile(__DIR__ . '/../../../core/routes.php', 'core');
// Also add the OCS collection
$collection = $this->getCollection('root.ocs');
@@ -245,28 +255,29 @@ class Router implements IRouter {
// empty string / 'apps' / $app / rest of the route
[, , $app,] = explode('/', $url, 4);
- $app = \OC_App::cleanAppId($app);
+ $app = $this->appManager->cleanAppId($app);
\OC::$REQUESTEDAPP = $app;
$this->loadRoutes($app);
} elseif (str_starts_with($url, '/ocsapp/apps/')) {
// empty string / 'ocsapp' / 'apps' / $app / rest of the route
[, , , $app,] = explode('/', $url, 5);
- $app = \OC_App::cleanAppId($app);
+ $app = $this->appManager->cleanAppId($app);
\OC::$REQUESTEDAPP = $app;
$this->loadRoutes($app);
} elseif (str_starts_with($url, '/settings/')) {
$this->loadRoutes('settings');
} elseif (str_starts_with($url, '/core/')) {
\OC::$REQUESTEDAPP = $url;
- if (!$this->config->getSystemValueBool('maintenance') && !Util::needUpgrade()) {
- \OC_App::loadApps();
+ if ($this->config->getSystemValueBool('installed', false) && !Util::needUpgrade()) {
+ $this->appManager->loadApps();
}
$this->loadRoutes('core');
} else {
$this->loadRoutes();
}
+ $this->eventLogger->start('route:url:match', 'Symfony url matcher call');
$matcher = new UrlMatcher($this->root, $this->context);
try {
$parameters = $matcher->match($url);
@@ -285,6 +296,7 @@ class Router implements IRouter {
throw $e;
}
}
+ $this->eventLogger->end('route:url:match');
$this->eventLogger->end('route:match');
return $parameters;
@@ -308,17 +320,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'])) {
- include $parameters['file'];
+ $this->logger->debug('Deprecated file route used', ['parameters' => $parameters]);
+ $this->includeLegacyFileRoute($parameters);
} else {
throw new \Exception('no action available');
}
@@ -326,6 +332,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
@@ -410,9 +442,29 @@ class Router implements IRouter {
if ($routeName === 'cloud_federation_api.requesthandlercontroller.receivenotification') {
return 'cloud_federation_api.requesthandler.receivenotification';
}
+ if ($routeName === 'core.ProfilePage.index') {
+ return 'profile.ProfilePage.index';
+ }
return $routeName;
}
+ private function loadAttributeRoutes(string $app): void {
+ $routes = $this->getAttributeRoutes($app);
+ if (count($routes) === 0) {
+ return;
+ }
+
+ $this->useCollection($app);
+ $this->setupRoutes($routes, $app);
+ $collection = $this->getCollection($app);
+ $this->root->addCollection($collection);
+
+ // Also add the OCS collection
+ $collection = $this->getCollection($app . '.ocs');
+ $collection->addPrefix('/ocsapp');
+ $this->root->addCollection($collection);
+ }
+
/**
* @throws ReflectionException
*/
@@ -423,7 +475,11 @@ class Router implements IRouter {
$appControllerPath = __DIR__ . '/../../../core/Controller';
$appNameSpace = 'OC\\Core';
} else {
- $appControllerPath = \OC_App::getAppPath($app) . '/lib/Controller';
+ try {
+ $appControllerPath = $this->appManager->getAppPath($app) . '/lib/Controller';
+ } catch (AppPathNotFoundException) {
+ return [];
+ }
$appNameSpace = App::buildAppNamespace($app);
}
@@ -464,8 +520,8 @@ class Router implements IRouter {
* @param string $file the route file location to include
* @param string $appName
*/
- private function requireRouteFile($file, $appName) {
- $this->setupRoutes(include_once $file, $appName);
+ protected function requireRouteFile(string $file, string $appName): void {
+ $this->setupRoutes(include $file, $appName);
}