3 namespace Drupal\Core\Routing;
5 use Symfony\Cmf\Component\Routing\NestedMatcher\RouteFilterInterface as BaseRouteFilterInterface;
6 use Symfony\Component\DependencyInjection\ContainerAwareInterface;
7 use Symfony\Component\DependencyInjection\ContainerAwareTrait;
8 use Symfony\Component\DependencyInjection\ContainerInterface;
9 use Symfony\Component\HttpFoundation\Request;
10 use Symfony\Component\Routing\RouteCollection;
13 * A route filter which lazily loads route filters, depending on the route.
15 * We lazy initialize route filters, because otherwise all dependencies of all
16 * route filters are initialized on every request, which is slow. However, with
17 * the use of lazy loading, dependencies are instantiated only when used.
19 class LazyRouteFilter implements BaseRouteFilterInterface, ContainerAwareInterface {
21 use ContainerAwareTrait;
24 * Array of route filter service IDs.
28 protected $serviceIds = [];
31 * The initialized route filters.
33 * @var \Drupal\Core\Routing\RouteFilterInterface[]
35 protected $filters = NULL;
38 * Constructs the LazyRouteEnhancer object.
41 * Array of route filter service IDs.
43 public function __construct($service_ids) {
44 $this->serviceIds = $service_ids;
48 * For each route, filter down the route collection.
50 * @param \Symfony\Component\Routing\RouteCollection $route_collection
51 * A collection of routes to apply filter checks to.
53 public function setFilters(RouteCollection $route_collection) {
54 /** @var \Symfony\Component\Routing\Route $route **/
55 foreach ($route_collection as $route) {
57 foreach ($this->getFilters() as $service_id => $filter) {
58 if ($filter instanceof RouteFilterInterface && $filter->applies($route)) {
59 $service_ids[] = $service_id;
63 $route->setOption('_route_filters', array_unique($service_ids));
69 * For each route, gets a list of applicable enhancers to the route.
71 * @return \Symfony\Cmf\Component\Routing\Enhancer\RouteEnhancerInterface[]|\Drupal\Core\Routing\Enhancer\RouteEnhancerInterface[]
73 protected function getFilters() {
74 if (!isset($this->filters)) {
75 foreach ($this->serviceIds as $service_id) {
76 $this->filters[$service_id] = $this->container->get($service_id);
79 return $this->filters;
85 public function filter(RouteCollection $collection, Request $request) {
87 foreach ($collection->all() as $route) {
88 $filter_ids = array_merge($filter_ids, $route->getOption('_route_filters') ?: []);
90 $filter_ids = array_unique($filter_ids);
92 if (isset($filter_ids)) {
93 foreach ($filter_ids as $filter_id) {
94 if ($filter = $this->container->get($filter_id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
95 $collection = $filter->filter($collection, $request);