diff --git a/core/core.services.yml b/core/core.services.yml index d10db5b..4cd9124 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -268,6 +268,10 @@ services: class: Symfony\Component\Routing\RequestContext calls: - [fromRequest, ['@request']] + router.admin_context: + class: Drupal\Core\Routing\AdminContext + calls: + - [setRequest, ['@?request=']] router.route_provider: class: Drupal\Core\Routing\RouteProvider arguments: ['@database', '@router.builder'] diff --git a/core/includes/common.inc b/core/includes/common.inc index 46449da..57b4ad4 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -2157,8 +2157,8 @@ function _drupal_add_js($data = NULL, $options = NULL) { $current_path = current_path(); $current_path_is_admin = FALSE; // The function path_is_admin() is not available on update.php pages. - if (!(defined('MAINTENANCE_MODE') && MAINTENANCE_MODE === 'update')) { - $current_path_is_admin = path_is_admin($current_path); + if (!(defined('MAINTENANCE_MODE'))) { + $current_path_is_admin = \Drupal::service('router.admin_context')->isAdminRoute(); } $path = array( 'basePath' => base_path(), diff --git a/core/includes/path.inc b/core/includes/path.inc index 533dcd9..d9f0d5a 100644 --- a/core/includes/path.inc +++ b/core/includes/path.inc @@ -5,7 +5,9 @@ * Functions to handle paths in Drupal. */ +use Drupal\Core\ParamConverter\ParamNotConvertedException; use Drupal\Core\Routing\RequestHelper; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\HttpFoundation\Request; /** @@ -130,54 +132,18 @@ function path_load($conditions) { * @return * TRUE if the path is administrative, FALSE otherwise. * - * @see path_get_admin_paths() - * @see hook_admin_paths() - * @see hook_admin_paths_alter() + * @deprecated Use \Drupal::service('router.admin_context')->isAdminRoute() + * service instead. */ function path_is_admin($path) { - $path_map = &drupal_static(__FUNCTION__); - if (!isset($path_map['admin'][$path])) { - $patterns = path_get_admin_paths(); - $path_map['admin'][$path] = drupal_match_path($path, $patterns['admin']); - $path_map['non_admin'][$path] = drupal_match_path($path, $patterns['non_admin']); + try { + $parameters = \Drupal::service('router')->match('/' . $path); + $route = $parameters[RouteObjectInterface::ROUTE_OBJECT]; + return \Drupal::service('router.admin_context')->isAdminRoute($route); } - return $path_map['admin'][$path] && !$path_map['non_admin'][$path]; -} - -/** - * Gets a list of administrative and non-administrative paths. - * - * @return array - * An associative array containing the following keys: - * 'admin': An array of administrative paths and regular expressions - * in a format suitable for drupal_match_path(). - * 'non_admin': An array of non-administrative paths and regular expressions. - * - * @see hook_admin_paths() - * @see hook_admin_paths_alter() - */ -function path_get_admin_paths() { - $patterns = &drupal_static(__FUNCTION__); - if (!isset($patterns)) { - $paths = \Drupal::moduleHandler()->invokeAll('admin_paths'); - drupal_alter('admin_paths', $paths); - // Combine all admin paths into one array, and likewise for non-admin paths, - // for easier handling. - $patterns = array(); - $patterns['admin'] = array(); - $patterns['non_admin'] = array(); - foreach ($paths as $path => $enabled) { - if ($enabled) { - $patterns['admin'][] = $path; - } - else { - $patterns['non_admin'][] = $path; - } - } - $patterns['admin'] = implode("\n", $patterns['admin']); - $patterns['non_admin'] = implode("\n", $patterns['non_admin']); + catch (ParamNotConvertedException $e) { + return FALSE; } - return $patterns; } /** diff --git a/core/lib/Drupal/Core/Routing/AdminContext.php b/core/lib/Drupal/Core/Routing/AdminContext.php new file mode 100644 index 0000000..0937848 --- /dev/null +++ b/core/lib/Drupal/Core/Routing/AdminContext.php @@ -0,0 +1,64 @@ +route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT); + } + + /** + * Determines whether the active route is an admin one. + * + * @param \Symfony\Component\Routing\Route $route + * (optional) The route to determine whether it is an admin one. Per default + * this falls back to the route object on the active request. + * + * @return bool + * Returns TRUE if the route is an admin one, otherwise FALSE. + */ + public function isAdminRoute(Route $route = NULL) { + if (!$route) { + $route = $this->route; + if (!$route) { + return FALSE; + } + } + return (bool) $route->getOption('_admin_route'); + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[RoutingEvents::ALTER] = array('onAlterRoutes', -10); + return $events; + } + +} diff --git a/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php b/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php index 1172428..f7cf537 100644 --- a/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php +++ b/core/lib/Drupal/Core/Routing/RouteSubscriberBase.php @@ -25,8 +25,7 @@ * The provider these routes belong to. For dynamically added routes, the * provider name will be 'dynamic_routes'. */ - protected function alterRoutes(RouteCollection $collection, $provider) { - } + abstract protected function alterRoutes(RouteCollection $collection, $provider); /** * {@inheritdoc} diff --git a/core/modules/block/block.module b/core/modules/block/block.module index daea82c..a5e9ec5 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -520,18 +520,6 @@ function block_menu_delete($menu) { } /** - * Implements hook_admin_paths(). - */ -function block_admin_paths() { - $paths = array( - // Exclude the block demonstration page from admin treatment. - // This allows us to present this page in its true form, full page. - 'admin/structure/block/demo/*' => FALSE, - ); - return $paths; -} - -/** * Implements hook_language_delete(). * * Delete the potential block visibility settings of the deleted language. diff --git a/core/modules/block/block.routing.yml b/core/modules/block/block.routing.yml index e7bbf22..47bb915 100644 --- a/core/modules/block/block.routing.yml +++ b/core/modules/block/block.routing.yml @@ -5,6 +5,8 @@ block.admin_demo: requirements: _access_theme: 'TRUE' _permission: 'administer blocks' + options: + _admin_route: FALSE block.admin_block_delete: path: '/admin/structure/block/manage/{block}/delete' diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index cdf90c7..e9bfeef 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -211,17 +211,3 @@ function custom_block_add_body_field($block_type_id, $label = 'Block body') { return $instance; } - -/** - * Implements hook_admin_paths(). - */ -function custom_block_admin_paths() { - $paths = array( - 'block/add' => TRUE, - 'block/add/*' => TRUE, - 'block/*' => TRUE, - 'block/*/delete' => TRUE, - 'admin/structure/block/custom-blocks/*' => TRUE, - ); - return $paths; -} diff --git a/core/modules/block/custom_block/custom_block.routing.yml b/core/modules/block/custom_block/custom_block.routing.yml index 622d08d..6cea531 100644 --- a/core/modules/block/custom_block/custom_block.routing.yml +++ b/core/modules/block/custom_block/custom_block.routing.yml @@ -10,6 +10,8 @@ custom_block.add_page: defaults: _content: 'Drupal\custom_block\Controller\CustomBlockController::add' _title: 'Add custom block' + options: + _admin_route: TRUE requirements: _permission: 'administer blocks' @@ -18,6 +20,8 @@ custom_block.add_form: defaults: _content: 'Drupal\custom_block\Controller\CustomBlockController::addForm' _title_callback: 'Drupal\custom_block\Controller\CustomBlockController::getAddFormTitle' + options: + _admin_route: TRUE requirements: _permission: 'administer blocks' @@ -28,11 +32,15 @@ custom_block.type_delete: _title: 'Delete' requirements: _entity_access: 'custom_block_type.delete' + options: + _admin_route: TRUE custom_block.edit: path: '/block/{custom_block}' defaults: _entity_form: 'custom_block.edit' + options: + _admin_route: TRUE requirements: _entity_access: 'custom_block.update' @@ -40,6 +48,8 @@ custom_block.delete: path: '/block/{custom_block}/delete' defaults: _entity_form: 'custom_block.delete' + options: + _admin_route: TRUE requirements: _entity_access: 'custom_block.delete' diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 8fe9e41..5f3fb9d 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -204,19 +204,6 @@ function book_menu_link_defaults() { } /** - * Implements hook_admin_paths(). - */ -function book_admin_paths() { - if (\Drupal::config('node.settings')->get('use_admin_theme')) { - $paths = array( - 'node/*/outline' => TRUE, - 'node/*/outline/remove' => TRUE, - ); - return $paths; - } -} - -/** * Returns an array of all books. * * @todo Remove in favor of BookManager Service. http://drupal.org/node/1963894 diff --git a/core/modules/book/book.routing.yml b/core/modules/book/book.routing.yml index 75e3ae8..6b49530 100644 --- a/core/modules/book/book.routing.yml +++ b/core/modules/book/book.routing.yml @@ -38,6 +38,8 @@ book.outline: requirements: _permission: 'administer book outlines' _entity_access: 'node.view' + options: + _node_admin_route: TRUE book.admin_edit: path: '/admin/structure/book/{node}' @@ -56,6 +58,7 @@ book.remove: _title: 'Remove from outline' options: _access_mode: 'ALL' + _node_admin_route: TRUE requirements: _permission: 'administer book outlines' _entity_access: 'node.view' diff --git a/core/modules/edit/edit.module b/core/modules/edit/edit.module index 87732dc..9e62a9f 100644 --- a/core/modules/edit/edit.module +++ b/core/modules/edit/edit.module @@ -37,8 +37,7 @@ function edit_page_build(&$page) { } // In-place editing is only supported on the front-end. - $path = \Drupal::request()->attributes->get('_system_path'); - if (path_is_admin($path)) { + if (\Drupal::service('router.admin_context')->isAdminRoute()) { return; } diff --git a/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php b/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php index 2eca5dd..29be8ed 100644 --- a/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php +++ b/core/modules/locale/lib/Drupal/locale/ParamConverter/LocaleAdminPathConfigEntityConverter.php @@ -7,6 +7,7 @@ namespace Drupal\locale\ParamConverter; +use Drupal\Core\Routing\AdminContext; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Route; use Drupal\Core\Config\ConfigFactory; @@ -38,14 +39,28 @@ class LocaleAdminPathConfigEntityConverter extends EntityConverter { protected $configFactory; /** + * The route admin context to determine whether a route is an admin one. + * + * @var \Drupal\Core\Routing\AdminContext + */ + protected $adminContext; + + /** * Constructs a new EntityConverter. * - * @param \Drupal\Core\Entity\EntityManagerInterface $entityManager + * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. + * @param \Drupal\Core\Config\ConfigFactory $config_factory + * The config factory. + * @param \Drupal\Core\Routing\AdminContext $admin_context + * The route admin context service. + * */ - public function __construct(EntityManagerInterface $entity_manager, ConfigFactory $config_factory) { - $this->configFactory = $config_factory; + public function __construct(EntityManagerInterface $entity_manager, ConfigFactory $config_factory, AdminContext $admin_context) { parent::__construct($entity_manager); + + $this->configFactory = $config_factory; + $this->adminContext = $admin_context; } /** @@ -73,9 +88,7 @@ public function applies($definition, $name, Route $route) { $entity_type = substr($definition['type'], strlen('entity:')); $info = $this->entityManager->getDefinition($entity_type); if ($info->isSubclassOf('\Drupal\Core\Config\Entity\ConfigEntityInterface')) { - // path_is_admin() needs the path without the leading slash. - $path = ltrim($route->getPath(), '/'); - return path_is_admin($path); + return $this->adminContext->isAdminRoute($route); } } return FALSE; diff --git a/core/modules/locale/locale.services.yml b/core/modules/locale/locale.services.yml index b5f4cf4..d400131 100644 --- a/core/modules/locale/locale.services.yml +++ b/core/modules/locale/locale.services.yml @@ -3,7 +3,7 @@ services: class: Drupal\locale\ParamConverter\LocaleAdminPathConfigEntityConverter tags: - { name: paramconverter, priority: 5 } - arguments: ['@entity.manager', '@config.factory'] + arguments: ['@entity.manager', '@config.factory', '@router.admin_context'] locale.config.typed: class: Drupal\locale\LocaleConfigManager arguments: ['@config.storage', '@config.storage.schema', '@config.storage.installer', '@locale.storage', '@cache.config', '@config.factory'] diff --git a/core/modules/node/lib/Drupal/node/EventSubscriber/NodeAdminRouteSubscriber.php b/core/modules/node/lib/Drupal/node/EventSubscriber/NodeAdminRouteSubscriber.php new file mode 100644 index 0000000..38cea31 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/EventSubscriber/NodeAdminRouteSubscriber.php @@ -0,0 +1,49 @@ +configFactory = $config_factory; + } + + /** + * {@inheritdoc} + */ + protected function alterRoutes(RouteCollection $collection, $provider) { + if ($this->configFactory->get('node.settings')->get('use_admin_theme')) { + foreach ($collection->all() as $route) { + if ($route->hasOption('_node_admin_route')) { + $route->setOption('_admin_route', TRUE); + } + } + } + } + +} diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 2a9504b..5c041e6 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -234,26 +234,6 @@ function node_uri(NodeInterface $node) { } /** - * Implements hook_admin_paths(). - */ -function node_admin_paths() { - if (\Drupal::config('node.settings')->get('use_admin_theme')) { - $paths = array( - 'node/*/edit' => TRUE, - 'node/*/delete' => TRUE, - 'node/*/revisions' => TRUE, - 'node/*/revisions/*/revert' => TRUE, - 'node/*/revisions/*/delete' => TRUE, - 'node/*/translations' => TRUE, - 'node/*/translations/*' => TRUE, - 'node/add' => TRUE, - 'node/add/*' => TRUE, - ); - return $paths; - } -} - -/** * Gathers a listing of links to nodes. * * @param $result @@ -1373,6 +1353,7 @@ function node_form_system_themes_admin_form_submit($form, &$form_state) { \Drupal::config('node.settings') ->set('use_admin_theme', $form_state['values']['use_admin_theme']) ->save(); + \Drupal::service('router.builder')->setRebuildNeeded(); } /** diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml index b16080c..74d63fd 100644 --- a/core/modules/node/node.routing.yml +++ b/core/modules/node/node.routing.yml @@ -19,6 +19,8 @@ node.page_edit: _entity_form: 'node.edit' requirements: _entity_access: 'node.update' + options: + _node_admin_route: TRUE node.add_page: path: '/node/add' @@ -27,6 +29,7 @@ node.add_page: _content: '\Drupal\node\Controller\NodeController::addPage' options: _access_mode: 'ANY' + _node_admin_route: TRUE requirements: _permission: 'administer content types' _node_add_access: 'node' @@ -38,6 +41,8 @@ node.add: _title_callback: '\Drupal\node\Controller\NodeController::addPageTitle' requirements: _node_add_access: 'node:{node_type}' + options: + _node_admin_route: TRUE node.view: path: '/node/{node}' @@ -53,6 +58,8 @@ node.delete_confirm: _entity_form: 'node.delete' requirements: _entity_access: 'node.delete' + options: + _node_admin_route: TRUE node.revision_overview: path: '/node/{node}/revisions' @@ -61,6 +68,8 @@ node.revision_overview: _content: '\Drupal\node\Controller\NodeController::revisionOverview' requirements: _access_node_revision: 'view' + options: + _node_admin_route: TRUE node.revision_show: path: '/node/{node}/revisions/{node_revision}/view' @@ -77,6 +86,8 @@ node.revision_revert_confirm: _title: 'Revert to earlier revision' requirements: _access_node_revision: 'update' + options: + _node_admin_route: TRUE node.revision_delete_confirm: path: '/node/{node}/revisions/{node_revision}/delete' @@ -85,6 +96,8 @@ node.revision_delete_confirm: _title: 'Delete earlier revision' requirements: _access_node_revision: 'delete' + options: + _node_admin_route: TRUE node.overview_types: path: '/admin/structure/types' diff --git a/core/modules/node/node.services.yml b/core/modules/node/node.services.yml index 7329685..e211f7b 100644 --- a/core/modules/node/node.services.yml +++ b/core/modules/node/node.services.yml @@ -12,3 +12,8 @@ services: arguments: ['@entity.manager'] tags: - { name: access_check, applies_to: _node_add_access } + node.admin_path.route_subscriber: + class: Drupal\node\EventSubscriber\NodeAdminRouteSubscriber + arguments: ['@config.factory'] + tags: + - { name: event_subscriber } diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index a988cf4..f6337b7 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -101,16 +101,6 @@ function shortcut_menu_link_defaults() { } /** - * Implements hook_admin_paths(). - */ -function shortcut_admin_paths() { - $paths = array( - 'user/*/shortcuts' => TRUE, - ); - return $paths; -} - -/** * Access callback for editing a shortcut set. * * @param Drupal\shortcut\ShortcutSetInterface $shortcut_set diff --git a/core/modules/shortcut/shortcut.routing.yml b/core/modules/shortcut/shortcut.routing.yml index 9ec8d64..d0721c0 100644 --- a/core/modules/shortcut/shortcut.routing.yml +++ b/core/modules/shortcut/shortcut.routing.yml @@ -74,4 +74,6 @@ shortcut.overview: _title: 'Shortcuts' requirements: _access_shortcut_set_switch: 'TRUE' + options: + _admin_route: TRUE diff --git a/core/modules/system/lib/Drupal/system/EventSubscriber/AdminRouteSubscriber.php b/core/modules/system/lib/Drupal/system/EventSubscriber/AdminRouteSubscriber.php new file mode 100644 index 0000000..eebe05c --- /dev/null +++ b/core/modules/system/lib/Drupal/system/EventSubscriber/AdminRouteSubscriber.php @@ -0,0 +1,29 @@ +all() as $route) { + if (strpos($route->getPath(), '/admin') === 0 && !$route->hasOption('_admin_route')) { + $route->setOption('_admin_route', TRUE); + } + } + } + +} diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php index a996604..4fce6d4 100644 --- a/core/modules/system/system.api.php +++ b/core/modules/system/system.api.php @@ -47,50 +47,6 @@ function hook_hook_info() { } /** - * Define administrative paths. - * - * Modules may specify whether or not the routing paths they define are - * to be considered administrative. Other modules may use this information to - * display those pages differently. - * - * To change the administrative status of menu items defined in another module's - * routing paths, modules should implement hook_admin_paths_alter(). - * - * @return - * An associative array. For each item, the key is the path in question, in - * a format acceptable to drupal_match_path(). The value for each item should - * be TRUE (for paths considered administrative) or FALSE (for non- - * administrative paths). - * - * @see drupal_match_path() - * @see hook_admin_paths_alter() - */ -function hook_admin_paths() { - $paths = array( - 'mymodule/*/add' => TRUE, - 'mymodule/*/edit' => TRUE, - ); - return $paths; -} - -/** - * Redefine administrative paths defined by other modules. - * - * @param $paths - * An associative array of administrative paths, as defined by implementations - * of hook_admin_paths(). - * - * @see hook_admin_paths() - */ -function hook_admin_paths_alter(&$paths) { - // Treat all user pages as administrative. - $paths['user'] = TRUE; - $paths['user/*'] = TRUE; - // Treat the forum topic node form as a non-administrative page. - $paths['node/add/forum'] = FALSE; -} - -/** * Perform periodic actions. * * Modules that require some commands to be executed periodically can diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 065d280..4ef0247 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2348,7 +2348,7 @@ function system_page_build(&$page) { 'weight' => CSS_SKIN - 10, 'every_page' => TRUE, ); - if (path_is_admin(current_path())) { + if (\Drupal::service('router.admin_context')->isAdminRoute()) { $page['#attached']['css'][$path . '/css/system.admin.css'] = array( 'weight' => CSS_COMPONENT - 10, ); @@ -3155,18 +3155,3 @@ function theme_confirm_form($variables) { function theme_system_config_form($variables) { return drupal_render_children($variables['form']); } - -/** - * Implements hook_admin_paths(). - */ -function system_admin_paths() { - $paths = array( - 'admin' => TRUE, - 'admin/*' => TRUE, - 'batch' => TRUE, - // This page should not be treated as administrative since it outputs its - // own content (outside of any administration theme). - 'admin/reports/status/php' => FALSE, - ); - return $paths; -} diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index 9be827e..39de86b 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -283,6 +283,10 @@ system.php: _controller: 'Drupal\system\Controller\SystemInfoController::php' requirements: _permission: 'administer site configuration' + # This page should not be treated as administrative since it outputs its own + # content (outside of any administration theme). + options: + _admin_route: FALSE system.admin_index: path: '/admin/index' @@ -387,6 +391,8 @@ system.batch_page.normal: _content: '\Drupal\system\Controller\BatchController::batchPage' requirements: _access: 'TRUE' + options: + _admin_route: TRUE system.batch_page.json: path: '/batch' @@ -395,6 +401,8 @@ system.batch_page.json: requirements: _access: 'TRUE' _format: 'json' + options: + _admin_route: TRUE system.update: path: '/core/update.php' diff --git a/core/modules/system/system.services.yml b/core/modules/system/system.services.yml index 179bb27..38c30db 100644 --- a/core/modules/system/system.services.yml +++ b/core/modules/system/system.services.yml @@ -15,6 +15,10 @@ services: class: Drupal\system\PathProcessor\PathProcessorFiles tags: - { name: path_processor_inbound, priority: 200 } + system.admin_path.route_subscriber: + class: Drupal\system\EventSubscriber\AdminRouteSubscriber + tags: + - { name: event_subscriber } theme.negotiator.system.batch: class: Drupal\system\Theme\BatchNegotiator arguments: ['@batch.storage'] diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index f2fe6fe..6199f6a 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -273,19 +273,6 @@ function taxonomy_menu_link_defaults() { } /** - * Implements hook_admin_paths(). - */ -function taxonomy_admin_paths() { - $paths = array( - 'taxonomy/term/*/edit' => TRUE, - 'taxonomy/term/*/delete' => TRUE, - 'taxonomy/term/*/translations' => TRUE, - 'taxonomy/term/*/translations/*' => TRUE, - ); - return $paths; -} - -/** * Checks and updates the hierarchy flag of a vocabulary. * * Checks the current parents of all terms in a vocabulary and updates the diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml index 63b374d..014f957 100644 --- a/core/modules/taxonomy/taxonomy.routing.yml +++ b/core/modules/taxonomy/taxonomy.routing.yml @@ -19,6 +19,8 @@ taxonomy.term_edit: defaults: _entity_form: 'taxonomy_term.default' _title: 'Edit term' + options: + _admin_route: TRUE requirements: _entity_access: 'taxonomy_term.update' @@ -27,6 +29,8 @@ taxonomy.term_delete: defaults: _entity_form: 'taxonomy_term.delete' _title: 'Delete term' + options: + _admin_route: TRUE requirements: _entity_access: 'taxonomy_term.delete' diff --git a/core/modules/tour/tests/tour_test/tour_test.module b/core/modules/tour/tests/tour_test/tour_test.module index 0df3e57..ca750ec 100644 --- a/core/modules/tour/tests/tour_test/tour_test.module +++ b/core/modules/tour/tests/tour_test/tour_test.module @@ -8,16 +8,6 @@ use Drupal\Core\Entity\EntityInterface; /** - * Implements hook_admin_paths(). - */ -function tour_test_admin_paths() { - $paths = array( - 'tour-test-1' => TRUE, - ); - return $paths; -} - -/** * Implements hook_menu(). */ function tour_test_menu() { diff --git a/core/modules/tour/tests/tour_test/tour_test.routing.yml b/core/modules/tour/tests/tour_test/tour_test.routing.yml index 5e4d254..f039dc0 100644 --- a/core/modules/tour/tests/tour_test/tour_test.routing.yml +++ b/core/modules/tour/tests/tour_test/tour_test.routing.yml @@ -2,6 +2,8 @@ tour_test.1: path: '/tour-test-1' defaults: _content: '\Drupal\tour_test\Controller\TourTestController::tourTest1' + options: + _admin_route: TRUE requirements: _access: 'TRUE' diff --git a/core/modules/user/lib/Drupal/user/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php b/core/modules/user/lib/Drupal/user/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php index c7a42eb..755df10 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php +++ b/core/modules/user/lib/Drupal/user/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php @@ -7,7 +7,11 @@ namespace Drupal\user\Plugin\LanguageNegotiation; +use Drupal\Core\DependencyInjection\ContainerInjectionInterface; +use Drupal\Core\Routing\AdminContext; use Drupal\language\LanguageNegotiationMethodBase; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; /** @@ -21,7 +25,7 @@ * description = @Translation("Account administration pages language setting.") * ) */ -class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase { +class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase implements ContainerInjectionInterface { /** * The language negotiation method id. @@ -29,6 +33,32 @@ class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase { const METHOD_ID = 'language-user-admin'; /** + * The admin context. + * + * @var \Drupal\Core\Routing\AdminContext + */ + protected $adminContext; + + /** + * Constructs a new LanguageNegotiationUserAdmin instance. + * + * @param \Drupal\Core\Routing\AdminContext $admin_context + * The admin context. + */ + public function __construct(AdminContext $admin_context = NULL) { + $this->adminContext = $admin_context; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('router.admin_context') + ); + } + + /** * {@inheritdoc} */ public function getLangcode(Request $request = NULL) { @@ -51,17 +81,16 @@ public function getLangcode(Request $request = NULL) { /** * Checks whether the given path is an administrative one. * - * @param string $path - * A Drupal path. + * @param \Symfony\Component\HttpFoundation\Request $request + * The request object. * * @return bool * TRUE if the path is administrative, FALSE otherwise. */ public function isAdminPath(Request $request) { $result = FALSE; - if ($request && function_exists('path_is_admin')) { - $path = urldecode(trim($request->getPathInfo(), '/')); - $result = path_is_admin($path); + if ($request && $this->adminContext) { + $result = $this->adminContext->isAdminRoute($request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)); } return $result; } diff --git a/core/modules/user/lib/Drupal/user/Theme/AdminNegotiator.php b/core/modules/user/lib/Drupal/user/Theme/AdminNegotiator.php index faaeb40..3e27dbf 100644 --- a/core/modules/user/lib/Drupal/user/Theme/AdminNegotiator.php +++ b/core/modules/user/lib/Drupal/user/Theme/AdminNegotiator.php @@ -9,8 +9,10 @@ use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Entity\EntityManagerInterface; +use Drupal\Core\Routing\AdminContext; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Theme\ThemeNegotiatorInterface; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\HttpFoundation\Request; /** @@ -40,6 +42,13 @@ class AdminNegotiator implements ThemeNegotiatorInterface { protected $entityManager; /** + * The route admin context to determine whether a route is an admin one. + * + * @var \Drupal\Core\Routing\AdminContext + */ + protected $adminContext; + + /** * Creates a new AdminNegotiator instance. * * @param \Drupal\Core\Session\AccountInterface $user @@ -49,18 +58,18 @@ class AdminNegotiator implements ThemeNegotiatorInterface { * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. */ - public function __construct(AccountInterface $user, ConfigFactory $config_factory, EntityManagerInterface $entity_manager) { + public function __construct(AccountInterface $user, ConfigFactory $config_factory, EntityManagerInterface $entity_manager, AdminContext $admin_context) { $this->user = $user; $this->configFactory = $config_factory; $this->entityManager = $entity_manager; + $this->adminContext = $admin_context; } /** * {@inheritdoc} */ public function applies(Request $request) { - $path = $request->attributes->get('_system_path'); - return ($this->entityManager->hasController('user_role', 'storage') && $this->user->hasPermission('view the administration theme') && path_is_admin($path)); + return ($this->entityManager->hasController('user_role', 'storage') && $this->user->hasPermission('view the administration theme') && $this->adminContext->isAdminRoute($request->attributes->get(RouteObjectInterface::ROUTE_OBJECT))); } /** diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 4262403..90cb7cb 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -874,20 +874,6 @@ function user_translated_menu_link_alter(MenuLink &$menu_link) { } /** - * Implements hook_admin_paths(). - */ -function user_admin_paths() { - $paths = array( - 'user/*/cancel' => TRUE, - 'user/*/edit' => TRUE, - 'user/*/edit/*' => TRUE, - 'user/*/translations' => TRUE, - 'user/*/translations/*' => TRUE, - ); - return $paths; -} - -/** * Returns $arg or the user ID of the current user if $arg is '%' or empty. * * Deprecated. Use %user_uid_optional instead. diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml index f59aabc..7812eea 100644 --- a/core/modules/user/user.routing.yml +++ b/core/modules/user/user.routing.yml @@ -151,6 +151,8 @@ user.edit: defaults: _entity_form: 'user.default' _title_callback: 'Drupal\user\Controller\UserController::userTitle' + options: + _admin_route: TRUE requirements: _entity_access: 'user.update' @@ -159,6 +161,8 @@ user.cancel: defaults: _title: 'Cancel account' _entity_form: 'user.cancel' + options: + _admin_route: TRUE requirements: _entity_access: 'user.delete' diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml index 23d8706..b0c1694 100644 --- a/core/modules/user/user.services.yml +++ b/core/modules/user/user.services.yml @@ -27,7 +27,7 @@ services: - { name: event_subscriber } theme.negotiator.admin_theme: class: Drupal\user\Theme\AdminNegotiator - arguments: ['@current_user', '@config.factory', '@entity.manager'] + arguments: ['@current_user', '@config.factory', '@entity.manager', '@router.admin_context'] tags: - { name: theme_negotiator, priority: -40 } user.permissions_hash: