dumper = $dumper; $this->lock = $lock; $this->dispatcher = $dispatcher; $this->moduleHandler = $module_handler; $this->controllerResolver = $controller_resolver; } /** * Rebuilds the route info and dumps to dumper. * * @return bool * Returns TRUE if the rebuild succeeds, FALSE otherwise. */ public function rebuild() { if (!$this->lock->acquire('router_rebuild')) { // Wait for another request that is already doing this work. // We choose to block here since otherwise the routes might not be // available, resulting in a 404. $this->lock->wait('router_rebuild'); return FALSE; } $yaml_discovery = $this->getYamlDiscovery(); foreach ($yaml_discovery->findAll() as $provider => $routes) { $collection = new RouteCollection(); // The top-level 'routes_callback' is a list of methods in controller // syntax, see \Drupal\Core\Controller\ControllerResolver. These methods // should return a set of \Symfony\Component\Routing\Route objects, either // in an associative array keyed by the route name, which will be iterated // over and added to the collection for this provider, or as a new // \Symfony\Component\Routing\RouteCollection object, which will be added // to the collection. if (isset($routes['route_callbacks'])) { foreach ($routes['route_callbacks'] as $route_callback) { $callback = $this->controllerResolver->getControllerFromDefinition($route_callback); if ($callback_routes = call_user_func($callback)) { // If a RouteCollection is returned, add the whole collection. if ($callback_routes instanceof RouteCollection) { $collection->addCollection($callback_routes); } // Otherwise, add each Route object individually. else { foreach ($callback_routes as $name => $callback_route) { $collection->add($name, $callback_route); } } } } unset($routes['route_callbacks']); } foreach ($routes as $name => $route_info) { $route_info += array( 'defaults' => array(), 'requirements' => array(), 'options' => array(), ); $route = new Route($route_info['path'], $route_info['defaults'], $route_info['requirements'], $route_info['options']); $collection->add($name, $route); } $this->dispatcher->dispatch(RoutingEvents::ALTER, new RouteBuildEvent($collection, $provider)); $this->dumper->addRoutes($collection); $this->dumper->dump(array('provider' => $provider)); } // Now allow modules to register additional, dynamic routes. // @todo Either remove this alter or the per-provider alter. $collection = new RouteCollection(); $this->dispatcher->dispatch(RoutingEvents::ALTER, new RouteBuildEvent($collection, 'dynamic_routes')); $this->dumper->addRoutes($collection); $this->dumper->dump(array('provider' => 'dynamic_routes')); $this->lock->release('router_rebuild'); $this->dispatcher->dispatch(RoutingEvents::FINISHED, new Event()); return TRUE; } /** * Returns the YAML discovery for getting all the .routing.yml files. * * @return \Drupal\Component\Discovery\YamlDiscovery * The yaml discovery. */ protected function getYamlDiscovery() { if (!isset($this->yamlDiscovery)) { $this->yamlDiscovery = new YamlDiscovery('routing', $this->moduleHandler->getModuleDirectories()); } return $this->yamlDiscovery; } }