diff --git a/config/routes.php b/config/routes.php index 539dfced56..3e6d28815b 100644 --- a/config/routes.php +++ b/config/routes.php @@ -1,10 +1,7 @@ add('network.public', '/main/all') - ->controller(NetworkPublic::class); + $routes->import('.', 'GNUsocial'); }; diff --git a/config/services.yaml b/config/services.yaml index 2d483616e2..97d023375a 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -15,7 +15,7 @@ services: # this creates a service per class whose id is the fully-qualified class name App\: resource: '../src/*' - exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}' + exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php,Routes}' # controllers are imported separately to make sure services can be injected # as action arguments even if you don't extend any base controller class @@ -23,8 +23,9 @@ services: resource: '../src/Controller' tags: ['controller.service_arguments'] - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones + App\Util\RouteLoader: + tags: ['routing.loader'] + # Wrapper arround Doctrine's StaticPHP metadata driver app.util.schemadef_driver: diff --git a/src/Routes/Main.php b/src/Routes/Main.php new file mode 100644 index 0000000000..b1745bb128 --- /dev/null +++ b/src/Routes/Main.php @@ -0,0 +1,13 @@ +connect('main_all', '/main/all', \App\Controller\NetworkPublic::class); + } +} diff --git a/src/Util/RouteLoader.php b/src/Util/RouteLoader.php new file mode 100644 index 0000000000..1b22de9d2d --- /dev/null +++ b/src/Util/RouteLoader.php @@ -0,0 +1,118 @@ +. + +/** + * Old URLMapper interface atop Symfony's router + * + * Converts a path into a set of parameters, and vice versa + * + * @package GNUsocial + * @category URL + * + * @author Hugo Sales + * @copyright 2020 Free Software Foundation, Inc http://www.fsf.org + * @license https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later + */ + +namespace App\Util; + +use Symfony\Component\Config\Loader\Loader; +use Symfony\Component\Routing\Route; +use Symfony\Component\Routing\RouteCollection; + +class RouteLoader extends Loader +{ + private RouteCollection $rc; + + /** + * Route loading entry point, called from `config/routes.php` + * + * Must comform to symfony's interface, but the $resource is unused + * and $type must not be null + * + * @param mixed $resource + */ + public function load($resource, string $type = null): RouteCollection + { + $this->rc = new RouteCollection(); + + $route_files = glob(INSTALLDIR . '/src/Routes/*.php'); + foreach ($route_files as $file) { + require_once $file; + $ns = '\\App\\Routes\\' . basename($file, '.php'); + $ns::load($this); + } + + return $this->rc; + } + + /** + * Connect a route to a controller + * + * @param mixed $target Some kind of callable, typically [object, method] + * @param ?array $options Possible keys are ['condition', 'defaults', 'format', + * 'fragment', 'http-methods', 'locale', 'methods', 'schemes'] + * 'http-methods' and 'methods' are aliases + */ + public function connect(string $id, string $uri_path, $target, ?array $param_reqs = [], ?array $options = []) + { + $this->rc->add($id, + new Route( + // path -- URI path + $uri_path, + // defaults = [] -- param default values, + // and special configuration options + array_merge( + [ + '_controller' => is_array($target) ? $target : [$target, '__invoke'], + '_format' => $options['format'] ?? 'html', + '_fragment' => $options['fragment'] ?? '', + '_locale' => $options['locale'] ?? '', + ], + $options['defaults'] ?? []), + // requirements = [] -- param => regex + $param_reqs, + // options = [] -- possible keys: compiler_class:, utf8 + // No need for a special compiler class for now, + // Enforce UTF8 + ['utf8' => true], + // host = '' -- hostname (subdomain, for instance) to match, + // we don't want this + '', + // schemes = [] -- URI schemes (https, ftp and such) + $options['schemes'] ?? [], + // methods = [] -- HTTP methods + $options['http-methods'] ?? $options['methods'] ?? [], + // condition = '' -- Symfony condition expression, + // see https://symfony.com/doc/current/routing.html#matching-expressions + $options['condition'] ?? '' + ) + ); + } + + /** + * Whether this loader supports loading this route type + * Passed the arguments from the `RoutingConfigurator::import` call from + * `config/routes.php` + * + * @param mixed $resource Unused + */ + public function supports($resource, string $type = null) + { + return 'GNUsocial' === $type; + } +}