Commit a96697c7 authored by Dries's avatar Dries

Issue #1864066 by sun, andypost, tim.plunkett: Simplify...

Issue #1864066 by sun, andypost, tim.plunkett: Simplify hook_menu_local_tasks() and MENU_DEFAULT_LOCAL_TASK usage.
parent 0edd4c0b
......@@ -1599,6 +1599,9 @@ function theme_menu_link(array $variables) {
*/
function theme_menu_local_task($variables) {
$link = $variables['element']['#link'];
$link += array(
'localized_options' => array(),
);
$link_text = $link['title'];
if (!empty($variables['element']['#active'])) {
......@@ -1831,21 +1834,20 @@ function menu_navigation_links($menu_name, $level = 0) {
*
* @return
* An array containing
* - tabs: Local tasks for the requested level:
* - count: The number of local tasks.
* - output: The themed output of local tasks.
* - actions: Action links for the requested level:
* - count: The number of action links.
* - output: The themed output of action links.
* - tabs: Local tasks for the requested level.
* - actions: Action links for the requested level.
* - root_path: The router path for the current page. If the current page is
* a default local task, then this corresponds to the parent tab.
*
* @see hook_menu_local_tasks()
* @see hook_menu_local_tasks_alter()
*/
function menu_local_tasks($level = 0) {
$data = &drupal_static(__FUNCTION__);
$root_path = &drupal_static(__FUNCTION__ . ':root_path', '');
$empty = array(
'tabs' => array('count' => 0, 'output' => array()),
'actions' => array('count' => 0, 'output' => array()),
'tabs' => array(),
'actions' => array(),
'root_path' => &$root_path,
);
......@@ -1897,8 +1899,7 @@ function menu_local_tasks($level = 0) {
// Tab parenting may skip levels, so the number of parts in the path may not
// equal the depth. Thus we use the $depth counter (offset by 1000 for ksort).
$depth = 1001;
$actions['count'] = 0;
$actions['output'] = array();
$actions = array();
while (isset($children[$path])) {
$tabs_current = array();
$actions_current = array();
......@@ -1931,10 +1932,11 @@ function menu_local_tasks($level = 0) {
if ($link['href'] != current_path()) {
$link['localized_options']['attributes']['class'][] = 'active';
}
$tabs_current[] = array(
$tabs_current[$link['href']] = array(
'#theme' => 'menu_local_task',
'#link' => $link,
'#active' => TRUE,
'#weight' => isset($link['weight']) ? $link['weight'] : NULL,
);
$next_path = $item['path'];
$tab_count++;
......@@ -1944,17 +1946,19 @@ function menu_local_tasks($level = 0) {
// MENU_IS_LOCAL_ACTION before checking.
if (($item['type'] & MENU_IS_LOCAL_ACTION) == MENU_IS_LOCAL_ACTION) {
// The item is an action, display it as such.
$actions_current[] = array(
$actions_current[$link['href']] = array(
'#theme' => 'menu_local_action',
'#link' => $link,
'#weight' => isset($link['weight']) ? $link['weight'] : NULL,
);
$action_count++;
}
else {
// Otherwise, it's a normal tab.
$tabs_current[] = array(
$tabs_current[$link['href']] = array(
'#theme' => 'menu_local_task',
'#link' => $link,
'#weight' => isset($link['weight']) ? $link['weight'] : NULL,
);
$tab_count++;
}
......@@ -1962,10 +1966,8 @@ function menu_local_tasks($level = 0) {
}
}
$path = $next_path;
$tabs[$depth]['count'] = $tab_count;
$tabs[$depth]['output'] = $tabs_current;
$actions['count'] += $action_count;
$actions['output'] = array_merge($actions['output'], $actions_current);
$tabs[$depth] = $tabs_current;
$actions = array_merge($actions, $actions_current);
$depth++;
}
$data['actions'] = $actions;
......@@ -2007,10 +2009,11 @@ function menu_local_tasks($level = 0) {
if ($link['href'] != current_path()) {
$link['localized_options']['attributes']['class'][] = 'active';
}
$tabs_current[] = array(
$tabs_current[$link['href']] = array(
'#theme' => 'menu_local_task',
'#link' => $link,
'#active' => TRUE,
'#weight' => isset($link['weight']) ? $link['weight'] : NULL,
);
$next_path = $item['tab_parent'];
if (isset($tasks[$next_path])) {
......@@ -2018,17 +2021,17 @@ function menu_local_tasks($level = 0) {
}
}
else {
$tabs_current[] = array(
$tabs_current[$link['href']] = array(
'#theme' => 'menu_local_task',
'#link' => $link,
'#weight' => isset($link['weight']) ? $link['weight'] : NULL,
);
}
}
}
$path = $next_path;
$parent = $next_parent;
$tabs[$depth]['count'] = $count;
$tabs[$depth]['output'] = $tabs_current;
$tabs[$depth] = $tabs_current;
$depth--;
}
// Sort by depth.
......@@ -2037,8 +2040,14 @@ function menu_local_tasks($level = 0) {
$tabs = array_values($tabs);
$data['tabs'] = $tabs;
// Allow modules to alter local tasks or dynamically append further tasks.
drupal_alter('menu_local_tasks', $data, $router_item, $root_path);
// Allow modules to dynamically add further tasks.
$module_handler = drupal_container()->get('module_handler');
foreach ($module_handler->getImplementations('menu_local_tasks') as $module) {
$function = $module . '_menu_local_tasks';
$function($data, $router_item, $root_path);
}
// Allow modules to alter local tasks.
$module_handler->alter('menu_local_tasks', $data, $router_item, $root_path);
}
if (isset($data['tabs'][$level])) {
......@@ -2048,9 +2057,7 @@ function menu_local_tasks($level = 0) {
'root_path' => $root_path,
);
}
// @todo If there are no tabs, then there still can be actions; for example,
// when added via hook_menu_local_tasks_alter().
elseif (!empty($data['actions']['output'])) {
elseif (!empty($data['actions'])) {
return array('actions' => $data['actions']) + $empty;
}
return $empty;
......@@ -2163,7 +2170,7 @@ function menu_contextual_links($module, $parent_path, $args) {
function menu_primary_local_tasks() {
$links = menu_local_tasks(0);
// Do not display single tabs.
return ($links['tabs']['count'] > 1 ? $links['tabs']['output'] : '');
return count(element_get_visible_children($links['tabs'])) > 1 ? $links['tabs'] : '';
}
/**
......@@ -2172,7 +2179,7 @@ function menu_primary_local_tasks() {
function menu_secondary_local_tasks() {
$links = menu_local_tasks(1);
// Do not display single tabs.
return ($links['tabs']['count'] > 1 ? $links['tabs']['output'] : '');
return count(element_get_visible_children($links['tabs'])) > 1 ? $links['tabs'] : '';
}
/**
......@@ -2180,7 +2187,7 @@ function menu_secondary_local_tasks() {
*/
function menu_local_actions() {
$links = menu_local_tasks();
return $links['actions']['output'];
return $links['actions'];
}
/**
......@@ -2195,11 +2202,12 @@ function menu_tab_root_path() {
* Returns a renderable element for the primary and secondary tabs.
*/
function menu_local_tabs() {
return array(
$build = array(
'#theme' => 'menu_local_tasks',
'#primary' => menu_primary_local_tasks(),
'#secondary' => menu_secondary_local_tasks(),
);
return !empty($build['#primary']) || !empty($build['#secondary']) ? $build : array();
}
/**
......@@ -2958,7 +2966,6 @@ function _menu_router_build($callbacks) {
$item['to_arg_functions'] = empty($to_arg_functions) ? '' : serialize($to_arg_functions);
$item += array(
'title' => '',
'weight' => 0,
'type' => MENU_NORMAL_ITEM,
'module' => '',
'_number_parts' => $number_parts,
......@@ -2966,6 +2973,9 @@ function _menu_router_build($callbacks) {
'_fit' => $fit,
);
$item += array(
// Default MENU_DEFAULT_LOCAL_TASKs to a weight of -10, so they appear as
// first tab by default.
'weight' => ($item['type'] & MENU_DEFAULT_LOCAL_TASK) == MENU_DEFAULT_LOCAL_TASK ? -10 : 0,
'_visible' => (bool) ($item['type'] & MENU_VISIBLE_IN_BREADCRUMB),
'_tab' => (bool) ($item['type'] & MENU_IS_LOCAL_TASK),
);
......
......@@ -69,7 +69,6 @@ function action_menu() {
'description' => 'Manage the actions defined for your site.',
'page callback' => 'action_admin_manage',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -2,
'file' => 'action.admin.inc',
);
$items['admin/config/system/actions/configure'] = array(
......
......@@ -141,7 +141,6 @@ function aggregator_menu() {
$items['admin/config/services/aggregator/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/config/services/aggregator/settings'] = array(
'title' => 'Settings',
......@@ -150,6 +149,7 @@ function aggregator_menu() {
'page arguments' => array('aggregator_admin_form'),
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
'weight' => 100,
'file' => 'aggregator.admin.inc',
);
$items['aggregator'] = array(
......@@ -196,7 +196,6 @@ function aggregator_menu() {
$items['aggregator/categories/%aggregator_category/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['aggregator/categories/%aggregator_category/categorize'] = array(
'title' => 'Categorize',
......@@ -212,7 +211,7 @@ function aggregator_menu() {
'page arguments' => array('aggregator_form_category', 2),
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'weight' => 10,
'file' => 'aggregator.admin.inc',
);
$items['aggregator/sources/%aggregator_feed'] = array(
......@@ -226,7 +225,6 @@ function aggregator_menu() {
$items['aggregator/sources/%aggregator_feed/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['aggregator/sources/%aggregator_feed/categorize'] = array(
'title' => 'Categorize',
......@@ -242,7 +240,7 @@ function aggregator_menu() {
'page arguments' => array(2),
'access arguments' => array('administer news feeds'),
'type' => MENU_LOCAL_TASK,
'weight' => 1,
'weight' => 10,
'file' => 'aggregator.admin.inc',
);
$items['admin/config/services/aggregator/edit/feed/%aggregator_feed'] = array(
......
......@@ -160,7 +160,6 @@ function block_menu() {
'title' => check_plain($theme->info['name']),
'page arguments' => array($key),
'type' => $key == $default_theme ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
'weight' => $key == $default_theme ? -10 : 0,
'access callback' => '_block_themes_access',
'access arguments' => array($key),
'file' => 'block.admin.inc',
......
......@@ -149,7 +149,7 @@ function book_menu() {
'page arguments' => array('book_admin_settings'),
'access arguments' => array('administer site configuration'),
'type' => MENU_LOCAL_TASK,
'weight' => 8,
'weight' => 100,
'file' => 'book.admin.inc',
);
$items['admin/content/book/%node'] = array(
......
......@@ -233,7 +233,6 @@ function comment_menu() {
$items['admin/content/comment/new'] = array(
'title' => 'Published comments',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/content/comment/approval'] = array(
'title' => 'Unapproved comments',
......@@ -251,7 +250,6 @@ function comment_menu() {
$items['comment/%/view'] = array(
'title' => 'View comment',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
// 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).
......@@ -262,7 +260,6 @@ function comment_menu() {
'access callback' => 'comment_access',
'access arguments' => array('edit', 1),
'type' => MENU_LOCAL_TASK,
'weight' => 0,
);
$items['comment/%/approve'] = array(
'title' => 'Approve',
......@@ -270,7 +267,7 @@ function comment_menu() {
'page arguments' => array(1),
'access arguments' => array('administer comments'),
'file' => 'comment.pages.inc',
'weight' => 1,
'weight' => 10,
);
$items['comment/%/delete'] = array(
'title' => 'Delete',
......@@ -279,7 +276,7 @@ function comment_menu() {
'access arguments' => array('administer comments'),
'type' => MENU_LOCAL_TASK,
'file' => 'comment.admin.inc',
'weight' => 2,
'weight' => 20,
);
$items['comment/reply/%node'] = array(
'title' => 'Add new comment',
......
......@@ -51,7 +51,6 @@ function config_menu() {
$items['admin/config/development/sync/import'] = array(
'title' => 'Import',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
return $items;
}
......
......@@ -46,7 +46,6 @@ function config_test_menu() {
$items['admin/structure/config_test/manage/%config_test/edit'] = array(
'title' => 'Edit',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/config_test/manage/%config_test/delete'] = array(
'title' => 'Delete',
......
......@@ -84,7 +84,6 @@ function contact_menu() {
$items['admin/structure/contact/manage/%contact_category/edit'] = array(
'title' => 'Edit',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/contact/manage/%contact_category/delete'] = array(
'title' => 'Delete',
......
......@@ -68,9 +68,8 @@ function field_ui_menu() {
'file' => 'field_ui.admin.inc',
);
$items['admin/reports/fields/list'] = array(
'title' => 'List',
'title' => 'Entities',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
// Create tabs for all possible bundles.
......@@ -190,9 +189,11 @@ function field_ui_menu() {
'access callback' => '_field_ui_view_mode_menu_access',
'access arguments' => array($entity_type, $bundle_arg, $view_mode, $access_display['access arguments'][0]),
'type' => ($view_mode == 'default' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK),
'weight' => ($view_mode == 'default' ? -10 : $weight++),
'file' => 'field_ui.admin.inc',
);
if ($view_mode != 'default') {
$items["$path/display/$view_mode"]['weight'] = $weight++;
}
}
}
}
......
......@@ -148,7 +148,6 @@ function filter_menu() {
'page callback' => 'filter_admin_format_page',
'access arguments' => array('administer filters'),
'type' => MENU_LOCAL_ACTION,
'weight' => 1,
'file' => 'filter.admin.inc',
);
$items['admin/config/content/formats/%filter_format'] = array(
......
......@@ -118,7 +118,6 @@ function forum_menu() {
$items['admin/structure/forum/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/forum/add/container'] = array(
'title' => 'Add container',
......@@ -143,7 +142,7 @@ function forum_menu() {
'page callback' => 'drupal_get_form',
'page arguments' => array('forum_admin_settings'),
'access arguments' => array('administer forums'),
'weight' => 5,
'weight' => 100,
'type' => MENU_LOCAL_TASK,
'parent' => 'admin/structure/forum',
'file' => 'forum.admin.inc',
......@@ -166,9 +165,9 @@ function forum_menu() {
}
/**
* Implements hook_menu_local_tasks_alter().
* Implements hook_menu_local_tasks().
*/
function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
function forum_menu_local_tasks(&$data, $router_item, $root_path) {
global $user;
// Add action link to 'node/add/forum' on 'forum' sub-pages.
......@@ -213,7 +212,7 @@ function forum_menu_local_tasks_alter(&$data, $router_item, $root_path) {
);
}
}
$data['actions']['output'] = array_merge($data['actions']['output'], $links);
$data['actions'] += $links;
}
}
}
......
......@@ -121,7 +121,6 @@ function image_menu() {
'page callback' => 'image_style_list',
'access arguments' => array('administer image styles'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 1,
'file' => 'image.admin.inc',
);
$items['admin/config/media/image-styles/add'] = array(
......
......@@ -75,7 +75,6 @@ function language_menu() {
);
$items['admin/config/regional/language/list'] = array(
'title' => 'List',
'weight' => 0,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/regional/language/add'] = array(
......@@ -83,7 +82,6 @@ function language_menu() {
'page callback' => 'drupal_get_form',
'page arguments' => array('language_admin_add_form'),
'access arguments' => array('administer languages'),
'weight' => 5,
'type' => MENU_LOCAL_ACTION,
'file' => 'language.admin.inc',
);
......
......@@ -193,7 +193,6 @@ function locale_menu() {
);
$items['admin/config/regional/translate/translate'] = array(
'title' => 'Translate',
'weight' => -10,
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/regional/translate/import'] = array(
......@@ -219,7 +218,7 @@ function locale_menu() {
'page callback' => 'drupal_get_form',
'page arguments' => array('locale_translate_settings'),
'access arguments' => array('translate interface'),
'weight' => 40,
'weight' => 100,
'type' => MENU_LOCAL_TASK,
'file' => 'locale.pages.inc',
);
......
......@@ -82,7 +82,6 @@ function menu_menu() {
$items['admin/structure/menu/list'] = array(
'title' => 'List menus',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/menu/add'] = array(
'title' => 'Add menu',
......@@ -97,7 +96,7 @@ function menu_menu() {
'page arguments' => array('menu_configure'),
'access arguments' => array('administer menu'),
'type' => MENU_LOCAL_TASK,
'weight' => 5,
'weight' => 100,
'file' => 'menu.admin.inc',
);
$items['admin/structure/menu/manage/%menu'] = array(
......
......@@ -1658,7 +1658,6 @@ function node_menu() {
$items['admin/content/node'] = array(
'title' => 'Content',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/reports/status/rebuild'] = array(
......@@ -1682,7 +1681,6 @@ function node_menu() {
$items['admin/structure/types/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/structure/types/add'] = array(
'title' => 'Add content type',
......@@ -1757,7 +1755,6 @@ function node_menu() {
$items['node/%node/view'] = array(
'title' => 'View',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['node/%node/edit'] = array(
'title' => 'Edit',
......@@ -1765,7 +1762,6 @@ function node_menu() {
'page arguments' => array(1),
'access callback' => 'node_access',
'access arguments' => array('update', 1),
'weight' => 0,
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE,
'file' => 'node.pages.inc',
......@@ -1776,7 +1772,7 @@ function node_menu() {
'page arguments' => array('node_delete_confirm', 1),
'access callback' => 'node_access',
'access arguments' => array('delete', 1),
'weight' => 1,
'weight' => 10,
'type' => MENU_LOCAL_TASK,
'context' => MENU_CONTEXT_INLINE,
'file' => 'node.pages.inc',
......@@ -1787,7 +1783,7 @@ function node_menu() {
'page arguments' => array(1),
'access callback' => '_node_revision_access',
'access arguments' => array(1),
'weight' => 2,
'weight' => 20,
'type' => MENU_LOCAL_TASK,
'file' => 'node.pages.inc',
);
......@@ -1818,14 +1814,14 @@ function node_menu() {
}
/**
* Implements hook_menu_local_tasks_alter().
* Implements hook_menu_local_tasks().
*/
function node_menu_local_tasks_alter(&$data, $router_item, $root_path) {
function node_menu_local_tasks(&$data, $router_item, $root_path) {
// Add action link to 'node/add' on 'admin/content' page.
if ($root_path == 'admin/content') {
$item = menu_get_item('node/add');
if ($item['access']) {
$data['actions']['output'][] = array(
$data['actions'][] = array(
'#theme' => 'menu_local_action',
'#link' => $item,
);
......
......@@ -64,6 +64,10 @@ function path_menu() {
'weight' => -5,
'file' => 'path.admin.inc',
);
$items['admin/config/search/path/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/config/search/path/edit/%path'] = array(
'title' => 'Edit alias',
'page callback' => 'path_admin_edit',
......@@ -78,11 +82,6 @@ function path_menu() {
'access arguments' => array('administer url aliases'),
'file' => 'path.admin.inc',
);
$items['admin/config/search/path/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['admin/config/search/path/add'] = array(
'title' => 'Add alias',
'page callback' => 'path_admin_edit',
......
......@@ -50,6 +50,7 @@ function simpletest_menu() {
'page arguments' => array('simpletest_settings_form'),
'access arguments' => array('administer unit tests'),
'type' => MENU_LOCAL_TASK,
'weight' => 100,
'file' => 'simpletest.pages.inc',
);
$items['admin/config/development/testing/results/%'] = array(
......
<?php
/**
* @file
* Contains Drupal\system\Tests\Menu\LocalTasksTest.
*/
namespace Drupal\system\Tests\Menu;
use Drupal\simpletest\WebTestBase;
/**
* Tests local tasks derived from router and added/altered via hooks.
*/
class LocalTasksTest extends WebTestBase {
public static $modules = array('menu_test');
public static function getInfo() {
return array(
'name' => 'Local tasks',
'description' => 'Tests local tasks derived from router and added/altered via hooks.',
'group' => 'Menu',
);
}
/**
* Tests appearance of local tasks.
*
* @see menu_test_menu()
* @see menu_test_menu_local_tasks()
* @see menu_test_menu_local_tasks_alter()
*/
function testLocalTasks() {
// Verify that there is no local tasks markup if none are defined in the
// router and no module adds any dynamically.
$this->drupalGet('menu-test/tasks/empty');
$this->assertNoRaw('tabs');
$this->drupalGet('menu-test/tasks/default');
$this->assertNoRaw('tabs');
// Verify that local tasks appear as defined in the router.
$this->drupalGet('menu-test/tasks/tasks');
$this->assertLocalTasks(array(
// MENU_DEFAULT_LOCAL_TASK is expected to get a default weight of -10
// (without having to define it manually), so it should appear first,
// despite that its label is "View".
'menu-test/tasks/tasks',
'menu-test/tasks/tasks/edit',
'menu-test/tasks/tasks/settings',
));
// Enable addition of tasks in menu_test_menu_local_tasks().
config('menu_test.settings')->set('tasks.add', TRUE)->save();
// Verify that the added tasks appear even if there are no tasks normally.
$this->drupalGet('menu-test/tasks/empty');
$this->assertLocalTasks(array(
'task/foo',
'task/bar',
));
// Verify that the default local task appears before the added tasks.
$this->drupalGet('menu-test/tasks/default');
$this->assertLocalTasks(array(
'menu-test/tasks/default',
'task/foo',
'task/bar',
));
// Verify that the added tasks appear within normal tasks.
$this->drupalGet('menu-test/tasks/tasks');
$this->assertLocalTasks(array(
'menu-test/tasks/tasks',
// The Edit task defines no weight, which is expected to sort as 0.
'menu-test/tasks/tasks/edit',
'task/foo',
'task/bar',
'menu-test/tasks/tasks/settings',
));
// Enable manipulation of tasks in menu_test_menu_local_tasks_alter().
config('menu_test.settings')->set('tasks.alter', TRUE)->save();
// Verify that the added tasks appear even if there are no tasks normally.
$this->drupalGet('menu-test/tasks/empty');
$this->assertLocalTasks(array(
'task/bar',
'task/foo',
));
$this->assertNoText('Show it');
$this->assertText('Advanced settings');
// Verify that the default local task appears before the added tasks.
$this->drupalGet('menu-test/tasks/default');
$this->assertLocalTasks(array(
'menu-test/tasks/default',
'task/bar',
'task/foo',
));
$this->assertText('Show it');
$this->assertText('Advanced settings');
// Verify that the added tasks appear within normal tasks.
$this->drupalGet('menu-test/tasks/tasks');
$this->assertLocalTasks(array(
'menu-test/tasks/tasks',
'menu-test/tasks/tasks/edit',
'task/bar',
'menu-test/tasks/tasks/settings',
'task/foo',
));
$this->assertText('Show it');
$this->assertText('Advanced settings');
}
/**
* Asserts local tasks in the page output.
*
* @param array $hrefs
* A list of expected link hrefs of local tasks to assert on the page (in
* the given order).
* @param int $level
* (optional) The local tasks level to assert; 0 for primary, 1 for
* secondary. Defaults to 0.
*/
protected function assertLocalTasks(array $hrefs, $level = 0) {
$elements = $this->xpath('//*[contains(@class, :class)]//a', array(
':class' => $level == 0 ? 'tabs primary' : 'tabs secondary',
));
$this->assertTrue(count($elements), 'Local tasks found.');
foreach ($hrefs as $index => $element) {
$expected = url($hrefs[$index]);
$method = ($elements[$index]['href'] == $expected ? 'pass' : 'fail');
$this->{$method}(format_string('Task @number href @value equals @expected.', array(
'@number' => $index + 1,
'@value' => (string) $elements[$index]['href'],
'@expected' => $expected,
)));