Commit 5a85df4c authored by catch's avatar catch

Issue #2230091 by dawehner, Berdir, marthinal, martin107: Fixed Route...

Issue #2230091 by dawehner, Berdir, marthinal, martin107: Fixed Route rebuilding is not guaranteed to finish in time for the next request.
parent 0ce0a356
......@@ -72,6 +72,13 @@ class RouteBuilder implements RouteBuilderInterface {
*/
protected $routeCollection;
/**
* Flag that indiciates if we are currently rebuilding the routes.
*
* @var bool
*/
protected $building = FALSE;
/**
* Constructs the RouteBuilder using the passed MatcherDumperInterface.
*
......@@ -101,6 +108,10 @@ public function __construct(MatcherDumperInterface $dumper, LockBackendInterface
* {@inheritdoc}
*/
public function rebuild() {
if ($this->building) {
throw new \RuntimeException('Recursive router rebuild detected.');
}
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
......@@ -109,6 +120,8 @@ public function rebuild() {
return FALSE;
}
$this->building = TRUE;
$collection = new RouteCollection();
$this->routeCollection = $collection;
foreach ($this->getRouteDefinitions() as $routes) {
......@@ -165,6 +178,7 @@ public function rebuild() {
$this->state->delete(static::REBUILD_NEEDED);
$this->lock->release('router_rebuild');
$this->dispatcher->dispatch(RoutingEvents::FINISHED, new Event());
$this->building = FALSE;
$this->routeCollection = NULL;
......
......@@ -172,8 +172,9 @@ public function getRoutesByNames($names) {
throw new \InvalidArgumentException('You must specify the route names to load');
}
$routes_to_load = array_diff($names, array_keys($this->routes));
$this->routeBuilder->rebuildIfNeeded();
$routes_to_load = array_diff($names, array_keys($this->routes));
if ($routes_to_load) {
$result = $this->connection->query('SELECT name, route FROM {' . $this->connection->escapeTable($this->tableName) . '} WHERE name IN (:names)', array(':names' => $routes_to_load));
$routes = $result->fetchAllKeyed();
......@@ -258,6 +259,7 @@ public function getCandidateOutlines(array $parts) {
*/
public function getRoutesByPattern($pattern) {
$path = RouteCompiler::getPatternOutline($pattern);
$this->routeBuilder->rebuildIfNeeded();
return $this->getRoutesByPath($path);
}
......
......@@ -109,19 +109,8 @@ function config_translation_config_translation_info(&$info) {
if (\Drupal::moduleHandler()->moduleExists('field_ui')) {
// Add fields entity mappers to all fieldable entity types defined.
foreach ($entity_manager->getDefinitions() as $entity_type_id => $entity_type) {
$base_route = NULL;
try {
$base_route = $route_provider->getRouteByName('field_ui.field_edit_' . $entity_type_id);
}
catch (RouteNotFoundException $e) {
if ($collection = \Drupal::service('router.builder')->getCollectionDuringRebuild()) {
$base_route = $collection->get('field_ui.field_edit_' . $entity_type_id);
}
// Ignore non-existent routes.
}
// Make sure entity type has field UI enabled and has a base route.
if ($entity_type->get('field_ui_base_route') && !empty($base_route)) {
if ($entity_type->get('field_ui_base_route')) {
$info[$entity_type_id . '_fields'] = array(
'base_route_name' => 'field_ui.field_edit_' . $entity_type_id,
'entity_type' => 'field_config',
......
......@@ -17,6 +17,8 @@
/**
* Provides a resource plugin definition for every entity type.
*
* @see \Drupal\rest\Plugin\rest\resource\EntityResource
*/
class EntityDerivative implements ContainerDeriverInterface {
......@@ -113,21 +115,20 @@ public function getDerivativeDefinitions($base_plugin_definition) {
// @todo remove the try/catch as part of
// http://drupal.org/node/2158571
try {
$route = $this->routeProvider->getRouteByName($route_name);
$this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $route->getPath();
}
catch (RouteNotFoundException $e) {
if (($collection = $this->routeBuilder->getCollectionDuringRebuild()) && $route = $collection->get($route_name)) {
$this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $route->getPath();
}
else {
// If the route does not exist it means we are in a brittle state
// of module enabling/disabling, so we simply exclude this entity
// type.
unset($this->derivatives[$entity_type_id]);
// Continue with the next entity type;
continue 2;
$route = $this->routeProvider->getRouteByName($route_name);
}
$this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $route->getPath();
}
catch (RouteNotFoundException $e) {
// If the route does not exist it means we are in a brittle state
// of module enabling/disabling, so we simply exclude this entity
// type.
unset($this->derivatives[$entity_type_id]);
// Continue with the next entity type;
continue 2;
}
}
else {
......
......@@ -28,6 +28,8 @@
* "http://drupal.org/link-relations/create" = "/entity/{entity_type}"
* }
* )
*
* @see \Drupal\rest\Plugin\Derivative\EntityDerivative
*/
class EntityResource extends ResourceBase {
......
......@@ -1395,6 +1395,11 @@ function user_modules_installed($modules) {
// Assign all available permissions to the administrator role.
$rid = \Drupal::config('user.settings')->get('admin_role');
if ($rid) {
/** @var \Drupal\Core\Routing\RouteBuilderInterface $route_builder */
$route_builder = \Drupal::service('router.builder');
// Some permissions call the url generator, so ensure that the routes are
// up to date.
$route_builder->setRebuildNeeded();
/** @var \Drupal\user\PermissionHandlerInterface $permission_handler */
$permission_handler = \Drupal::service('user.permissions');
$permissions = $permission_handler->getPermissions();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment