Permalink
Browse files

feature #24180 [Routing] Add PHP fluent DSL for configuring routes (n…

…icolas-grekas)

This PR was merged into the 3.4 branch.

Discussion
----------

[Routing] Add PHP fluent DSL for configuring routes

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

If we add a PHP DSL for DI config (#23834), we must have a similar one for routing. Here it is. See fixtures.

So, you always start with a `RoutingConfigurator $routes`, which allows you to:
```php
$routes->add($name, $path); // adds a route
$routes->import($resource, $type = null, $ignoreErrors = false); // imports routes
$routes->collection($name = ''); // starts a collection, all *names* might be prefixed
```

then
- for "import" and "collection", you can `->prefix($path)`;
- for "add" and "collection", you can fluently "add" several times;
- for "collection" you add sub"`->collection()`";
- and on all, you can configure the route(s) with:
```php
->defaults(array $defaults)
->requirements(array $requirements)
->options(array $options)
->condition($condition)
->host($pattern)
->schemes(array $schemes)
->methods(array $methods)
->controller($controller)
```

Commits
-------

f433c9a [Routing] Add PHP fluent DSL for configuring routes
  • Loading branch information...
nicolas-grekas committed Sep 20, 2017
2 parents aad62c4 + f433c9a commit 20ecf91d5249b5cd80b111cca8b08c4bb9b0d561
@@ -0,0 +1,79 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Routing\Loader\Configurator;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class CollectionConfigurator
{
use Traits\AddTrait;
use Traits\RouteTrait;
private $parent;
public function __construct(RouteCollection $parent, $name)
{
$this->parent = $parent;
$this->name = $name;
$this->collection = new RouteCollection();
$this->route = new Route('');
}
public function __destruct()
{
$this->collection->addPrefix(rtrim($this->route->getPath(), '/'));
$this->parent->addCollection($this->collection);
}
/**
* Adds a route.
*
* @param string $name
* @param string $value
*
* @return RouteConfigurator
*/
final public function add($name, $path)
{
$this->collection->add($this->name.$name, $route = clone $this->route);
return new RouteConfigurator($this->collection, $route->setPath($path), $this->name);
}
/**
* Creates a sub-collection.
*
* @return self
*/
final public function collection($name = '')
{
return new self($this->collection, $this->name.$name);
}
/**
* Sets the prefix to add to the path of all child routes.
*
* @param string $prefix
*
* @return $this
*/
final public function prefix($prefix)
{
$this->route->setPath($prefix);
return $this;
}
}
@@ -0,0 +1,49 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Routing\Loader\Configurator;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class ImportConfigurator
{
use Traits\RouteTrait;
private $parent;
public function __construct(RouteCollection $parent, RouteCollection $route)
{
$this->parent = $parent;
$this->route = $route;
}
public function __destruct()
{
$this->parent->addCollection($this->route);
}
/**
* Sets the prefix to add to the path of all child routes.
*
* @param string $prefix
*
* @return $this
*/
final public function prefix($prefix)
{
$this->route->addPrefix($prefix);
return $this;
}
}
@@ -0,0 +1,31 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Routing\Loader\Configurator;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class RouteConfigurator
{
use Traits\AddTrait;
use Traits\RouteTrait;
public function __construct(RouteCollection $collection, Route $route, $name = '')
{
$this->collection = $collection;
$this->route = $route;
$this->name = $name;
}
}
@@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Routing\Loader\Configurator;
use Symfony\Component\Routing\Loader\PhpFileLoader;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*/
class RoutingConfigurator
{
use Traits\AddTrait;
private $loader;
private $path;
private $file;
public function __construct(RouteCollection $collection, PhpFileLoader $loader, $path, $file)
{
$this->collection = $collection;
$this->loader = $loader;
$this->path = $path;
$this->file = $file;
}
/**
* @return ImportConfigurator
*/
final public function import($resource, $type = null, $ignoreErrors = false)
{
$this->loader->setCurrentDir(dirname($this->path));
$subCollection = $this->loader->import($resource, $type, $ignoreErrors, $this->file);
return new ImportConfigurator($this->collection, $subCollection);
}
/**
* @return CollectionConfigurator
*/
final public function collection($name = '')
{
return new CollectionConfigurator($this->collection, $name);
}
}
@@ -0,0 +1,54 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Routing\Loader\Configurator\Traits;
use Symfony\Component\Routing\Loader\Configurator\RouteConfigurator;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
trait AddTrait
{
/**
* @var RouteCollection
*/
private $collection;
private $name = '';
/**
* Adds a route.
*
* @param string $name
* @param string $value
*
* @return RouteConfigurator
*/
final public function add($name, $path)
{
$this->collection->add($this->name.$name, $route = new Route($path));
return new RouteConfigurator($this->collection, $route);
}
/**
* Adds a route.
*
* @param string $name
* @param string $path
*
* @return RouteConfigurator
*/
final public function __invoke($name, $path)
{
return $this->add($name, $path);
}
}
Oops, something went wrong.

0 comments on commit 20ecf91

Please sign in to comment.