diff options
author | provokateurin <kate@provokateurin.de> | 2024-01-10 12:35:09 +0100 |
---|---|---|
committer | provokateurin <kate@provokateurin.de> | 2024-02-21 12:07:50 +0100 |
commit | df6175ccb17cc6917c41fc6eb41b727ec81a920b (patch) | |
tree | 67c8b8a6c9801c497951ed3150a610eb992c8daa /lib/private/Route | |
parent | 66e7056c5ebd1538ca94ab3a1f04b6bf184170cb (diff) | |
download | nextcloud-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.php | 68 |
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 |