diff --git a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php index f4b8a31..15f1b96 100644 --- a/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php +++ b/core/lib/Drupal/Core/ParamConverter/ParamConverterManager.php @@ -156,7 +156,12 @@ public function enhance(array $defaults, Request $request) { // variables in the route path pattern. $route = $defaults[RouteObjectInterface::ROUTE_OBJECT]; $variables = array_flip($route->compile()->getVariables()); - $defaults['_raw_variables'] = new ParameterBag(array_intersect_key($defaults, $variables)); + // Explicitly copy values to break references. + $raw_variables = array(); + foreach (array_intersect_key($defaults, $variables) as $key => $value) { + $raw_variables[$key] = $value; + } + $defaults['_raw_variables'] = new ParameterBag($raw_variables); // Skip this enhancer if there are no parameter definitions. if (!$parameters = $route->getOption('parameters')) { diff --git a/core/modules/action/action.local_tasks.yml b/core/modules/action/action.local_tasks.yml new file mode 100644 index 0000000..b8825e0 --- /dev/null +++ b/core/modules/action/action.local_tasks.yml @@ -0,0 +1,5 @@ +action.admin: + route_name: action.admin + title: 'Manage actions' + description: 'Manage the actions defined for your site.' + tab_root_id: action.admin diff --git a/core/modules/action/action.module b/core/modules/action/action.module index 4dc9a3b..0395462 100644 --- a/core/modules/action/action.module +++ b/core/modules/action/action.module @@ -53,11 +53,6 @@ function action_menu() { 'description' => 'Manage the actions defined for your site.', 'route_name' => 'action.admin', ); - $items['admin/config/system/actions/manage'] = array( - 'title' => 'Manage actions', - 'description' => 'Manage the actions defined for your site.', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); $items['admin/config/system/actions/add'] = array( 'title' => 'Create an advanced action', 'type' => MENU_VISIBLE_IN_BREADCRUMB, diff --git a/core/modules/action/tests/Drupal/action/Tests/Menu/ActionLocalTasksTest.php b/core/modules/action/tests/Drupal/action/Tests/Menu/ActionLocalTasksTest.php new file mode 100644 index 0000000..d882c77 --- /dev/null +++ b/core/modules/action/tests/Drupal/action/Tests/Menu/ActionLocalTasksTest.php @@ -0,0 +1,39 @@ + 'Action local tasks test', + 'description' => 'Test action local tasks.', + 'group' => 'Action', + ); + } + + public function setUp() { + $this->moduleList = array('action' => 'core/modules/action/action.info'); + parent::setUp(); + } + + /** + * Test local task existence. + */ + public function testActionLocalTasks() { + $this->assertLocalTasks('action.admin', array(array('action.admin'))); + } +} diff --git a/core/modules/aggregator/aggregator.local_tasks.yml b/core/modules/aggregator/aggregator.local_tasks.yml new file mode 100644 index 0000000..8d23201 --- /dev/null +++ b/core/modules/aggregator/aggregator.local_tasks.yml @@ -0,0 +1,24 @@ +aggregator.admin_overview: + route_name: aggregator.admin_overview + title: 'List' + tab_root_id: aggregator.admin_overview +aggregator.admin_settings: + route_name: aggregator.admin_settings + title: 'Settings' + description: 'Configure the behavior of the feed aggregator, including when to discard feed items and how to present feed items and categories.' + weight: 100 + tab_root_id: aggregator.admin_overview + +aggregator.category_view: + route_name: aggregator.category_view + title: 'View' + tab_root_id: aggregator.category_view +aggregator.categorize_feed_form: + route_name: aggregator.categorize_feed_form + title: 'Categorize' + tab_root_id: aggregator.category_view +aggregator.feed_configure: + route_name: aggregator.feed_configure + title: 'Configure' + tab_root_id: aggregator.category_view + weight: 10 diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module index 7238278..af58913 100644 --- a/core/modules/aggregator/aggregator.module +++ b/core/modules/aggregator/aggregator.module @@ -92,6 +92,7 @@ function aggregator_theme() { */ function aggregator_menu() { $items['admin/config/services/aggregator'] = array( + 'title' => 'Feed aggregator', 'description' => "Configure which content your site aggregates from other sites, how often it polls them, and how they're categorized.", 'route_name' => 'aggregator.admin_overview', 'weight' => 10, @@ -119,17 +120,6 @@ function aggregator_menu() { 'title' => 'Update items', 'route_name' => 'aggregator.feed_refresh', ); - $items['admin/config/services/aggregator/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['admin/config/services/aggregator/settings'] = array( - 'title' => 'Settings', - 'description' => 'Configure the behavior of the feed aggregator, including when to discard feed items and how to present feed items and categories.', - 'route_name' => 'aggregator.admin_settings', - 'type' => MENU_LOCAL_TASK, - 'weight' => 100, - ); $items['aggregator'] = array( 'title' => 'Feed aggregator', 'weight' => 5, @@ -148,41 +138,26 @@ function aggregator_menu() { 'title arguments' => array(2), 'route_name' => 'aggregator.category_view', ); - $items['aggregator/categories/%aggregator_category/view'] = array( - 'title' => 'View', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['aggregator/categories/%aggregator_category/categorize'] = array( - 'title' => 'Categorize', - 'type' => MENU_LOCAL_TASK, - 'route_name' => 'aggregator.categorize_category_form', - ); - $items['aggregator/categories/%aggregator_category/configure'] = array( - 'title' => 'Configure', - 'type' => MENU_LOCAL_TASK, - 'weight' => 10, - 'route_name' => 'aggregator.category_edit', - ); $items['aggregator/sources/%aggregator_feed'] = array( 'title callback' => 'entity_page_label', 'title arguments' => array(2), 'route_name' => 'aggregator.feed_view', ); - $items['aggregator/sources/%aggregator_feed/view'] = array( - 'title' => 'View', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['aggregator/sources/%aggregator_feed/categorize'] = array( - 'title' => 'Categorize', - 'route_name' => 'aggregator.categorize_feed_form', - 'type' => MENU_LOCAL_TASK, - ); - $items['aggregator/sources/%aggregator_feed/configure'] = array( - 'title' => 'Configure', - 'route_name' => 'aggregator.feed_configure', - 'type' => MENU_LOCAL_TASK, - 'weight' => 10, - ); +// $items['aggregator/sources/%aggregator_feed/view'] = array( +// 'title' => 'View', +// 'type' => MENU_DEFAULT_LOCAL_TASK, +// ); +// $items['aggregator/sources/%aggregator_feed/categorize'] = array( +// 'title' => 'Categorize', +// 'route_name' => 'aggregator.categorize_feed_form', +// 'type' => MENU_LOCAL_TASK, +// ); +// $items['aggregator/sources/%aggregator_feed/configure'] = array( +// 'title' => 'Configure', +// 'route_name' => 'aggregator.feed_configure', +// 'type' => MENU_LOCAL_TASK, +// 'weight' => 10, +// ); $items['admin/config/services/aggregator/edit/feed/%aggregator_feed'] = array( 'title' => 'Edit feed', 'route_name' => 'aggregator.feed_edit', diff --git a/core/modules/aggregator/tests/Drupal/aggregator/Tests/Menu/AggregatorLocalTasksTest.php b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Menu/AggregatorLocalTasksTest.php new file mode 100644 index 0000000..76a154c --- /dev/null +++ b/core/modules/aggregator/tests/Drupal/aggregator/Tests/Menu/AggregatorLocalTasksTest.php @@ -0,0 +1,81 @@ + 'Aggregator local tasks test', + 'description' => 'Test existence of aggregator local tasks.', + 'group' => 'Aggregator', + ); + } + + /** + * @{inheritdoc} + */ + public function setUp() { + $this->moduleList = array('aggregator' => 'core/modules/aggregator/aggregator.info'); + parent::setUp(); + } + + /** + * Test local task existence. + * + * @dataProvider getAggregatorAdminRoutes + */ + public function testAggregatorAdminLocalTasks($route) { + $this->assertLocalTasks('aggregator.admin_overview', array( + 0 => array($route, 'aggregator.admin_settings'), + )); + } + + /** + * Provide a list of routes to test. + */ + public function getAggregatorAdminRoutes() { + return array( + array('aggregator.admin_overview'), + ); + } + + /** + * Check category aggregator tasks. + * + * @dataProvider getAggregatorCategoryRoutes + */ + public function testAggregatorCategoryLocalTasks($route) { + $this->assertLocalTasks($route, array( + 0 => array('aggregator.category_view', 'aggregator.categorize_feed_form', 'aggregator.feed_configure'), + )); + ; + } + + /** + * Provide a list of routes to test. + */ + public function getAggregatorCategoryRoutes() { + return array( + array('aggregator.category_view'), + array('aggregator.categorize_feed_form'), + array('aggregator.feed_configure'), + ); + } +} diff --git a/core/modules/block/block.local_tasks.yml b/core/modules/block/block.local_tasks.yml new file mode 100644 index 0000000..2a9b2ce --- /dev/null +++ b/core/modules/block/block.local_tasks.yml @@ -0,0 +1,16 @@ +block.admin_edit: + route_name: block.admin_edit + title: 'Configure block' + tab_root_id: block.admin_edit + +# Per theme block layout pages. +block.admin_display: + route_name: block.admin_display + title: 'Block Layout' + tab_root_id: block.admin_display +block.admin_display_theme: + route_name: block.admin_display_theme + title: 'Block Layout' + tab_root_id: block.admin_display + tab_parent_id: block.admin_display + derivative: 'Drupal\block\Plugin\Derivative\ThemeLocalTask' diff --git a/core/modules/block/block.module b/core/modules/block/block.module index f1112d6..438e946 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -104,17 +104,13 @@ function block_menu() { 'description' => 'Configure what block content appears in your site\'s sidebars and other regions.', 'route_name' => 'block.admin_display', ); - $items['admin/structure/block/list'] = array( - 'title' => 'Block layout', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); $items['admin/structure/block/manage/%block'] = array( 'title' => 'Configure block', 'route_name' => 'block.admin_edit', ); $items['admin/structure/block/manage/%block/configure'] = array( 'title' => 'Configure block', - 'type' => MENU_DEFAULT_LOCAL_TASK, +// 'type' => MENU_DEFAULT_LOCAL_TASK, 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, ); $items['admin/structure/block/add/%/%'] = array( @@ -125,15 +121,9 @@ function block_menu() { // Block administration is tied to the theme and plugin definition so // that the plugin can appropriately attach to this URL structure. // @todo D8: Use dynamic % arguments instead of static, hard-coded theme names - // and plugin IDs to decouple the routes from these dependencies and allow - // hook_menu_local_tasks() to check for the untranslated tab_parent path. + // and plugin IDs to decouple the routes from these dependencies. // @see http://drupal.org/node/1067408 foreach (list_themes() as $key => $theme) { - $items["admin/structure/block/list/$key"] = array( - 'title' => check_plain($theme->info['name']), - 'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK, - 'route_name' => "block.admin_display_$key", - ); $items["admin/structure/block/demo/$key"] = array( 'title' => check_plain($theme->info['name']), 'route_name' => 'block.admin_demo', diff --git a/core/modules/block/block.routing.yml b/core/modules/block/block.routing.yml index 5b87e2f..8f567b5 100644 --- a/core/modules/block/block.routing.yml +++ b/core/modules/block/block.routing.yml @@ -31,6 +31,14 @@ block.admin_display: requirements: _permission: 'administer blocks' +block.admin_display_theme: + path: 'admin/structure/block/list/{theme_name}' + defaults: + _controller: '\Drupal\block\Controller\BlockListController::listing' + requirements: + _access_theme: 'TRUE' + _permission: 'administer blocks' + block.admin_add: path: '/admin/structure/block/add/{plugin_id}/{theme}' defaults: diff --git a/core/modules/block/block.services.yml b/core/modules/block/block.services.yml index c6704bc..b6bf1f4 100644 --- a/core/modules/block/block.services.yml +++ b/core/modules/block/block.services.yml @@ -9,7 +9,3 @@ services: factory_method: get factory_service: cache_factory arguments: [block] - block.route_subscriber: - class: Drupal\block\Routing\RouteSubscriber - tags: - - { name: event_subscriber} diff --git a/core/modules/block/custom_block/custom_block.local_tasks.yml b/core/modules/block/custom_block/custom_block.local_tasks.yml new file mode 100644 index 0000000..57a27b8 --- /dev/null +++ b/core/modules/block/custom_block/custom_block.local_tasks.yml @@ -0,0 +1,14 @@ +custom_block.list: + route_name: custom_block.list + tab_root_id: block.admin_display + title: 'Manage custom blocks.' +custom_block.list_sub: + route_name: custom_block.list + tab_root_id: block.admin_display + tab_parent_id: custom_block.list + title: Blocks +custom_block.type_list: + route_name: custom_block.type_list + tab_root_id: block.admin_display + tab_parent_id: custom_block.list + title: Types diff --git a/core/modules/block/custom_block/custom_block.module b/core/modules/block/custom_block/custom_block.module index eed50a4..4613a1e 100644 --- a/core/modules/block/custom_block/custom_block.module +++ b/core/modules/block/custom_block/custom_block.module @@ -71,16 +71,7 @@ function custom_block_menu() { 'title' => 'Custom block library', 'description' => 'Manage custom blocks.', 'route_name' => 'custom_block.list', - 'type' => MENU_LOCAL_TASK | MENU_NORMAL_ITEM, - ); - $items['admin/structure/block/custom-blocks/list'] = array( - 'title' => 'Blocks', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['admin/structure/block/custom-blocks/types'] = array( - 'title' => 'Types', - 'route_name' => 'custom_block.type_list', - 'type' => MENU_LOCAL_TASK, + 'type' => MENU_NORMAL_ITEM, ); $items['admin/structure/block/custom-blocks/types/add'] = array( 'route_name' => 'custom_block.type_add', @@ -115,13 +106,13 @@ function custom_block_menu() { $items['block/%custom_block/edit'] = array( 'title' => 'Edit', 'weight' => 0, - 'type' => MENU_DEFAULT_LOCAL_TASK, + 'type' => MENU_DEFAULT_LOCAL_TASK, // Not a local task. Breadcrumb management. 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, ); $items['block/%custom_block/delete'] = array( 'title' => 'Delete', 'weight' => 1, - 'type' => MENU_LOCAL_TASK, + 'type' => MENU_LOCAL_TASK, // Not a local task. Breadcrumb management. 'context' => MENU_CONTEXT_INLINE, 'route_name' => 'custom_block.delete', ); diff --git a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php index e37328d..12f2b72 100644 --- a/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php +++ b/core/modules/block/custom_block/lib/Drupal/custom_block/Plugin/Derivative/CustomBlock.php @@ -8,6 +8,7 @@ namespace Drupal\custom_block\Plugin\Derivative; use Drupal\Component\Plugin\Derivative\DerivativeBase; +use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface; /** * Retrieves block plugin definitions for all custom blocks. diff --git a/core/modules/block/custom_block/tests/Drupal/custom_blocks/Tests/Menu/CustomBlockLocalTasksTest.php b/core/modules/block/custom_block/tests/Drupal/custom_blocks/Tests/Menu/CustomBlockLocalTasksTest.php new file mode 100644 index 0000000..8951f63 --- /dev/null +++ b/core/modules/block/custom_block/tests/Drupal/custom_blocks/Tests/Menu/CustomBlockLocalTasksTest.php @@ -0,0 +1,69 @@ + 'Custom Block local tasks test', + 'description' => 'Test custom_block local tasks.', + 'group' => 'Block', + ); + } + + /** + * @{inheritdoc} + */ + public function setUp() { + $this->moduleList = array( + 'block' => 'core/modules/block/block.info', + 'custom_block' => 'core/modules/block/custom_block/custom_block.info', + ); + parent::setUp(); + } + + /** + * Check custom_block listing local tasks + * + * @dataProvider getCustomBlockListingRoutes + */ + public function testCustomBlockListLocalTasks($route) { + // + $this->assertLocalTasks($route, array( + 0 => array( + 'block.admin_display', + 'custom_block.list', + ), + 1 => array( + 'custom_block.list_sub', + 'custom_block.type_list', + ) + )); + } + + /** + * Provide a list of routes to test.C + */ + public function getCustomBlockListingRoutes() { + return array( + array('custom_block.list', 'custom_block.type_list'), + ); + } +} diff --git a/core/modules/block/lib/Drupal/block/Plugin/Derivative/ThemeLocalTask.php b/core/modules/block/lib/Drupal/block/Plugin/Derivative/ThemeLocalTask.php new file mode 100644 index 0000000..ba897e4 --- /dev/null +++ b/core/modules/block/lib/Drupal/block/Plugin/Derivative/ThemeLocalTask.php @@ -0,0 +1,42 @@ +get('default'); + + foreach (list_themes() as $theme_name => $theme) { + if ($theme->status) { + $this->derivatives[$theme_name] = $base_plugin_definition; + $this->derivatives[$theme_name]['title'] = $theme->info['name']; + $this->derivatives[$theme_name]['route_parameters'] = array('theme_name' => $theme_name); + } + // Default task! + if ($default_theme == $theme_name) { + $this->derivatives[$theme_name]['route_name'] = 'block.admin_display'; + // Emulate default logic because without the base plugin id we can't set the + // change the tab_root_id. + $this->derivatives[$theme_name]['weight'] = -10; + + unset($this->derivatives[$theme_name]['route_parameters']); + } + } + return $this->derivatives; + } + +} diff --git a/core/modules/block/lib/Drupal/block/Routing/RouteSubscriber.php b/core/modules/block/lib/Drupal/block/Routing/RouteSubscriber.php deleted file mode 100644 index f60e51a..0000000 --- a/core/modules/block/lib/Drupal/block/Routing/RouteSubscriber.php +++ /dev/null @@ -1,60 +0,0 @@ -getRouteCollection(); - foreach (list_themes(TRUE) as $key => $theme) { - // The block entity listing page. - $route = new Route( - "admin/structure/block/list/$key", - array( - '_controller' => '\Drupal\block\Controller\BlockListController::listing', - 'theme' => $key, - ), - array( - '_access_theme' => 'TRUE', - '_permission' => 'administer blocks', - ), - array( - '_access_mode' => 'ALL', - ) - ); - $collection->add("block.admin_display_$key", $route); - } - } - -} diff --git a/core/modules/block/tests/Drupal/block/Tests/Menu/BlockLocalTasksTest.php b/core/modules/block/tests/Drupal/block/Tests/Menu/BlockLocalTasksTest.php new file mode 100644 index 0000000..5ac19bf --- /dev/null +++ b/core/modules/block/tests/Drupal/block/Tests/Menu/BlockLocalTasksTest.php @@ -0,0 +1,73 @@ + 'Block local tasks test', + 'description' => 'Test block local tasks.', + 'group' => 'Block', + ); + } + + /** + * @{inheritdoc} + */ + public function setUp() { + $this->moduleList = array('block' => 'core/modules/block/block.info'); + parent::setUp(); + } + + /** + * Test local task existence. + */ + public function testBlockAdminLocalTasks() { + $this->markTestIncomplete( + 'This test has not been implemented yet. list_theme() and Drupal::config() calls fail.' + ); + //$this->assertLocalTasks('block.admin_edit', array(array('block.admin_edit'))); + } + + /** + * Check block listing local tasks + * + * @dataProvider getBlockListingRoutes + */ + public function testBlockListLocalTasks($route) { + $this->markTestIncomplete( + 'This test has not been implemented yet. list_theme() and Drupal::config() calls fail.' + ); + // +// $this->assertLocalTasks($route, array( +// 0 => array('aggregator.category_view', 'aggregator.categorize_feed_form', 'aggregator.feed_configure'), +// )); + } + + /** + * Provide a list of routes to test. + */ + public function getBlockListingRoutes() { + return array( + array('placeholder'), + // theme_list() + ); + } +} diff --git a/core/modules/book/book.local_tasks.yml b/core/modules/book/book.local_tasks.yml new file mode 100644 index 0000000..f0f8464 --- /dev/null +++ b/core/modules/book/book.local_tasks.yml @@ -0,0 +1,15 @@ +book.admin: + route_name: book.admin + title: 'List' + tab_root_id: book.admin +book.settings: + route_name: book.settings + title: 'Settings' + tab_root_id: book.admin + weight: 100 + +book.outline: + route_name: book.outline + tab_root_id: node.view + title: Outline + weight: 2 diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 282aa92..d53ab93 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -171,28 +171,11 @@ function book_menu() { 'description' => "Manage your site's book outlines.", 'route_name' => 'book.admin', ); - $items['admin/structure/book/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['admin/structure/book/settings'] = array( - 'title' => 'Settings', - 'route_name' => 'book.settings', - 'access arguments' => array('administer site configuration'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 100, - ); $items['book'] = array( 'title' => 'Books', 'route_name' => 'book.render', 'type' => MENU_SUGGESTED_ITEM, ); - $items['node/%node/outline'] = array( - 'title' => 'Outline', - 'route_name' => 'book.outline', - 'type' => MENU_LOCAL_TASK, - 'weight' => 2, - ); $items['node/%node/outline/remove'] = array( 'title' => 'Remove from outline', 'route_name' => 'book.remove', diff --git a/core/modules/book/tests/Drupal/book/Tests/Menu/BookLocalTasksTest.php b/core/modules/book/tests/Drupal/book/Tests/Menu/BookLocalTasksTest.php new file mode 100644 index 0000000..e8aa150 --- /dev/null +++ b/core/modules/book/tests/Drupal/book/Tests/Menu/BookLocalTasksTest.php @@ -0,0 +1,84 @@ + 'Book local tasks test', + 'description' => 'Test existence of book local tasks.', + 'group' => 'Book', + ); + } + + /** + * @{inheritdoc} + */ + public function setUp() { + $this->moduleList = array( + 'book' => 'core/modules/book/book.info', + 'node' => 'core/modules/node/node.info', + ); + parent::setUp(); + } + + /** + * Test local task existence. + * + * @dataProvider getBookAdminRoutes + */ + public function testBookAdminLocalTasks($route) { + + $this->assertLocalTasks($route, array( + 0 => array('book.admin', 'book.settings'), + )); + } + + /** + * Provide a list of routes to test. + */ + public function getBookAdminRoutes() { + return array( + array('book.admin'), + array('book.settings'), + ); + } + + /** + * Test local task existence. + * + * @dataProvider getBookNodeRoutes + */ + public function testBookNodeLocalTasks($route) { + $this->assertLocalTasks($route, array( + 0 => array('book.outline', 'node.view', 'node.page_edit', 'node.delete_confirm', 'node.revision_overview',), + )); + } + + /** + * Provide a list of routes to test. + */ + public function getBookNodeRoutes() { + return array( + array('node.view'), + array('book.outline'), + ); + } +} diff --git a/core/modules/comment/comment.local_tasks.yml b/core/modules/comment/comment.local_tasks.yml index ee8d3bf..353a831 100644 --- a/core/modules/comment/comment.local_tasks.yml +++ b/core/modules/comment/comment.local_tasks.yml @@ -1,15 +1,15 @@ -comment_permalink_tab: - route_name: comment_permalink +comment.permalink: + route_name: comment.permalink title: 'View comment' - tab_root_id: comment_permalink_tab -comment_edit_page_tab: - route_name: comment_edit_page + tab_root_id: comment.permalink +comment.edit_page: + route_name: comment.edit_page title: 'Edit' - tab_root_id: comment_permalink_tab + tab_root_id: comment.permalink weight: 0 -comment_confirm_delete_tab: - route_name: comment_confirm_delete +comment.confirm_delete: + route_name: comment.confirm_delete title: 'Delete' - tab_root_id: comment_permalink_tab + tab_root_id: comment.permalink weight: 10 diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index fb2f320..fbba68a 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -227,28 +227,28 @@ function comment_menu() { 'title' => 'Comment permalink', 'route_name' => 'comment.permalink', ); - $items['comment/%comment/view'] = array( - 'title' => 'View comment', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - // Every other comment path uses %, but this one loads the comment directly, - // so we don't end up loading it twice (in the page and access callback). - $items['comment/%comment/edit'] = array( - 'title' => 'Edit', - 'type' => MENU_LOCAL_TASK, - 'route_name' => 'comment.edit_page', - ); +// $items['comment/%comment/view'] = array( +// 'title' => 'View comment', +// 'type' => MENU_DEFAULT_LOCAL_TASK, +// ); +// // Every other comment path uses %, but this one loads the comment directly, +// // so we don't end up loading it twice (in the page and access callback). +// $items['comment/%comment/edit'] = array( +// 'title' => 'Edit', +// 'type' => MENU_LOCAL_TASK, +// 'route_name' => 'comment.edit_page', +// ); $items['comment/%comment/approve'] = array( 'title' => 'Approve', 'weight' => 10, 'route_name' => 'comment.approve', ); - $items['comment/%comment/delete'] = array( - 'title' => 'Delete', - 'type' => MENU_LOCAL_TASK, - 'route_name' => 'comment.confirm_delete', - 'weight' => 20, - ); +// $items['comment/%comment/delete'] = array( +// 'title' => 'Delete', +// 'type' => MENU_LOCAL_TASK, +// 'route_name' => 'comment.confirm_delete', +// 'weight' => 20, +// ); return $items; } diff --git a/core/modules/config/config.local_tasks.yml b/core/modules/config/config.local_tasks.yml new file mode 100644 index 0000000..c2b6916 --- /dev/null +++ b/core/modules/config/config.local_tasks.yml @@ -0,0 +1,22 @@ +config.sync: + route_name: config.sync + tab_root_id: config.sync + title: 'Synchronize' + weight: 0 +config.export: + route_name: config.export + tab_root_id: config.sync + title: Export + weight: 1 +config.import: + route_name: config.import + title: Import + tab_root_id: config.sync + weight: 2 +# todo I'm not sure why there are two imports. is there history here? +config.sync_import: + route_name: config.sync + tab_root_id: config.sync + tab_parent_id: config.sync + title: 'Import' + weight: 0 diff --git a/core/modules/config/config.module b/core/modules/config/config.module index 5e93c02..6d73294 100644 --- a/core/modules/config/config.module +++ b/core/modules/config/config.module @@ -64,37 +64,29 @@ function config_menu() { $items['admin/config/development/configuration'] = array( 'title' => 'Configuration management', 'description' => 'Import, export, or synchronize your site configuration.', - 'route_name' => 'config_management', + 'route_name' => 'config.sync', ); + #this page doesn't really exist. It was an old task that collapsed up. $items['admin/config/development/configuration/sync'] = array( 'title' => 'Synchronize', 'description' => 'Synchronize configuration changes.', 'route_name' => 'config.sync', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => 0, ); $items['admin/config/development/configuration/export'] = array( 'title' => 'Export', 'description' => 'Export your site configuration', 'route_name' => 'config.export', - 'type' => MENU_LOCAL_TASK, - 'weight' => 1, ); $items['admin/config/development/configuration/import'] = array( 'title' => 'Import', 'description' => 'Import configuration for your site', 'route_name' => 'config.import', - 'type' => MENU_LOCAL_TASK, - 'weight' => 2, ); $items['admin/config/development/configuration/sync/diff/%'] = array( 'title' => 'Configuration file diff', 'description' => 'Diff between active and staged configuration.', 'route_name' => 'config.diff', ); - $items['admin/config/development/configuration/sync/import'] = array( - 'title' => 'Import', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); + return $items; } diff --git a/core/modules/config/config.routing.yml b/core/modules/config/config.routing.yml index 3eaeb34..c3a6850 100644 --- a/core/modules/config/config.routing.yml +++ b/core/modules/config/config.routing.yml @@ -1,14 +1,14 @@ -config.diff: - path: '/admin/config/development/configuration/sync/diff/{config_file}' +config.sync: + path: '/admin/config/development/configuration' defaults: - _content: '\Drupal\config\Controller\ConfigController::diff' + _form: '\Drupal\config\Form\ConfigSync' requirements: _permission: 'synchronize configuration' -config_management: - path: '/admin/config/development/configuration' +config.diff: + path: '/admin/config/development/configuration/sync/diff/{config_file}' defaults: - _form: '\Drupal\config\Form\ConfigSync' + _content: '\Drupal\config\Controller\ConfigController::diff' requirements: _permission: 'synchronize configuration' @@ -32,10 +32,3 @@ config.import: _form: '\Drupal\config\Form\ConfigImportForm' requirements: _permission: 'import configuration' - -config.sync: - path: '/admin/config/development/configuration/sync' - defaults: - _form: '\Drupal\config\Form\ConfigSync' - requirements: - _permission: 'synchronize configuration' diff --git a/core/modules/field_ui/field_ui.local_tasks.yml b/core/modules/field_ui/field_ui.local_tasks.yml new file mode 100644 index 0000000..e690491 --- /dev/null +++ b/core/modules/field_ui/field_ui.local_tasks.yml @@ -0,0 +1,4 @@ +field_ui.list: + title: Entities + route_name: field_ui.list + tab_root_id: field_ui.list diff --git a/core/modules/field_ui/field_ui.module b/core/modules/field_ui/field_ui.module index 0d81232..dc0d38f 100644 --- a/core/modules/field_ui/field_ui.module +++ b/core/modules/field_ui/field_ui.module @@ -60,10 +60,6 @@ function field_ui_menu() { 'route_name' => 'field_ui.list', 'type' => MENU_NORMAL_ITEM, ); - $items['admin/reports/fields/list'] = array( - 'title' => 'Entities', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); // Create tabs for all possible bundles. foreach (entity_get_info() as $entity_type => $entity_info) { diff --git a/core/modules/forum/forum.local_tasks.yml b/core/modules/forum/forum.local_tasks.yml new file mode 100644 index 0000000..4cd9dcb --- /dev/null +++ b/core/modules/forum/forum.local_tasks.yml @@ -0,0 +1,9 @@ +forum.overview: + route_name: forum.overview + tab_root_id: forum.overview + title: List +forum.settings: + route_name: forum.settings + tab_root_id: forum.overview + title: Settings + weight: 100 diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 0c1815f..a38b8db 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -119,17 +119,6 @@ function forum_menu() { 'description' => 'Control forum hierarchy settings.', 'route_name' => 'forum.overview', ); - $items['admin/structure/forum/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['admin/structure/forum/settings'] = array( - 'title' => 'Settings', - 'weight' => 100, - 'type' => MENU_LOCAL_TASK, - 'parent' => 'admin/structure/forum', - 'route_name' => 'forum.settings', - ); $items['admin/structure/forum/edit/container/%taxonomy_term'] = array( 'title' => 'Edit container', 'route_name' => 'forum.edit_container', diff --git a/core/modules/locale/locale.local_tasks.yml b/core/modules/locale/locale.local_tasks.yml new file mode 100644 index 0000000..ade24ed --- /dev/null +++ b/core/modules/locale/locale.local_tasks.yml @@ -0,0 +1,22 @@ +locale.translate_page: + route_name: locale.translate_page + tab_root_id: locale.translate_page + title: Translate + +locale.translate_import: + route_name: locale.translate_import + tab_root_id: locale.translate_page + title: Import + weight: 20 + +locale.translate_export: + route_name: locale.translate_export + tab_root_id: locale.translate_page + title: Export + weight: 30 + +locale.settings: + route_name: locale.settings + tab_root_id: locale.translate_page + title: Settings + weight: 100 diff --git a/core/modules/locale/locale.module b/core/modules/locale/locale.module index 3ae54e1..77185fe 100644 --- a/core/modules/locale/locale.module +++ b/core/modules/locale/locale.module @@ -176,28 +176,7 @@ function locale_menu() { 'route_name' => 'locale.translate_page', 'weight' => -5, ); - $items['admin/config/regional/translate/translate'] = array( - 'title' => 'Translate', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['admin/config/regional/translate/import'] = array( - 'title' => 'Import', - 'route_name' => 'locale.translate_import', - 'weight' => 20, - 'type' => MENU_LOCAL_TASK, - ); - $items['admin/config/regional/translate/export'] = array( - 'title' => 'Export', - 'route_name' => 'locale.translate_export', - 'weight' => 30, - 'type' => MENU_LOCAL_TASK, - ); - $items['admin/config/regional/translate/settings'] = array( - 'title' => 'Settings', - 'route_name' => 'locale.settings', - 'weight' => 100, - 'type' => MENU_LOCAL_TASK, - ); + $items['admin/reports/translations'] = array( 'title' => 'Available translation updates', 'route_name' => 'locale.translate_status', diff --git a/core/modules/locale/tests/Drupal/locale/Tests/Menu/LocaleLocalTasksTest.php b/core/modules/locale/tests/Drupal/locale/Tests/Menu/LocaleLocalTasksTest.php new file mode 100644 index 0000000..187df06 --- /dev/null +++ b/core/modules/locale/tests/Drupal/locale/Tests/Menu/LocaleLocalTasksTest.php @@ -0,0 +1,64 @@ + 'Locale local tasks test', + 'description' => 'Test locale local tasks.', + 'group' => 'Locale', + ); + } + + /** + * @{inheritdoc} + */ + public function setUp() { + $this->moduleList = array( + 'locale' => 'core/modules/locale/locale.info', + ); + parent::setUp(); + } + + /** + * Check locale listing local tasks + * + * @dataProvider getLocalePageRoutes + */ + public function testLocalePageLocalTasks($route) { + $tasks = array( + 0 => array('locale.translate_page', 'locale.translate_import', 'locale.translate_export','locale.settings'), + ); + $this->assertLocalTasks($route, $tasks); + } + + /** + * Provide a list of routes to test. + */ + public function getLocalePageRoutes() { + return array( + array('locale.translate_page'), + array('locale.translate_import'), + array('locale.translate_export'), + array('locale.settings'), + ); + } +} diff --git a/core/modules/node/node.local_tasks.yml b/core/modules/node/node.local_tasks.yml new file mode 100644 index 0000000..24d9ef2 --- /dev/null +++ b/core/modules/node/node.local_tasks.yml @@ -0,0 +1,18 @@ +node.view: + route_name: node.view + tab_root_id: node.view + title: 'View' +node.page_edit: + route_name: node.page_edit + tab_root_id: node.view + title: Edit +node.delete_confirm: + route_name: node.delete_confirm + tab_root_id: node.view + title: Delete + weight: 10 +node.revision_overview: + route_name: node.revision_overview + tab_root_id: node.view + title: 'Revisions' + weight: 20 diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 0dcda45..09f5e58 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -1001,7 +1001,7 @@ function node_menu() { ); $items['admin/structure/types/manage/%node_type/edit'] = array( 'title' => 'Edit', - 'type' => MENU_DEFAULT_LOCAL_TASK, + 'type' => MENU_DEFAULT_LOCAL_TASK, // Entity base ); $items['node/add'] = array( 'title' => 'Add content', @@ -1014,36 +1014,16 @@ function node_menu() { 'description arguments' => array(2), 'route_name' => 'node.add', ); - $items['node/%node'] = array( - 'title callback' => 'node_page_title', - 'title arguments' => array(1), - // The controller also sets the #title in case the routes' title is - // overridden by a menu link. - 'route_name' => 'node.view', - ); - $items['node/%node/view'] = array( - 'title' => 'View', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); $items['node/%node/edit'] = array( 'title' => 'Edit', 'route_name' => 'node.page_edit', - 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, ); $items['node/%node/delete'] = array( 'title' => 'Delete', 'route_name' => 'node.delete_confirm', - 'weight' => 10, - 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_INLINE, ); - $items['node/%node/revisions'] = array( - 'title' => 'Revisions', - 'route_name' => 'node.revision_overview', - 'weight' => 20, - 'type' => MENU_LOCAL_TASK, - ); $items['node/%node/revisions/%node_revision/view'] = array( 'title' => 'Revisions', 'route_name' => 'node.revision_show', @@ -1076,21 +1056,6 @@ function node_menu_local_tasks(&$data, $router_item, $root_path) { } /** - * Title callback: Displays the node's title. - * - * @param \Drupal\Core\Entity\EntityInterface $node - * The node entity. - * - * @return - * An unsanitized string that is the title of the node. - * - * @see node_menu() - */ -function node_page_title(EntityInterface $node) { - return $node->label(); -} - -/** * Finds the last time a node was changed. * * @param $nid diff --git a/core/modules/shortcut/shortcut.local_tasks.yml b/core/modules/shortcut/shortcut.local_tasks.yml new file mode 100644 index 0000000..edfeaeb --- /dev/null +++ b/core/modules/shortcut/shortcut.local_tasks.yml @@ -0,0 +1,4 @@ +shortcut.overview: + route_name: shortcut.overview + tab_root_id: user.view + title: 'Shortcuts' diff --git a/core/modules/shortcut/shortcut.module b/core/modules/shortcut/shortcut.module index 8ea2fa1..c108f9a 100644 --- a/core/modules/shortcut/shortcut.module +++ b/core/modules/shortcut/shortcut.module @@ -119,11 +119,6 @@ function shortcut_menu() { 'title' => 'Delete shortcut', 'route_name' => 'shortcut.link_delete', ); - $items['user/%user/shortcuts'] = array( - 'title' => 'Shortcuts', - 'route_name' => 'shortcut.overview', - 'type' => MENU_LOCAL_TASK, - ); return $items; } diff --git a/core/modules/shortcut/tests/Drupal/shortcut/Tests/Menu/ShortcutLocalTasksTest.php b/core/modules/shortcut/tests/Drupal/shortcut/Tests/Menu/ShortcutLocalTasksTest.php new file mode 100644 index 0000000..4e52d49 --- /dev/null +++ b/core/modules/shortcut/tests/Drupal/shortcut/Tests/Menu/ShortcutLocalTasksTest.php @@ -0,0 +1,64 @@ + 'Shortcut local tasks test', + 'description' => 'Test shortcut local tasks.', + 'group' => 'Shortcut', + ); + } + + /** + * @{inheritdoc} + */ + public function setUp() { + $this->moduleList = array( + 'shortcut' => 'core/modules/shortcut/shortcut.info', + 'user' => 'core/modules/user/user.info', + ); + parent::setUp(); + } + + /** + * Check shortcut listing local tasks + * + * @dataProvider getShortcutPageRoutes + */ + public function testShortcutPageLocalTasks($route) { + $tasks = array( + 0 => array('shortcut.overview', 'user.view', 'user.edit',), + ); + $this->assertLocalTasks($route, $tasks); + } + + /** + * Provide a list of routes to test. + */ + public function getShortcutPageRoutes() { + return array( + array('user.view'), + array('user.edit'), + array('shortcut.overview'), + ); + } +} diff --git a/core/modules/system/lib/Drupal/system/Plugin/Derivative/ThemeLocalTask.php b/core/modules/system/lib/Drupal/system/Plugin/Derivative/ThemeLocalTask.php new file mode 100644 index 0000000..992fc03 --- /dev/null +++ b/core/modules/system/lib/Drupal/system/Plugin/Derivative/ThemeLocalTask.php @@ -0,0 +1,31 @@ + $theme) { + if ($theme->status) { + $this->derivatives[$theme_name] = $base_plugin_definition; + $this->derivatives[$theme_name]['title'] = $theme->info['name']; + $this->derivatives[$theme_name]['route_parameters'] = array('theme_name' => $theme_name); + } + } + return $this->derivatives; + } + +} diff --git a/core/modules/system/lib/Drupal/system/Routing/RouteSubscriber.php b/core/modules/system/lib/Drupal/system/Routing/RouteSubscriber.php deleted file mode 100644 index 600e6af..0000000 --- a/core/modules/system/lib/Drupal/system/Routing/RouteSubscriber.php +++ /dev/null @@ -1,47 +0,0 @@ -getRouteCollection(); - foreach (list_themes() as $theme) { - if (!empty($theme->status)) { - $route = new Route('admin/appearance/settings/' . $theme->name, array( - '_form' => '\Drupal\system\Form\ThemeSettingsForm', 'theme_name' => $theme->name), array( - '_permission' => 'administer themes', - )); - $collection->add('system.theme_settings_' . $theme->name, $route); - } - } - } - -} diff --git a/core/modules/system/system.local_tasks.yml b/core/modules/system/system.local_tasks.yml index b29773d..89c7f92 100644 --- a/core/modules/system/system.local_tasks.yml +++ b/core/modules/system/system.local_tasks.yml @@ -1,14 +1,64 @@ system.rss_feeds_settings_tab: route_name: system.rss_feeds_settings - title: Settings tab_root_id: system.rss_feeds_settings_tab + title: Settings system.site_maintenance_mode_settings_tab: route_name: system.site_maintenance_mode - title: Settings tab_root_id: system.site_maintenance_mode_settings_tab + title: Settings system.site_information_settings_tab: route_name: system.site_information_settings - title: Settings tab_root_id: system.site_information_settings_tab + title: Settings + +system.themes_page: + route_name: system.themes_page + title: List + description: 'Select and configure your theme' + tab_root_id: system.themes_page + +system.theme_settings: + route_name: system.theme_settings + title: Settings + description: 'Configure default and theme specific settings.' + tab_root_id: system.themes_page + weight: 100 + +system.theme_settings_global: + route_name: system.theme_settings + title: 'Global settings' + tab_root_id: system.themes_page + tab_parent_id: system.theme_settings + description: 'Configure default and theme specific settings.' + weight: -100 + +system.theme_settings_theme: + route_name: system.theme_settings_theme + title: 'Theme name' + tab_root_id: system.themes_page + tab_parent_id: system.theme_settings + derivative: Drupal\system\Plugin\Derivative\ThemeLocalTask + +system.modules_list: + route_name: system.modules_list + tab_root_id: system.modules_list + title: 'List' + +system.modules_uninstall: + route_name: system.modules_uninstall + tab_root_id: system.modules_list + title: 'Uninstall' + weight: 20 + +system.admin: + route_name: system.admin + tab_root_id: system.admin + title: Tasks + weight: -20 +system.admin_index: + route_name: system.admin_index + tab_root_id: system.admin + title: Index + weight: -18 diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 2337ae7..e7aa992 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -620,17 +620,6 @@ function system_menu() { 'weight' => 9, 'menu_name' => 'admin', ); - $items['admin/tasks'] = array( - 'title' => 'Tasks', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'weight' => -20, - ); - $items['admin/index'] = array( - 'title' => 'Index', - 'route_name' => 'system.admin_index', - 'type' => MENU_LOCAL_TASK, - 'weight' => -18, - ); // Menu items that are basically just menu blocks. $items['admin/structure'] = array( @@ -648,34 +637,6 @@ function system_menu() { 'position' => 'left', 'weight' => -6, ); - $items['admin/appearance/list'] = array( - 'title' => 'List', - 'description' => 'Select and configure your theme', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'file' => 'system.admin.inc', - ); - $items['admin/appearance/settings'] = array( - 'title' => 'Settings', - 'description' => 'Configure default and theme specific settings.', - 'route_name' => 'system.theme_settings', - 'type' => MENU_LOCAL_TASK, - 'weight' => 100, - ); - // Theme configuration local tasks. - $items['admin/appearance/settings/global'] = array( - 'title' => 'Global settings', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - - foreach (list_themes(TRUE) as $theme) { - if (!empty($theme->status)) { - $items['admin/appearance/settings/' . $theme->name] = array( - 'title' => $theme->info['name'], - 'route_name' => 'system.theme_settings_' . $theme->name, - 'type' => MENU_LOCAL_TASK, - ); - } - } // Modules. $items['admin/modules'] = array( @@ -684,21 +645,11 @@ function system_menu() { 'route_name' => 'system.modules_list', 'weight' => -2, ); - $items['admin/modules/list'] = array( - 'title' => 'List', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); $items['admin/modules/list/confirm'] = array( 'title' => 'List', 'route_name' => 'system.modules_list_confirm', 'type' => MENU_VISIBLE_IN_BREADCRUMB, ); - $items['admin/modules/uninstall'] = array( - 'title' => 'Uninstall', - 'route_name' => 'system.modules_uninstall', - 'type' => MENU_LOCAL_TASK, - 'weight' => 20, - ); $items['admin/modules/uninstall/confirm'] = array( 'title' => 'Uninstall', 'route_name' => 'system.modules_uninstall_confirm', diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index 508d59c..b03f450 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -324,6 +324,13 @@ system.theme_settings: requirements: _permission: 'administer themes' +system.theme_settings_theme: + path: '/admin/appearance/settings/{theme_name}' + defaults: + _form: '\Drupal\system\Form\ThemeSettingsForm' + requirements: + _permission: 'administer themes' + '': path: '/' requirements: diff --git a/core/modules/system/system.services.yml b/core/modules/system/system.services.yml index ae137da..db343b1 100644 --- a/core/modules/system/system.services.yml +++ b/core/modules/system/system.services.yml @@ -19,7 +19,3 @@ services: class: Drupal\system\PathProcessor\PathProcessorFiles tags: - { name: path_processor_inbound, priority: 200 } - system.route_subscriber: - class: Drupal\system\Routing\RouteSubscriber - tags: - - { name: event_subscriber } diff --git a/core/modules/update/update.local_tasks.yml b/core/modules/update/update.local_tasks.yml new file mode 100644 index 0000000..cf1e3b6 --- /dev/null +++ b/core/modules/update/update.local_tasks.yml @@ -0,0 +1,29 @@ +update.status: + route_name: update.status + tab_root_id: system.admin_reports + title: List + +update.settings: + route_name: update.settings + tab_root_id: system.admin_reports + tab_parent_id: update.status + title: Settings + weight: 50 + +update.report_install: + route_name: update.report_install + tab_root_id: system.admin_reports + title: Update + weight: 10 + +update.module_install: + route_name: update.module_install + tab_root_id: system.modules_list + title: Update + weight: 10 + +update.theme_install: + route_name: update.theme_install + tab_root_id: system.themes_page + title: Update + weight: 10 diff --git a/core/modules/update/update.module b/core/modules/update/update.module index 4258644..317e3e1 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -161,18 +161,6 @@ function update_menu() { 'route_name' => 'update.status', 'weight' => -50, ); - $items['admin/reports/updates/list'] = array( - 'title' => 'List', - 'access arguments' => array('administer site configuration'), - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - $items['admin/reports/updates/settings'] = array( - 'title' => 'Settings', - 'route_name' => 'update.settings', - 'access arguments' => array('administer site configuration'), - 'type' => MENU_LOCAL_TASK, - 'weight' => 50, - ); // We want action links for updating projects at a few different locations: // both the module and theme administration pages, and on the available @@ -191,12 +179,6 @@ function update_menu() { 'weight' => 25, 'type' => MENU_LOCAL_ACTION, ); - $items[$path . '/update'] = array( - 'route_name' => "update.{$context}_update", - 'weight' => 10, - 'title' => 'Update', - 'type' => MENU_LOCAL_TASK, - ); } // Customize the titles of the action links depending on where they appear. // We use += array() to let the translation extractor find these menu titles. diff --git a/core/modules/user/tests/Drupal/user/Tests/Menu/UserLocalTasksTest.php b/core/modules/user/tests/Drupal/user/Tests/Menu/UserLocalTasksTest.php new file mode 100644 index 0000000..4f51de2 --- /dev/null +++ b/core/modules/user/tests/Drupal/user/Tests/Menu/UserLocalTasksTest.php @@ -0,0 +1,101 @@ + 'User local tasks test', + 'description' => 'Test user local tasks.', + 'group' => 'User', + ); + } + + /** + * @{inheritdoc} + */ + public function setUp() { + $this->moduleList = array('user' => 'core/modules/user/user.info'); + parent::setUp(); + } + +// /** +// * Test local task existence. +// * +// * @dataProvider getUserAdminRoutes +// */ +// public function tesstUserAdminLocalTasks() { +// } +// +// public function getUserAdminRoutes() { +// return array( +// array('user.page', 'user.register', 'user.pass'), +// ); +// } +// + /** + * Check user listing local tasks + * + * @dataProvider getUserLoginRoutes + */ + public function testUserLoginLocalTasks($route, $subtask = array()) { + $tasks = array( + 0 => array('user.page', 'user.register', 'user.pass',), + ); + if ($subtask) $tasks[] = $subtask; + $this->assertLocalTasks($route, $tasks); + } + + /** + * Provide a list of routes to test. + */ + public function getUserLoginRoutes() { + return array( + array('user.page', array('user.login',)), + array('user.login', array('user.login',)), + array('user.register'), + array('user.pass'), + ); + } + + /** + * Check user listing local tasks + * + * @dataProvider getUserPageRoutes + */ + public function testUserPageLocalTasks($route, $subtask = array()) { + $tasks = array( + 0 => array('user.view', 'user.edit',), + ); + if ($subtask) $tasks[] = $subtask; + $this->assertLocalTasks($route, $tasks); + } + + /** + * Provide a list of routes to test. + */ + public function getUserPageRoutes() { + return array( + array('user.view'), + array('user.edit'), + ); + } + +} diff --git a/core/modules/user/user.local_tasks.yml b/core/modules/user/user.local_tasks.yml index c82874b..b5d9c36 100644 --- a/core/modules/user/user.local_tasks.yml +++ b/core/modules/user/user.local_tasks.yml @@ -1,4 +1,37 @@ user.role_list_tab: route_name: user.role_list - title: 'Roles' tab_root_id: user.role_list_tab + title: 'Roles' + +user.page: + route_name: user.page + tab_root_id: user.page + title: 'Log in' + weight: -10 + +user.register: + route_name: user.register + tab_root_id: user.page + title: 'Create new account' + +user.pass: + route_name: user.pass + tab_root_id: user.page + title: 'Request new password' + +# Other authentication methods may add pages below user/login/. +user.login: + route_name: user.login + tab_root_id: user.page + tab_parent_id: user.page + title: 'Username and password' + +user.view: + route_name: user.view + tab_root_id: user.view + title: View + +user.edit: + route_name: user.edit + tab_root_id: user.view + title: Edit diff --git a/core/modules/user/user.module b/core/modules/user/user.module index c73155b..6e5ff85 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -738,27 +738,6 @@ function user_menu() { 'menu_name' => 'account', ); - $items['user/login'] = array( - 'title' => 'Log in', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - // Other authentication methods may add pages below user/login/. - $items['user/login/default'] = array( - 'title' => 'Username and password', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); - - $items['user/register'] = array( - 'title' => 'Create new account', - 'type' => MENU_LOCAL_TASK, - 'route_name' => 'user.register', - ); - - $items['user/password'] = array( - 'title' => 'Request new password', - 'route_name' => 'user.pass', - 'type' => MENU_LOCAL_TASK, - ); // Since menu_get_ancestors() does not support multiple placeholders in a row, // this MENU_CALLBACK cannot be removed yet. $items['user/reset/%/%/%'] = array( @@ -844,10 +823,6 @@ function user_menu() { 'title arguments' => array(1), 'route_name' => 'user.view', ); - $items['user/%user/view'] = array( - 'title' => 'View', - 'type' => MENU_DEFAULT_LOCAL_TASK, - ); $items['user/%user/cancel'] = array( 'route_name' => 'user.cancel', ); @@ -855,11 +830,6 @@ function user_menu() { 'title' => 'Confirm account cancellation', 'route_name' => 'user.cancel_confirm', ); - $items['user/%user/edit'] = array( - 'title' => 'Edit', - 'route_name' => 'user.edit', - 'type' => MENU_LOCAL_TASK, - ); return $items; } diff --git a/core/modules/views_ui/views_ui.local_tasks.yml b/core/modules/views_ui/views_ui.local_tasks.yml index 383ef10..83eb11e 100644 --- a/core/modules/views_ui/views_ui.local_tasks.yml +++ b/core/modules/views_ui/views_ui.local_tasks.yml @@ -20,3 +20,8 @@ views_ui_list_tab: route_name: views_ui.list title: List tab_root_id: views_ui_list_tab + +views_ui.reports_fields: + title: 'Used in views' + route_name: views_ui.reports_fields + tab_root_id: field_ui.list diff --git a/core/modules/views_ui/views_ui.module b/core/modules/views_ui/views_ui.module index 0508ff9..d3e4e58 100644 --- a/core/modules/views_ui/views_ui.module +++ b/core/modules/views_ui/views_ui.module @@ -39,19 +39,8 @@ function views_ui_menu() { 'type' => MENU_VISIBLE_IN_BREADCRUMB, ); - // The primary Edit View page. Secondary tabs for each Display are added in - // views_ui_menu_local_tasks_alter(). - $items['admin/structure/views/view/%'] = array( - 'route_name' => 'views_ui.edit', - ); - $items['admin/structure/views/view/%/edit'] = array( - 'title' => 'Edit view', - 'type' => MENU_DEFAULT_LOCAL_TASK, - 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, - ); $items['admin/structure/views/view/%/preview/%'] = array( 'route_name' => 'views_ui.preview', - 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, 'type' => MENU_VISIBLE_IN_BREADCRUMB, ); @@ -73,7 +62,6 @@ function views_ui_menu() { 'title' => 'Used in views', 'description' => 'Overview of fields used in all views.', 'route_name' => 'views_ui.reports_fields', - 'type' => MENU_LOCAL_TASK, ); // A page in the Reports section to show usage of plugins in all views. diff --git a/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php new file mode 100644 index 0000000..0399f4b --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Menu/LocalTaskIntegrationTest.php @@ -0,0 +1,114 @@ +getMockBuilder('Drupal\Core\Menu\LocalTaskManager') + ->disableOriginalConstructor() + ->setMethods(NULL) + ->getMock(); + + $controllerResolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface'); + $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'controllerResolver'); + $property->setAccessible(TRUE); + $property->setValue($manager, $controllerResolver); + + // todo mock a request with a route. + $request = $this->getMock('Symfony\Component\HttpFoundation\Request'); + $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'request'); + $property->setAccessible(TRUE); + $property->setValue($manager, $request); + + $accessManager = $this->getMockBuilder('Drupal\Core\Access\AccessManager') + ->disableOriginalConstructor() + ->getMock(); $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'accessManager'); + $property->setAccessible(TRUE); + $property->setValue($manager, $accessManager); + + $module_handler = new ModuleHandler($modules); + $pluginDiscovery = new YamlDiscovery('local_tasks', $module_handler->getModuleDirectories()); + $pluginDiscovery = new ContainerDerivativeDiscoveryDecorator($pluginDiscovery); + $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'discovery'); + $property->setAccessible(TRUE); + $property->setValue($manager, $pluginDiscovery); + + $plugin_stub = $this->getMock('Drupal\Core\Menu\LocalTaskInterface'); + $factory = $this->getMock('Drupal\Component\Plugin\Factory\FactoryInterface'); + $factory->expects($this->any()) + ->method('createInstance') + ->will($this->returnValue($plugin_stub)); + $property = new \ReflectionProperty('Drupal\Core\Menu\LocalTaskManager', 'factory'); + $property->setAccessible(TRUE); + $property->setValue($manager, $factory); + + $language_manager = $this->getMockBuilder('Drupal\Core\Language\LanguageManager') + ->disableOriginalConstructor() + ->getMock(); + $language_manager->expects($this->any()) + ->method('getLanguage') + ->will($this->returnValue(new Language(array('id' => 'en')))); + + $cache_backend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface'); + $manager->setCacheBackend($cache_backend, $language_manager, 'local_task'); + + return $manager; + } + + /** + * Integration test for local tasks. + * + * @param $route_name + * Route name to base task building on. + * @param $expected_tasks + * A list of tasks groups by level expected at the given route + * @param array $route_params + * (optional) a list of route parameters used to resolve tasks. + */ + protected function assertLocalTasks($route_name, $expected_tasks, $route_params = array()) { + + $manager = $this->getLocalTaskManager($this->moduleList, $route_name, $route_params); + + $tmp_tasks = $manager->getLocalTasksForRoute($route_name); + + // At this point we're just testing existence so pull out keys and then compare. + // + // Deeper testing would require a functioning factory which because we're using + // the DefaultPluginManager base means we get into dependency soup because of + // its factories create method and pulling services off the \Drupal container. + $tasks = array(); + foreach ($tmp_tasks as $level => $level_tasks) { + $tasks[$level] = array_keys($level_tasks); + } + $this->assertEquals($expected_tasks, $tasks); + } +} diff --git a/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php b/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php index 6e9a018..942a3f2 100644 --- a/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php +++ b/core/tests/Drupal/Tests/Core/ParamConverter/ParamConverterManagerTest.php @@ -9,7 +9,10 @@ use Drupal\Core\ParamConverter\ParamConverterManager; use Drupal\Tests\UnitTestCase; +use Symfony\Cmf\Component\Routing\RouteObjectInterface; use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\Routing\Route; /** * Tests the typed data resolver manager. @@ -142,4 +145,45 @@ public function providerTestGetConverter() { ); } + /** + * Tests the enhance method. + * + * @see \Drupal\Core\ParamConverter\ParamConverterManager::enhance(). + */ + public function testEnhance() { + $converter = $this->getMock('Drupal\Core\ParamConverter\ParamConverterInterface'); + $this->manager->addConverter('test_convert'); + + $this->container->set('test_convert', $converter); + + $route = new Route('/test/{id}'); + $parameters = array(); + $parameters['id'] = array( + 'converter' => 'test_convert' + ); + $route->setOption('parameters', $parameters); + + $defaults = array(); + $defaults[RouteObjectInterface::ROUTE_OBJECT] = $route; + $defaults['id'] = 1; + $defaults['_entity'] = &$defaults['id']; + + $request = new Request(); + + $entity = $this->getMockBuilder('\Drupal\user\Entity\User') + ->disableOriginalConstructor() + ->getMock(); + + $converter->expects($this->once()) + ->method('convert') + ->with($this->equalTo(1)) + ->will($this->returnValue($entity)); + + $defaults = $this->manager->enhance($defaults, $request); + + $this->assertSame($entity, $defaults['id']); + $this->assertTrue($defaults['_raw_variables']->has('id')); + $this->assertEquals(1, $defaults['_raw_variables']->get('id')); + } + }