/** * Rebuilds the router when the default or admin theme is changed. * * @param \Drupal\Core\Config\ConfigCrudEvent $event */ public function onConfigSave(ConfigCrudEvent $event) { $saved_config = $event->getConfig(); if ($saved_config->getName() == 'system.theme' && ($event->isChanged('admin') || $event->isChanged('default'))) { $this->routerBuilder->setRebuildNeeded(); } }
/** * Gets the real route provider service and rebuilds the router id necessary. * * @return \Drupal\Core\Routing\RouteProviderInterface * The route provider service. */ protected function getRouteProvider() { if (!$this->rebuilt) { $this->routeBuilder->rebuild(); $this->rebuilt = TRUE; } return $this->routeProvider; }
protected function execute(InputInterface $input, OutputInterface $output) { $io = new DrupalStyle($input, $output); $io->newLine(); $io->comment($this->trans('commands.router.rebuild.messages.rebuilding')); $this->routerBuilder->rebuild(); $io->success($this->trans('commands.router.rebuild.messages.completed')); }
/** * Set the default theme. * * @param \Symfony\Component\HttpFoundation\Request $request * A request object containing a theme name. * * @return \Symfony\Component\HttpFoundation\RedirectResponse * Redirects back to the appearance admin page. * * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException * Throws access denied when no theme is set in the request. */ public function setDefaultTheme(Request $request) { $config = $this->configFactory->getEditable('system.theme'); $theme = $request->query->get('theme'); if (isset($theme)) { // Get current list of themes. $themes = $this->themeHandler->listInfo(); // Check if the specified theme is one recognized by the system. // Or try to install the theme. if (isset($themes[$theme]) || $this->themeHandler->install(array($theme))) { $themes = $this->themeHandler->listInfo(); // Set the default theme. $config->set('default', $theme)->save(); $this->routeBuilder->setRebuildNeeded(); // The status message depends on whether an admin theme is currently in // use: a value of 0 means the admin theme is set to be the default // theme. $admin_theme = $config->get('admin'); if ($admin_theme != 0 && $admin_theme != $theme) { drupal_set_message($this->t('Please note that the administration theme is still set to the %admin_theme theme; consequently, the theme on this page remains unchanged. All non-administrative sections of the site, however, will show the selected %selected_theme theme by default.', array('%admin_theme' => $themes[$admin_theme]->info['name'], '%selected_theme' => $themes[$theme]->info['name']))); } else { drupal_set_message($this->t('%theme is now the default theme.', array('%theme' => $themes[$theme]->info['name']))); } } else { drupal_set_message($this->t('The %theme theme was not found.', array('%theme' => $theme)), 'error'); } return $this->redirect('system.themes_page'); } throw new AccessDeniedHttpException(); }
/** * {@inheritdoc} */ public function submitForm(array &$form, formstateinterface $form_state) { $methods = $form_state->getValue('methods'); $resource_id = $form_state->getValue('resource_id'); $resources = \Drupal::config('rest.settings')->get('resources') ?: array(); // Reset the resource configuration. $resources[$resource_id] = array(); foreach ($methods as $method => $settings) { if ($settings[$method] == TRUE) { $resources[$resource_id][$method] = array(); // Check for selected formats. $formats = array_keys(array_filter($settings['settings']['formats'])); if (!empty($formats)) { $resources[$resource_id][$method]['supported_formats'] = $formats; } // Check for selected authentication providers. $auth = array_keys(array_filter($settings['settings']['auth'])); if (!empty($auth)) { $resources[$resource_id][$method]['supported_auth'] = $auth; } } } $config = \Drupal::configFactory()->getEditable('rest.settings'); $config->set('resources', $resources); $config->save(); // Rebuild routing cache. $this->routeBuilder->rebuild(); drupal_set_message(t('The resource was updated successfully.')); // Redirect back to the listing. $form_state->setRedirectUrl(new Url('restui.list')); }
/** * Resets some other systems like rebuilding the route information or caches. */ protected function resetSystem() { if ($this->routeBuilder) { $this->routeBuilder->setRebuildNeeded(); } $this->systemListReset(); // @todo It feels wrong to have the requirement to clear the local tasks // cache here. Cache::invalidateTags(array('local_task')); $this->themeRegistryRebuild(); }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { parent::submitForm($form, $form_state); $values = $form_state->getValues(); $this->config('ds.settings')->set('field_template', $values['fs1']['field_template'])->set('ft-default', $values['fs1']['ft-default'])->set('ft-show-colon', $values['fs1']['ft-show-colon'])->save(); $this->entityFieldManager->clearCachedFieldDefinitions(); $this->moduleHandler->resetImplementations(); $this->themeRegistry->reset(); $this->routeBuilder->setRebuildNeeded(); \Drupal::cache('render')->deleteAll(); }
/** * Tests the cache of the local task manager with a filled initial cache. */ public function testGetLocalTaskForRouteWithFilledCache() { $this->pluginDiscovery->expects($this->never())->method('getDefinitions'); $mock_plugin = $this->getMock('Drupal\\Core\\Menu\\LocalTaskInterface'); $this->setupFactory($mock_plugin); $this->setupLocalTaskManager(); $result = $this->getLocalTasksCache($mock_plugin); $this->cacheBackend->expects($this->at(0))->method('get')->with('local_task_plugins:en:menu_local_task_test_tasks_view')->will($this->returnValue((object) array('data' => $result))); $this->cacheBackend->expects($this->never())->method('set'); $this->routeBuilder->expects($this->never())->method('rebuildIfNeeded'); $result = $this->getLocalTasksForRouteResult($mock_plugin); $local_tasks = $this->manager->getLocalTasksForRoute('menu_local_task_test_tasks_view'); $this->assertEquals($result, $local_tasks); }
/** * Disables a resource. * * @param string $resource_id * The identifier or the REST resource. * @param \Symfony\Component\HttpFoundation\Request $request * The current request. * * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse * Redirects back to the listing page. * * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException * Access is denied, if the token is invalid or missing. */ public function disable($resource_id, Request $request) { if (!\Drupal::csrfToken()->validate($request->query->get('token'), 'restui_disable')) { throw new AccessDeniedHttpException(); } $config = \Drupal::configFactory()->getEditable('rest.settings'); $resources = $config->get('resources') ?: array(); $plugin = $this->resourcePluginManager->getInstance(array('id' => $resource_id)); if (!empty($plugin)) { // disable the resource. unset($resources[$resource_id]); $config->set('resources', $resources); $config->save(); // Rebuild routing cache. $this->routeBuilder->rebuild(); drupal_set_message(t('The resource was disabled successfully.')); } // Redirect back to the page. return new RedirectResponse($this->urlGenerator->generate('restui.list', array(), TRUE)); }
/** * Finds routes that may potentially match the request. * * This may return a mixed list of class instances, but all routes returned * must extend the core symfony route. The classes may also implement * RouteObjectInterface to link to a content document. * * This method may not throw an exception based on implementation specific * restrictions on the url. That case is considered a not found - returning * an empty array. Exceptions are only used to abort the whole request in * case something is seriously broken, like the storage backend being down. * * Note that implementations may not implement an optimal matching * algorithm, simply a reasonable first pass. That allows for potentially * very large route sets to be filtered down to likely candidates, which * may then be filtered in memory more completely. * * @param Request $request A request against which to match. * * @return \Symfony\Component\Routing\RouteCollection with all urls that * could potentially match $request. Empty collection if nothing can * match. * * @todo Should this method's found routes also be included in the cache? */ public function getRouteCollectionForRequest(Request $request) { // The '_system_path' has language prefix stripped and path alias resolved, // whereas getPathInfo() returns the requested path. In Drupal, the request // always contains a system_path attribute, but this component may get // adopted by non-Drupal projects. Some unit tests also skip initializing // '_system_path'. // @todo Consider abstracting this to a separate object. if ($request->attributes->has('_system_path')) { // _system_path never has leading or trailing slashes. $path = '/' . $request->attributes->get('_system_path'); } else { // getPathInfo() always has leading slash, and might or might not have a // trailing slash. $path = rtrim($request->getPathInfo(), '/'); } $collection = $this->getRoutesByPath($path); // Try rebuilding the router if it is necessary. if (!$collection->count() && $this->routeBuilder->rebuildIfNeeded()) { $collection = $this->getRoutesByPath($path); } return $collection; }
/** * Implements DerivativeInterface::getDerivativeDefinitions(). */ public function getDerivativeDefinitions($base_plugin_definition) { if (!isset($this->derivatives)) { // Add in the default plugin configuration and the resource type. foreach ($this->entityManager->getDefinitions() as $entity_type_id => $entity_type) { $this->derivatives[$entity_type_id] = array('id' => 'entity:' . $entity_type_id, 'entity_type' => $entity_type_id, 'serialization_class' => $entity_type->getClass(), 'label' => $entity_type->getLabel()); $default_uris = array('canonical' => "/entity/{$entity_type_id}/" . '{' . $entity_type_id . '}', 'http://drupal.org/link-relations/create' => "/entity/{$entity_type_id}"); foreach ($default_uris as $link_relation => $default_uri) { // Check if there are link templates defined for the entity type and // use the path from the route instead of the default. if ($route_name = $entity_type->getLinkTemplate($link_relation)) { // @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; } } } else { $this->derivatives[$entity_type_id]['uri_paths'][$link_relation] = $default_uri; } } $this->derivatives[$entity_type_id] += $base_plugin_definition; } } return $this->derivatives; }
/** * Rebuilds routers if necessary. * * @param \Symfony\Component\HttpKernel\Event\PostResponseEvent $event * The event object. */ public function onKernelTerminate(PostResponseEvent $event) { $this->routeBuilder->rebuildIfNeeded(); }
/** * {@inheritdoc} */ public function getRoutesByPattern($pattern) { $path = RouteCompiler::getPatternOutline($pattern); $this->routeBuilder->rebuildIfNeeded(); return $this->getRoutesByPath($path); }
/** * Find all local tasks that appear on a named route. * * @param string $route_name * The route for which to find local tasks. * * @return array * Returns an array of task levels. Each task level contains instances * of local tasks (LocalTaskInterface) which appear on the tab route. * The array keys are the depths and the values are arrays of plugin * instances. */ public function getLocalTasksForRoute($route_name) { if (!isset($this->instances[$route_name])) { $this->instances[$route_name] = array(); if ($cache = $this->cacheBackend->get($this->cacheKey . ':' . $route_name)) { $base_routes = $cache->data['base_routes']; $parents = $cache->data['parents']; $children = $cache->data['children']; } else { // Maybe some code asked to rebuild the routes, so rebuild the router // as we rely on having proper existing routes in dynamic local tasks. $this->routeBuilder->rebuildIfNeeded(); $definitions = $this->getDefinitions(); // We build the hierarchy by finding all tabs that should // appear on the current route. $base_routes = array(); $parents = array(); $children = array(); foreach ($definitions as $plugin_id => $task_info) { // Fill in the base_route from the parent to insure consistency. if (!empty($task_info['parent_id']) && !empty($definitions[$task_info['parent_id']])) { $task_info['base_route'] = $definitions[$task_info['parent_id']]['base_route']; // Populate the definitions we use in the next loop. Using a // reference like &$task_info causes bugs. $definitions[$plugin_id]['base_route'] = $definitions[$task_info['parent_id']]['base_route']; } if ($route_name == $task_info['route_name']) { if (!empty($task_info['base_route'])) { $base_routes[$task_info['base_route']] = $task_info['base_route']; } // Tabs that link to the current route are viable parents // and their parent and children should be visible also. // @todo - this only works for 2 levels of tabs. // instead need to iterate up. $parents[$plugin_id] = TRUE; if (!empty($task_info['parent_id'])) { $parents[$task_info['parent_id']] = TRUE; } } } if ($base_routes) { // Find all the plugins with the same root and that are at the top // level or that have a visible parent. foreach ($definitions as $plugin_id => $task_info) { if (!empty($base_routes[$task_info['base_route']]) && (empty($task_info['parent_id']) || !empty($parents[$task_info['parent_id']]))) { // Concat '> ' with root ID for the parent of top-level tabs. $parent = empty($task_info['parent_id']) ? '> ' . $task_info['base_route'] : $task_info['parent_id']; $children[$parent][$plugin_id] = $task_info; } } } $data = array('base_routes' => $base_routes, 'parents' => $parents, 'children' => $children); $this->cacheBackend->set($this->cacheKey . ':' . $route_name, $data, Cache::PERMANENT, $this->cacheTags); } // Create a plugin instance for each element of the hierarchy. foreach ($base_routes as $base_route) { // Convert the tree keyed by plugin IDs into a simple one with // integer depth. Create instances for each plugin along the way. $level = 0; // We used this above as the top-level parent array key. $next_parent = '> ' . $base_route; do { $parent = $next_parent; $next_parent = FALSE; foreach ($children[$parent] as $plugin_id => $task_info) { $plugin = $this->createInstance($plugin_id); $this->instances[$route_name][$level][$plugin_id] = $plugin; // Normally, l() compares the href of every link with the current // path and sets the active class accordingly. But the parents of // the current local task may be on a different route in which // case we have to set the class manually by flagging it active. if (!empty($parents[$plugin_id]) && $route_name != $task_info['route_name']) { $plugin->setActive(); } if (isset($children[$plugin_id])) { // This tab has visible children $next_parent = $plugin_id; } } $level++; } while ($next_parent); } } return $this->instances[$route_name]; }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $this->routeBuilder->rebuild(); drupal_set_message($this->t('The menu router has been rebuilt.')); $form_state->setRedirect('<front>'); }