From cd635205008dae172e8a79bbd48bc103684c1abe Mon Sep 17 00:00:00 2001 From: Alex Pott <alex.a.pott@googlemail.com> Date: Sun, 8 Jun 2014 17:49:56 -0500 Subject: [PATCH] Issue #2085571 by Xano, dawehner: Fixed admin/content should not depend on node.module. --- core/modules/comment/comment.local_tasks.yml | 2 +- core/modules/comment/comment.menu_links.yml | 2 +- core/modules/comment/comment.module | 13 --- core/modules/node/node.local_actions.yml | 2 +- core/modules/node/node.local_tasks.yml | 4 - core/modules/node/node.menu_links.yml | 6 -- core/modules/node/node.module | 2 +- core/modules/node/node.routing.yml | 7 -- core/modules/node/node.services.yml | 4 + core/modules/node/src/Form/DeleteMultiple.php | 2 +- .../node/src/Routing/RouteSubscriber.php | 37 ++++++++ .../src/Controller/SystemController.php | 9 +- .../src/Plugin/Derivative/ThemeLocalTask.php | 33 +++++++- core/modules/system/system.local_tasks.yml | 5 ++ core/modules/system/system.menu_links.yml | 6 ++ core/modules/system/system.routing.yml | 10 +++ .../Tests/Menu/SystemLocalTasksTest.php | 84 +++++++++++++++++++ .../Core/Menu/LocalTaskIntegrationTest.php | 11 +++ 18 files changed, 199 insertions(+), 40 deletions(-) create mode 100644 core/modules/node/src/Routing/RouteSubscriber.php create mode 100644 core/modules/system/tests/Drupal/system/Tests/Menu/SystemLocalTasksTest.php diff --git a/core/modules/comment/comment.local_tasks.yml b/core/modules/comment/comment.local_tasks.yml index 091321bf9455..8826d1d70040 100644 --- a/core/modules/comment/comment.local_tasks.yml +++ b/core/modules/comment/comment.local_tasks.yml @@ -16,7 +16,7 @@ comment.confirm_delete_tab: comment.admin: title: Comments route_name: comment.admin - base_route: node.content_overview + base_route: system.admin_content comment.admin_new: title: 'Published comments' diff --git a/core/modules/comment/comment.menu_links.yml b/core/modules/comment/comment.menu_links.yml index 7d715fe18561..7f0af7805aa9 100644 --- a/core/modules/comment/comment.menu_links.yml +++ b/core/modules/comment/comment.menu_links.yml @@ -1,7 +1,7 @@ comment.admin: title: Comments route_name: comment.admin - parent: system.admin + parent: system.admin_content description: 'List and edit site comments and the comment approval queue.' comment.bundle_list: title: 'Comment forms' diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index fce19d937417..8fc55372d585 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -183,19 +183,6 @@ function comment_theme() { ); } -/** - * Implements hook_menu_link_defaults_alter() - */ -function comment_menu_link_defaults_alter(&$links) { - if (isset($links['node.content_overview'])) { - // Add comments to the description for admin/content if any. - $links['node.content_overview']['description'] = 'Administer content and comments.'; - } - if (\Drupal::moduleHandler()->moduleExists('node')) { - $links['comment.admin']['parent'] = 'node.content_overview'; - } -} - /** * Returns a menu title which includes the number of unapproved comments. * diff --git a/core/modules/node/node.local_actions.yml b/core/modules/node/node.local_actions.yml index af8a56d6c9d8..b7b1577512cf 100644 --- a/core/modules/node/node.local_actions.yml +++ b/core/modules/node/node.local_actions.yml @@ -7,4 +7,4 @@ node.add_page: route_name: node.add_page title: 'Add content' appears_on: - - node.content_overview + - system.admin_content diff --git a/core/modules/node/node.local_tasks.yml b/core/modules/node/node.local_tasks.yml index d3026e117c66..c61ad9064eac 100644 --- a/core/modules/node/node.local_tasks.yml +++ b/core/modules/node/node.local_tasks.yml @@ -11,10 +11,6 @@ node.delete_confirm: base_route: node.view title: Delete weight: 10 -node.content_overview: - title: Content - route_name: node.content_overview - base_route: node.content_overview node.revision_overview: route_name: node.revision_overview base_route: node.view diff --git a/core/modules/node/node.menu_links.yml b/core/modules/node/node.menu_links.yml index 50fd002e399a..a19749466297 100644 --- a/core/modules/node/node.menu_links.yml +++ b/core/modules/node/node.menu_links.yml @@ -1,9 +1,3 @@ -node.content_overview: - title: Content - route_name: node.content_overview - parent: system.admin - description: 'Find and manage content.' - weight: -10 node.overview_types: title: 'Content types' parent: system.admin_structure diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 32d32951c26d..475e797c7d1a 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -117,7 +117,7 @@ function node_help($route_name, Request $request) { $output .= '<dt>' . t('Creating custom content types') . '</dt>'; $output .= '<dd>' . t('The Node module gives users with the <em>Administer content types</em> permission the ability to <a href="!content-new">create new content types</a> in addition to the default ones already configured. Creating custom content types allows you the flexibility to add <a href="!field">fields</a> and configure default settings that suit the differing needs of various site content.', array('!content-new' => \Drupal::url('node.type_add'), '!field' => \Drupal::url('help.page', array('name' => 'field')))) . '</dd>'; $output .= '<dt>' . t('Administering content') . '</dt>'; - $output .= '<dd>' . t('The <a href="!content">Content administration page</a> allows you to review and bulk manage your site content.', array('!content' => \Drupal::url('node.content_overview'))) . '</dd>'; + $output .= '<dd>' . t('The <a href="!content">Content administration page</a> allows you to review and bulk manage your site content.', array('!content' => \Drupal::url('system.admin_content'))) . '</dd>'; $output .= '<dt>' . t('Creating revisions') . '</dt>'; $output .= '<dd>' . t('The Node module also enables you to create multiple versions of any content, and revert to older versions using the <em>Revision information</em> settings.') . '</dd>'; $output .= '<dt>' . t('User permissions') . '</dt>'; diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml index 03ce3473bc2b..86278f2afff6 100644 --- a/core/modules/node/node.routing.yml +++ b/core/modules/node/node.routing.yml @@ -1,10 +1,3 @@ -node.content_overview: - path: '/admin/content' - defaults: - _title: 'Content' - _entity_list: 'node' - requirements: - _permission: 'access content overview' node.multiple_delete_confirm: path: '/admin/content/node/delete' diff --git a/core/modules/node/node.services.yml b/core/modules/node/node.services.yml index e211f7ba11bd..69cadb21f760 100644 --- a/core/modules/node/node.services.yml +++ b/core/modules/node/node.services.yml @@ -1,4 +1,8 @@ services: + node.route_subscriber: + class: Drupal\node\Routing\RouteSubscriber + tags: + - { name: event_subscriber } node.grant_storage: class: Drupal\node\NodeGrantDatabaseStorage arguments: ['@database', '@module_handler'] diff --git a/core/modules/node/src/Form/DeleteMultiple.php b/core/modules/node/src/Form/DeleteMultiple.php index fada9bbe559c..1e94e43c9bf4 100644 --- a/core/modules/node/src/Form/DeleteMultiple.php +++ b/core/modules/node/src/Form/DeleteMultiple.php @@ -125,7 +125,7 @@ public function submitForm(array &$form, array &$form_state) { drupal_set_message(format_plural($count, 'Deleted 1 post.', 'Deleted @count posts.')); Cache::invalidateTags(array('content' => TRUE)); } - $form_state['redirect_route']['route_name'] = 'node.content_overview'; + $form_state['redirect_route']['route_name'] = 'system.admin_content'; } } diff --git a/core/modules/node/src/Routing/RouteSubscriber.php b/core/modules/node/src/Routing/RouteSubscriber.php new file mode 100644 index 000000000000..5c9dde629724 --- /dev/null +++ b/core/modules/node/src/Routing/RouteSubscriber.php @@ -0,0 +1,37 @@ +<?php + +/** + * @file + * Contains \Drupal\node\Routing\RouteSubscriber. + */ + +namespace Drupal\node\Routing; + +use Drupal\Core\Routing\RouteSubscriberBase; +use Symfony\Component\Routing\RouteCollection; + +/** + * Listens to the dynamic route events. + */ +class RouteSubscriber extends RouteSubscriberBase { + + /** + * {@inheritdoc} + */ + protected function alterRoutes(RouteCollection $collection) { + // As nodes are the primary type of content, the node listing should be + // easily available. In order to do that, override admin/content to show + // a node listing instead of the path's child links. + $route = $collection->get('system.admin_content'); + if ($route) { + $route->setDefaults(array( + '_title' => 'Content', + '_entity_list' => 'node', + )); + $route->setRequirements(array( + '_permission' => 'access content overview', + )); + } + } + +} diff --git a/core/modules/system/src/Controller/SystemController.php b/core/modules/system/src/Controller/SystemController.php index 62272963d684..b9609687ca4a 100644 --- a/core/modules/system/src/Controller/SystemController.php +++ b/core/modules/system/src/Controller/SystemController.php @@ -94,18 +94,21 @@ public static function create(ContainerInterface $container) { /** * Provide the administration overview page. * + * @param string $path + * The administrative path for which to display child links. + * * @return array * A renderable array of the administration overview page. */ - public function overview() { + public function overview($path) { // Check for status report errors. if ($this->systemManager->checkRequirements() && $this->currentUser()->hasPermission('administer site configuration')) { drupal_set_message($this->t('One or more problems were detected with your Drupal installation. Check the <a href="@status">status report</a> for more information.', array('@status' => url('admin/reports/status'))), 'error'); } $blocks = array(); - // Load all links on admin/config and menu links below it. + // Load all links on $path and menu links below it. $query = $this->queryFactory->get('menu_link') - ->condition('link_path', 'admin/config') + ->condition('link_path', $path) ->condition('module', 'system'); $result = $query->execute(); $menu_link_storage = $this->entityManager()->getStorage('menu_link'); diff --git a/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php b/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php index da6910d1ef82..0fa1ebc7e6dc 100644 --- a/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php +++ b/core/modules/system/src/Plugin/Derivative/ThemeLocalTask.php @@ -8,17 +8,46 @@ namespace Drupal\system\Plugin\Derivative; use Drupal\Component\Plugin\Derivative\DerivativeBase; +use Drupal\Core\Extension\ThemeHandlerInterface; +use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides dynamic tabs based on active themes. */ -class ThemeLocalTask extends DerivativeBase { +class ThemeLocalTask extends DerivativeBase implements ContainerDerivativeInterface { + + /** + * The theme handler. + * + * @var \Drupal\Core\Extension\ThemeHandlerInterface + */ + protected $themeHandler; + + /** + * Constructs a new ThemeLocalTask instance. + * + * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler + * The theme handler. + */ + public function __construct(ThemeHandlerInterface $theme_handler) { + $this->themeHandler = $theme_handler; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, $base_plugin_id) { + return new static( + $container->get('theme_handler') + ); + } /** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { - foreach (list_themes() as $theme_name => $theme) { + foreach ($this->themeHandler->listInfo() as $theme_name => $theme) { if ($theme->status) { $this->derivatives[$theme_name] = $base_plugin_definition; $this->derivatives[$theme_name]['title'] = $theme->info['name']; diff --git a/core/modules/system/system.local_tasks.yml b/core/modules/system/system.local_tasks.yml index 4d597ee708a9..ebc1d0fe1a4f 100644 --- a/core/modules/system/system.local_tasks.yml +++ b/core/modules/system/system.local_tasks.yml @@ -63,3 +63,8 @@ system.date_format_edit: title: 'Edit' route_name: system.date_format_edit base_route: system.date_format_edit + +system.admin_content: + title: Content + route_name: system.admin_content + base_route: system.admin_content diff --git a/core/modules/system/system.menu_links.yml b/core/modules/system/system.menu_links.yml index 4d883a7421e3..9b1f5e314406 100644 --- a/core/modules/system/system.menu_links.yml +++ b/core/modules/system/system.menu_links.yml @@ -3,6 +3,12 @@ system.admin: route_name: system.admin weight: 9 menu_name: admin +system.admin_content: + title: Content + description: 'Find and manage content.' + route_name: system.admin_content + parent: system.admin + weight: -10 system.admin_structure: route_name: system.admin_structure parent: system.admin diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index 13019c2e0156..35e17f7bd2a4 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -382,6 +382,7 @@ system.admin_config: path: '/admin/config' defaults: _content: '\Drupal\system\Controller\SystemController::overview' + path: 'admin/config' _title: 'Configuration' requirements: _permission: 'access administration pages' @@ -408,3 +409,12 @@ system.batch_page.json: system.update: path: '/core/update.php' + +system.admin_content: + path: '/admin/content' + defaults: + _content: '\Drupal\system\Controller\SystemController::overview' + path: 'admin/content' + _title: 'Content' + requirements: + _permission: 'access administration pages' diff --git a/core/modules/system/tests/Drupal/system/Tests/Menu/SystemLocalTasksTest.php b/core/modules/system/tests/Drupal/system/Tests/Menu/SystemLocalTasksTest.php new file mode 100644 index 000000000000..9cd7ebc4fc7b --- /dev/null +++ b/core/modules/system/tests/Drupal/system/Tests/Menu/SystemLocalTasksTest.php @@ -0,0 +1,84 @@ +<?php + +/** + * @file + * Contains \Drupal\system\Tests\Menu\SystemLocalTasksTest. + */ + +namespace Drupal\system\Tests\Menu; + +use Drupal\Core\Extension\Extension; +use Drupal\Tests\Core\Menu\LocalTaskIntegrationTest; + +/** + * Tests existence of system local tasks. + * + * @group Drupal + * @group System + */ +class SystemLocalTasksTest extends LocalTaskIntegrationTest { + + /** + * The mocked theme handler. + * + * @var \Drupal\Core\Extension\ThemeHandlerInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $themeHandler; + + /** + * {@inheritdoc} + */ + public static function getInfo() { + return array( + 'name' => 'System local tasks', + 'description' => '', + 'group' => 'System', + ); + } + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + + $this->directoryList = array( + 'system' => 'core/modules/system', + ); + + $this->themeHandler = $this->getMock('Drupal\Core\Extension\ThemeHandlerInterface'); + + $theme = new Extension('theme', DRUPAL_ROOT . '/core/themes/bartik', 'bartik.info.yml'); + $theme->status = 1; + $theme->info = array('name' => 'bartik'); + $this->themeHandler->expects($this->any()) + ->method('listInfo') + ->will($this->returnValue(array( + 'bartik' => $theme, + ))); + $this->container->set('theme_handler', $this->themeHandler); + } + + /** + * Tests local task existence. + * + * @dataProvider getSystemAdminRoutes + */ + public function testSystemAdminLocalTasks($route, $expected) { + $this->assertLocalTasks($route, $expected); + } + + /** + * Provides a list of routes to test. + */ + public function getSystemAdminRoutes() { + return array( + array('system.admin_content', array(array('system.admin_content'))), + array('system.theme_settings_theme', array( + array('system.themes_page', 'system.theme_settings'), + array('system.theme_settings_global', 'system.theme_settings_theme:bartik'), + )), + ); + } + +} diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php index 0069d1504c19..234c1f3aad51 100644 --- a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php +++ b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php @@ -40,11 +40,22 @@ abstract class LocalTaskIntegrationTest extends UnitTestCase { */ protected $moduleHandler; + /** + * The container. + * + * @var \Symfony\Component\DependencyInjection\ContainerBuilder + */ + protected $container; + + /** + * {@inheritdoc} + */ protected function setUp() { $container = new ContainerBuilder(); $config_factory = $this->getConfigFactoryStub(array()); $container->set('config.factory', $config_factory); \Drupal::setContainer($container); + $this->container = $container; } /** -- GitLab