2018-02-01 20:01:12 +00:00
< ? 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 ;
2019-01-18 18:33:28 +00:00
use Symfony\Component\Config\Exception\LoaderLoadException ;
2018-02-01 20:01:12 +00:00
use Symfony\Component\Config\Loader\LoaderInterface ;
use Symfony\Component\Config\Resource\ResourceInterface ;
2022-03-10 11:54:29 +00:00
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator ;
trigger_deprecation ( 'symfony/routing' , '5.1' , 'The "%s" class is deprecated, use "%s" instead.' , RouteCollectionBuilder :: class , RoutingConfigurator :: class );
2018-02-01 20:01:12 +00:00
/**
* Helps add and import routes into a RouteCollection .
*
* @ author Ryan Weaver < ryan @ knpuniversity . com >
2022-03-10 11:54:29 +00:00
*
* @ deprecated since Symfony 5.1 , use RoutingConfigurator instead
2018-02-01 20:01:12 +00:00
*/
class RouteCollectionBuilder
{
/**
* @ var Route [] | RouteCollectionBuilder []
*/
2019-06-11 11:29:32 +00:00
private $routes = [];
2018-02-01 20:01:12 +00:00
private $loader ;
2019-06-11 11:29:32 +00:00
private $defaults = [];
2018-02-01 20:01:12 +00:00
private $prefix ;
private $host ;
private $condition ;
2019-06-11 11:29:32 +00:00
private $requirements = [];
private $options = [];
2018-02-01 20:01:12 +00:00
private $schemes ;
private $methods ;
2019-06-11 11:29:32 +00:00
private $resources = [];
2018-02-01 20:01:12 +00:00
public function __construct ( LoaderInterface $loader = null )
{
$this -> loader = $loader ;
}
/**
* Import an external routing resource and returns the RouteCollectionBuilder .
*
2018-10-14 19:50:32 +00:00
* $routes -> import ( 'blog.yml' , '/blog' );
2018-02-01 20:01:12 +00:00
*
2022-03-10 11:54:29 +00:00
* @ param mixed $resource
2018-02-01 20:01:12 +00:00
*
* @ return self
*
2019-01-18 18:33:28 +00:00
* @ throws LoaderLoadException
2018-02-01 20:01:12 +00:00
*/
2022-03-10 11:54:29 +00:00
public function import ( $resource , string $prefix = '/' , string $type = null )
2018-02-01 20:01:12 +00:00
{
2018-10-14 19:50:32 +00:00
/** @var RouteCollection[] $collections */
2018-02-01 20:01:12 +00:00
$collections = $this -> load ( $resource , $type );
// create a builder from the RouteCollection
$builder = $this -> createBuilder ();
foreach ( $collections as $collection ) {
if ( null === $collection ) {
continue ;
}
foreach ( $collection -> all () as $name => $route ) {
$builder -> addRoute ( $route , $name );
}
foreach ( $collection -> getResources () as $resource ) {
$builder -> addResource ( $resource );
}
}
// mount into this builder
$this -> mount ( $prefix , $builder );
return $builder ;
}
/**
* Adds a route and returns it for future modification .
*
* @ return Route
*/
2022-03-10 11:54:29 +00:00
public function add ( string $path , string $controller , string $name = null )
2018-02-01 20:01:12 +00:00
{
$route = new Route ( $path );
$route -> setDefault ( '_controller' , $controller );
$this -> addRoute ( $route , $name );
return $route ;
}
/**
* Returns a RouteCollectionBuilder that can be configured and then added with mount () .
*
* @ return self
*/
public function createBuilder ()
{
return new self ( $this -> loader );
}
/**
* Add a RouteCollectionBuilder .
*/
2022-03-10 11:54:29 +00:00
public function mount ( string $prefix , self $builder )
2018-02-01 20:01:12 +00:00
{
$builder -> prefix = trim ( trim ( $prefix ), '/' );
$this -> routes [] = $builder ;
}
/**
* Adds a Route object to the builder .
*
* @ return $this
*/
2022-03-10 11:54:29 +00:00
public function addRoute ( Route $route , string $name = null )
2018-02-01 20:01:12 +00:00
{
if ( null === $name ) {
// used as a flag to know which routes will need a name later
$name = '_unnamed_route_' . spl_object_hash ( $route );
}
$this -> routes [ $name ] = $route ;
return $this ;
}
/**
* Sets the host on all embedded routes ( unless already set ) .
*
* @ return $this
*/
2022-03-10 11:54:29 +00:00
public function setHost ( ? string $pattern )
2018-02-01 20:01:12 +00:00
{
$this -> host = $pattern ;
return $this ;
}
/**
* Sets a condition on all embedded routes ( unless already set ) .
*
* @ return $this
*/
2022-03-10 11:54:29 +00:00
public function setCondition ( ? string $condition )
2018-02-01 20:01:12 +00:00
{
$this -> condition = $condition ;
return $this ;
}
/**
* Sets a default value that will be added to all embedded routes ( unless that
* default value is already set ) .
*
2022-03-10 11:54:29 +00:00
* @ param mixed $value
2018-02-01 20:01:12 +00:00
*
* @ return $this
*/
2022-03-10 11:54:29 +00:00
public function setDefault ( string $key , $value )
2018-02-01 20:01:12 +00:00
{
$this -> defaults [ $key ] = $value ;
return $this ;
}
/**
* Sets a requirement that will be added to all embedded routes ( unless that
* requirement is already set ) .
*
2022-03-10 11:54:29 +00:00
* @ param mixed $regex
2018-02-01 20:01:12 +00:00
*
* @ return $this
*/
2022-03-10 11:54:29 +00:00
public function setRequirement ( string $key , $regex )
2018-02-01 20:01:12 +00:00
{
$this -> requirements [ $key ] = $regex ;
return $this ;
}
/**
* Sets an option that will be added to all embedded routes ( unless that
* option is already set ) .
*
2022-03-10 11:54:29 +00:00
* @ param mixed $value
2018-02-01 20:01:12 +00:00
*
* @ return $this
*/
2022-03-10 11:54:29 +00:00
public function setOption ( string $key , $value )
2018-02-01 20:01:12 +00:00
{
$this -> options [ $key ] = $value ;
return $this ;
}
/**
* Sets the schemes on all embedded routes ( unless already set ) .
*
* @ param array | string $schemes
*
* @ return $this
*/
public function setSchemes ( $schemes )
{
$this -> schemes = $schemes ;
return $this ;
}
/**
* Sets the methods on all embedded routes ( unless already set ) .
*
* @ param array | string $methods
*
* @ return $this
*/
public function setMethods ( $methods )
{
$this -> methods = $methods ;
return $this ;
}
/**
* Adds a resource for this collection .
*
* @ return $this
*/
2018-10-14 19:50:32 +00:00
private function addResource ( ResourceInterface $resource ) : self
2018-02-01 20:01:12 +00:00
{
$this -> resources [] = $resource ;
return $this ;
}
/**
* Creates the final RouteCollection and returns it .
*
* @ return RouteCollection
*/
public function build ()
{
$routeCollection = new RouteCollection ();
foreach ( $this -> routes as $name => $route ) {
if ( $route instanceof Route ) {
$route -> setDefaults ( array_merge ( $this -> defaults , $route -> getDefaults ()));
$route -> setOptions ( array_merge ( $this -> options , $route -> getOptions ()));
foreach ( $this -> requirements as $key => $val ) {
if ( ! $route -> hasRequirement ( $key )) {
$route -> setRequirement ( $key , $val );
}
}
if ( null !== $this -> prefix ) {
$route -> setPath ( '/' . $this -> prefix . $route -> getPath ());
}
if ( ! $route -> getHost ()) {
$route -> setHost ( $this -> host );
}
if ( ! $route -> getCondition ()) {
$route -> setCondition ( $this -> condition );
}
if ( ! $route -> getSchemes ()) {
$route -> setSchemes ( $this -> schemes );
}
if ( ! $route -> getMethods ()) {
$route -> setMethods ( $this -> methods );
}
// auto-generate the route name if it's been marked
if ( '_unnamed_route_' === substr ( $name , 0 , 15 )) {
$name = $this -> generateRouteName ( $route );
}
$routeCollection -> add ( $name , $route );
} else {
/* @var self $route */
$subCollection = $route -> build ();
2022-03-10 11:54:29 +00:00
if ( null !== $this -> prefix ) {
$subCollection -> addPrefix ( $this -> prefix );
}
2018-02-01 20:01:12 +00:00
$routeCollection -> addCollection ( $subCollection );
}
}
foreach ( $this -> resources as $resource ) {
$routeCollection -> addResource ( $resource );
}
return $routeCollection ;
}
/**
* Generates a route name based on details of this route .
*/
2018-10-14 19:50:32 +00:00
private function generateRouteName ( Route $route ) : string
2018-02-01 20:01:12 +00:00
{
$methods = implode ( '_' , $route -> getMethods ()) . '_' ;
$routeName = $methods . $route -> getPath ();
2019-06-11 11:29:32 +00:00
$routeName = str_replace ([ '/' , ':' , '|' , '-' ], '_' , $routeName );
2018-02-01 20:01:12 +00:00
$routeName = preg_replace ( '/[^a-z0-9A-Z_.]+/' , '' , $routeName );
// Collapse consecutive underscores down into a single underscore.
$routeName = preg_replace ( '/_+/' , '_' , $routeName );
return $routeName ;
}
/**
* Finds a loader able to load an imported resource and loads it .
*
* @ param mixed $resource A resource
* @ param string | null $type The resource type or null if unknown
*
* @ return RouteCollection []
*
2019-01-18 18:33:28 +00:00
* @ throws LoaderLoadException If no loader is found
2018-02-01 20:01:12 +00:00
*/
2018-10-14 19:50:32 +00:00
private function load ( $resource , string $type = null ) : array
2018-02-01 20:01:12 +00:00
{
if ( null === $this -> loader ) {
throw new \BadMethodCallException ( 'Cannot import other routing resources: you must pass a LoaderInterface when constructing RouteCollectionBuilder.' );
}
if ( $this -> loader -> supports ( $resource , $type )) {
$collections = $this -> loader -> load ( $resource , $type );
2019-06-11 11:29:32 +00:00
return \is_array ( $collections ) ? $collections : [ $collections ];
2018-02-01 20:01:12 +00:00
}
if ( null === $resolver = $this -> loader -> getResolver ()) {
2022-03-10 11:54:29 +00:00
throw new LoaderLoadException ( $resource , null , 0 , null , $type );
2018-02-01 20:01:12 +00:00
}
if ( false === $loader = $resolver -> resolve ( $resource , $type )) {
2022-03-10 11:54:29 +00:00
throw new LoaderLoadException ( $resource , null , 0 , null , $type );
2018-02-01 20:01:12 +00:00
}
$collections = $loader -> load ( $resource , $type );
2019-06-11 11:29:32 +00:00
return \is_array ( $collections ) ? $collections : [ $collections ];
2018-02-01 20:01:12 +00:00
}
}