├── README.md ├── composer.json └── src ├── Contract └── Routing │ ├── ModularRouterInterface.php │ └── RouteCollectionProviderInterface.php ├── DependencyInjection ├── CompilerPass │ └── AddRouteCollectionProvidersCompilerPass.php └── Extension │ └── SymplifyModularRoutingExtension.php ├── Exception └── FileNotFoundException.php ├── Resources └── config │ └── services.yml ├── Routing ├── AbstractRouteCollectionProvider.php └── ModularRouter.php └── SymplifyModularRoutingBundle.php /README.md: -------------------------------------------------------------------------------- 1 | # Modular Routing 2 | 3 | [![Build Status](https://img.shields.io/travis/Symplify/ModularRouting/master.svg?style=flat-square)](https://travis-ci.org/Symplify/ModularRouting) 4 | [![Downloads](https://img.shields.io/packagist/dt/symplify/modular-routing.svg?style=flat-square)](https://packagist.org/packages/symplify/modular-routing) 5 | 6 | To add routes you usually need to add few lines to `app/config/routing.yml`. If you have over dozens of modules, it would be easy to get lost in it. To see all options on how to do that including this package, read [this short article](http://www.tomasvotruba.cz/blog/2016/02/25/modular-routing-in-symfony). 7 | 8 | 9 | **Thanks to this router, you can add them easily as via service loader**. 10 | 11 | 12 | ## Install 13 | 14 | ```bash 15 | composer require symplify/modular-routing 16 | ``` 17 | 18 | Add bundle to `AppKernel.php`: 19 | 20 | ```php 21 | final class AppKernel extends Kernel 22 | { 23 | public function registerBundles(): array 24 | { 25 | $bundles = [ 26 | new Symfony\Bundle\FrameworkBundle\FrameworkBundle(), 27 | new Symfony\Cmf\Bundle\RoutingBundle\CmfRoutingBundle(), 28 | new Symplify\ModularRouting\SymplifyModularRoutingBundle(), 29 | // ... 30 | ]; 31 | } 32 | } 33 | ``` 34 | 35 | 36 | ## Usage 37 | 38 | 1. Implement [`RouteCollectionProviderInterface`](src/Contract/Routing/RouteCollectionProviderInterface.php) 39 | 40 | ```php 41 | use Symfony\Component\Routing\Route; 42 | use Symfony\Component\Routing\RouteCollection; 43 | use Symplify\ModularRouting\Contract\Routing\RouteCollectionProviderInterface; 44 | 45 | final class SomeRouteCollectionProvider implements RouteCollectionProviderInterface 46 | { 47 | public function getRouteCollection() : RouteCollection 48 | { 49 | $routeCollection = new RouteCollection(); 50 | $routeCollection->add('my_route', new Route('/hello')); 51 | 52 | return $routeCollection; 53 | } 54 | } 55 | ``` 56 | 57 | 2. Register service 58 | 59 | ```yml 60 | services: 61 | some_module.route_provider: 62 | class: SomeModule\Routing\SomeRouteCollectionProvider 63 | autowire: true # or better use Symplify\DefaultAutowire package 64 | ``` 65 | 66 | That's all! 67 | 68 | 69 | ### Loading YML/XML files 70 | 71 | In case you want to load these files, just use [`AbstractRouteCollectionProvider`](src/Routing/AbstractRouteCollectionProvider.php) 72 | with helper methods. 73 | 74 | ```php 75 | use Symfony\Component\Routing\RouteCollection; 76 | use Symplify\ModularRouting\Routing\AbstractRouteCollectionProvider; 77 | 78 | final class FilesRouteCollectionProvider extends AbstractRouteCollectionProvider 79 | { 80 | public function getRouteCollection(): RouteCollection 81 | { 82 | return $this->loadRouteCollectionFromFiles([ 83 | __DIR__ . '/routes.xml', 84 | __DIR__ . '/routes.yml', 85 | ]); 86 | 87 | // on in case you have only 1 file 88 | // return $this->loadRouteCollectionFromFile(__DIR__ . '/routes.yml'); 89 | } 90 | } 91 | 92 | ``` 93 | 94 | 95 | ## Contributing 96 | 97 | Send [issue](https://github.com/Symplify/Symplify/issues) or [pull-request](https://github.com/Symplify/Symplify/pulls) to main repository. 98 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "symplify/modular-routing", 3 | "description": "Load your Symfony routes with a simple service.", 4 | "license": "MIT", 5 | "require": { 6 | "php": "^7.1", 7 | "symfony/dependency-injection": "^3.3", 8 | "symfony/framework-bundle": "^3.3", 9 | "symfony/http-kernel": "^3.3", 10 | "symfony/routing": "^3.3", 11 | "symfony/twig-bundle": "^3.3", 12 | "symfony/yaml": "^3.3", 13 | "symfony-cmf/routing-bundle": "^2.0", 14 | "doctrine/doctrine-bundle": "^1.6", 15 | "symplify/package-builder": "v2.0.0-RC3 as 1.4" 16 | }, 17 | "require-dev": { 18 | "nette/utils": "^2.4|^3.0", 19 | "nette/finder": "^2.4|^3.0", 20 | "phpunit/phpunit": "^6.0", 21 | "symfony/asset": "^3.3", 22 | "symfony/form": "^3.3", 23 | "symfony/translation": "^3.3", 24 | "symfony/templating": "^3.3", 25 | "symfony/validator": "^3.3", 26 | "twig/twig": "^2.2", 27 | "doctrine/annotations": "^1.4" 28 | }, 29 | "autoload": { 30 | "psr-4": { 31 | "Symplify\\ModularRouting\\": "src" 32 | } 33 | }, 34 | "autoload-dev": { 35 | "psr-4": { 36 | "Symplify\\ModularRouting\\Tests\\": "tests" 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Contract/Routing/ModularRouterInterface.php: -------------------------------------------------------------------------------- 1 | load('services.yml'); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Exception/FileNotFoundException.php: -------------------------------------------------------------------------------- 1 | loaderResolver = $loaderResolver; 20 | } 21 | 22 | protected function loadRouteCollectionFromFile(string $path): RouteCollection 23 | { 24 | $this->ensureFileExists($path); 25 | 26 | $loader = $this->loaderResolver->resolve($path); 27 | if ($loader === null) { 28 | return new RouteCollection; 29 | } 30 | 31 | return $loader->load($path); 32 | } 33 | 34 | /** 35 | * @param string[] $paths 36 | */ 37 | protected function loadRouteCollectionFromFiles(array $paths): RouteCollection 38 | { 39 | $routeCollection = new RouteCollection; 40 | 41 | foreach ($paths as $path) { 42 | $routeCollection->addCollection($this->loadRouteCollectionFromFile($path)); 43 | } 44 | 45 | return $routeCollection; 46 | } 47 | 48 | private function ensureFileExists(string $path): void 49 | { 50 | if (! file_exists($path)) { 51 | throw new FileNotFoundException( 52 | sprintf('File "%s" was not found.', $path) 53 | ); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Routing/ModularRouter.php: -------------------------------------------------------------------------------- 1 | routeCollection = new RouteCollection; 39 | } 40 | 41 | public function addRouteCollectionProvider(RouteCollectionProviderInterface $routeCollectionProvider): void 42 | { 43 | $this->routeCollection->addCollection($routeCollectionProvider->getRouteCollection()); 44 | } 45 | 46 | public function getRouteCollection(): RouteCollection 47 | { 48 | return $this->routeCollection; 49 | } 50 | 51 | public function setContext(RequestContext $requestContext): void 52 | { 53 | $this->requestContext = $requestContext; 54 | } 55 | 56 | /** 57 | * @param string $name 58 | * @param mixed[] $parameters 59 | * @param int $referenceType 60 | */ 61 | public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH): string 62 | { 63 | return $this->getUrlGenerator() 64 | ->generate($name, $parameters, $referenceType); 65 | } 66 | 67 | /** 68 | * @param string $pathinfo 69 | * @return array[] 70 | */ 71 | public function match($pathinfo): array 72 | { 73 | return $this->getUrlMatcher() 74 | ->match($pathinfo); 75 | } 76 | 77 | public function getContext(): string 78 | { 79 | // this method is never used 80 | return '...'; 81 | } 82 | 83 | private function getUrlGenerator(): UrlGeneratorInterface 84 | { 85 | if ($this->urlGenerator) { 86 | return $this->urlGenerator; 87 | } 88 | 89 | return $this->urlGenerator = new UrlGenerator($this->getRouteCollection(), $this->requestContext); 90 | } 91 | 92 | private function getUrlMatcher(): UrlMatcherInterface 93 | { 94 | if ($this->urlMatcher) { 95 | return $this->urlMatcher; 96 | } 97 | 98 | return $this->urlMatcher = new UrlMatcher($this->getRouteCollection(), $this->requestContext); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /src/SymplifyModularRoutingBundle.php: -------------------------------------------------------------------------------- 1 | addCompilerPass(new AddRouteCollectionProvidersCompilerPass); 20 | } 21 | } 22 | --------------------------------------------------------------------------------