aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Route
diff options
context:
space:
mode:
authorprovokateurin <kate@provokateurin.de>2024-01-10 12:35:09 +0100
committerprovokateurin <kate@provokateurin.de>2024-02-21 12:07:50 +0100
commitdf6175ccb17cc6917c41fc6eb41b727ec81a920b (patch)
tree67c8b8a6c9801c497951ed3150a610eb992c8daa /lib/private/Route
parent66e7056c5ebd1538ca94ab3a1f04b6bf184170cb (diff)
downloadnextcloud-server-df6175ccb17cc6917c41fc6eb41b727ec81a920b.tar.gz
nextcloud-server-df6175ccb17cc6917c41fc6eb41b727ec81a920b.zip
feat(AppFramework): Add Route attribute
Signed-off-by: provokateurin <kate@provokateurin.de>
Diffstat (limited to 'lib/private/Route')
-rw-r--r--lib/private/Route/Router.php68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/private/Route/Router.php b/lib/private/Route/Router.php
index 9cf12f00185..e7e2a9f0e49 100644
--- a/lib/private/Route/Router.php
+++ b/lib/private/Route/Router.php
@@ -14,6 +14,7 @@
* @author Robin McCorkell <robin@mccorkell.me.uk>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Kate Döen <kate.doeen@nextcloud.com>
*
* @license AGPL-3.0
*
@@ -32,8 +33,10 @@
*/
namespace OC\Route;
+use DirectoryIterator;
use OC\AppFramework\Routing\RouteParser;
use OCP\AppFramework\App;
+use OCP\AppFramework\Http\Attribute\Route as RouteAttribute;
use OCP\Diagnostics\IEventLogger;
use OCP\IConfig;
use OCP\IRequest;
@@ -41,6 +44,9 @@ use OCP\Route\IRouter;
use OCP\Util;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
+use ReflectionAttribute;
+use ReflectionClass;
+use ReflectionException;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Generator\UrlGenerator;
@@ -150,6 +156,22 @@ class Router implements IRouter {
}
}
$this->eventLogger->start('route:load:' . $requestedApp, 'Loading Routes for ' . $requestedApp);
+
+ if ($requestedApp !== null) {
+ $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);
+ }
+ }
+
foreach ($routingFiles as $app => $file) {
if (!isset($this->loadedApps[$app])) {
if (!\OC_App::isAppLoaded($app)) {
@@ -173,6 +195,7 @@ class Router implements IRouter {
if (!isset($this->loadedApps['core'])) {
$this->loadedApps['core'] = true;
$this->useCollection('root');
+ $this->setupRoutes($this->getAttributeRoutes('core'), 'core');
require_once __DIR__ . '/../../../core/routes.php';
// Also add the OCS collection
@@ -420,6 +443,51 @@ class Router implements IRouter {
}
/**
+ * @throws ReflectionException
+ */
+ private function getAttributeRoutes(string $app): array {
+ $routes = [];
+
+ if ($app === 'core') {
+ $appControllerPath = __DIR__ . '/../../../core/Controller';
+ $appNameSpace = 'OC\\Core';
+ } else {
+ $appControllerPath = \OC_App::getAppPath($app) . '/lib/Controller';
+ $appNameSpace = App::buildAppNamespace($app);
+ }
+
+ if (!file_exists($appControllerPath)) {
+ return [];
+ }
+
+ $dir = new DirectoryIterator($appControllerPath);
+ foreach ($dir as $file) {
+ if (!str_ends_with($file->getPathname(), 'Controller.php')) {
+ continue;
+ }
+
+ $class = new ReflectionClass($appNameSpace . '\\Controller\\' . basename($file->getPathname(), '.php'));
+
+ foreach ($class->getMethods() as $method) {
+ foreach ($method->getAttributes(RouteAttribute::class, ReflectionAttribute::IS_INSTANCEOF) as $attribute) {
+ $route = $attribute->newInstance();
+
+ $serializedRoute = $route->toArray();
+ // Remove 'Controller' suffix
+ $serializedRoute['name'] = substr($class->getShortName(), 0, -10) . '#' . $method->getName();
+
+ $key = $route->getType();
+
+ $routes[$key] ??= [];
+ $routes[$key][] = $serializedRoute;
+ }
+ }
+ }
+
+ return $routes;
+ }
+
+ /**
* To isolate the variable scope used inside the $file it is required in it's own method
*
* @param string $file the route file location to include