2016-11-30 14:08:10 +01:00
< ? php
/*
2016-12-29 12:09:26 +01:00
* This file is part of the NelmioApiDocBundle package .
2016-11-30 14:08:10 +01:00
*
2016-12-29 12:09:26 +01:00
* ( c ) Nelmio
2016-11-30 14:08:10 +01:00
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
2016-12-29 12:09:26 +01:00
namespace Nelmio\ApiDocBundle\Routing ;
2016-11-30 14:08:10 +01:00
2019-01-05 16:37:43 +01:00
use Doctrine\Common\Annotations\Reader ;
use Nelmio\ApiDocBundle\Annotation\Areas ;
use Nelmio\ApiDocBundle\Util\ControllerReflector ;
2018-03-13 12:40:36 -03:00
use Symfony\Component\OptionsResolver\OptionsResolver ;
2016-11-30 14:08:10 +01:00
use Symfony\Component\Routing\Route ;
use Symfony\Component\Routing\RouteCollection ;
final class FilteredRouteCollectionBuilder
{
2019-01-05 16:37:43 +01:00
/** @var Reader */
private $annotationReader ;
/** @var ControllerReflector */
private $controllerReflector ;
/** @var string */
private $area ;
/** @var array */
2018-03-13 12:40:36 -03:00
private $options ;
2016-11-30 14:08:10 +01:00
2019-01-05 16:37:43 +01:00
public function __construct (
Reader $annotationReader ,
ControllerReflector $controllerReflector ,
string $area ,
array $options = []
) {
2018-03-13 12:40:36 -03:00
$resolver = new OptionsResolver ();
$resolver
-> setDefaults ([
'path_patterns' => [],
'host_patterns' => [],
2019-04-16 18:22:51 +03:00
'name_patterns' => [],
2019-01-05 16:37:43 +01:00
'with_annotation' => false ,
2018-03-13 12:40:36 -03:00
])
-> setAllowedTypes ( 'path_patterns' , 'string[]' )
-> setAllowedTypes ( 'host_patterns' , 'string[]' )
2019-04-16 18:22:51 +03:00
-> setAllowedTypes ( 'name_patterns' , 'string[]' )
2019-01-05 16:37:43 +01:00
-> setAllowedTypes ( 'with_annotation' , 'boolean' )
2018-03-13 12:40:36 -03:00
;
if ( array_key_exists ( 0 , $options )) {
@ trigger_error ( sprintf ( 'Passing an indexed array with a collection of path patterns as argument 1 for `%s()` is deprecated since 3.2.0, expected structure is an array containing parameterized options.' , __METHOD__ ), E_USER_DEPRECATED );
$normalizedOptions = [ 'path_patterns' => $options ];
$options = $normalizedOptions ;
}
2019-01-05 16:37:43 +01:00
$this -> annotationReader = $annotationReader ;
$this -> controllerReflector = $controllerReflector ;
$this -> area = $area ;
2018-03-13 12:40:36 -03:00
$this -> options = $resolver -> resolve ( $options );
2016-11-30 14:08:10 +01:00
}
public function filter ( RouteCollection $routes ) : RouteCollection
{
$filteredRoutes = new RouteCollection ();
foreach ( $routes -> all () as $name => $route ) {
2019-04-16 18:22:51 +03:00
if ( $this -> matchPath ( $route )
&& $this -> matchHost ( $route )
&& $this -> matchAnnotation ( $route )
&& $this -> matchName ( $name )
) {
2016-11-30 14:08:10 +01:00
$filteredRoutes -> add ( $name , $route );
}
}
return $filteredRoutes ;
}
2018-03-13 12:40:36 -03:00
private function matchPath ( Route $route ) : bool
2016-11-30 14:08:10 +01:00
{
2018-03-13 12:40:36 -03:00
foreach ( $this -> options [ 'path_patterns' ] as $pathPattern ) {
2017-06-07 13:55:32 +02:00
if ( preg_match ( '{' . $pathPattern . '}' , $route -> getPath ())) {
return true ;
2016-11-30 14:08:10 +01:00
}
}
2018-03-13 12:40:36 -03:00
return 0 === count ( $this -> options [ 'path_patterns' ]);
}
private function matchHost ( Route $route ) : bool
{
foreach ( $this -> options [ 'host_patterns' ] as $hostPattern ) {
if ( preg_match ( '{' . $hostPattern . '}' , $route -> getHost ())) {
return true ;
}
}
return 0 === count ( $this -> options [ 'host_patterns' ]);
2016-11-30 14:08:10 +01:00
}
2019-01-05 16:37:43 +01:00
2019-04-16 18:22:51 +03:00
private function matchName ( string $name ) : bool
{
foreach ( $this -> options [ 'name_patterns' ] as $namePattern ) {
if ( preg_match ( '{' . $namePattern . '}' , $name )) {
return true ;
}
}
return 0 === count ( $this -> options [ 'name_patterns' ]);
}
2019-01-05 16:37:43 +01:00
private function matchAnnotation ( Route $route ) : bool
{
if ( false === $this -> options [ 'with_annotation' ]) {
return true ;
}
$method = $this -> controllerReflector -> getReflectionMethod (
$route -> getDefault ( '_controller' ) ? ? ''
);
if ( null === $method ) {
return false ;
}
2020-08-06 10:26:59 +02:00
/** @var Areas|null $areas */
2019-01-05 16:37:43 +01:00
$areas = $this -> annotationReader -> getMethodAnnotation (
$method ,
Areas :: class
);
return ( null !== $areas ) ? $areas -> has ( $this -> area ) : false ;
}
2016-11-30 14:08:10 +01:00
}