diff --git includes/menu.inc includes/menu.inc index 642e946..3d8e872 100644 --- includes/menu.inc +++ includes/menu.inc @@ -1095,6 +1095,38 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) { } /** + * Set the path for determining the active trail of the specified menu tree. + * + * @param $menu_name + * The name of the affected menu tree. + * @param $path + * The path to use when finding the active trail. + */ +function menu_tree_set_path($menu_name, $path) { + return menu_tree_get_path($menu_name, $path); +} + +/** + * Get the path for determining the active trail of the specified menu tree. + * + * @param $menu_name + * The menu name of the requested tree. + * @param $path + * Internal use only. + * + * @return + * A string containing the path. If no path has been specified with + * menu_tree_set_path(), NULL is returned. + */ +function menu_tree_get_path($menu_name, $path = NULL) { + $paths = &drupal_static(__FUNCTION__); + if (isset($path)) { + $paths[$menu_name] = $path; + } + return isset($paths[$menu_name]) ? $paths[$menu_name] : NULL; +} + +/** * Get the data structure representing a named menu tree, based on the current page. * * The tree order is maintained by storing each parent in an individual @@ -1119,8 +1151,10 @@ function menu_tree_all_data($menu_name, $link = NULL, $max_depth = NULL) { function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail = FALSE) { $tree = &drupal_static(__FUNCTION__, array()); + // Check if the active trail has been overridden for this menu tree. + $active_path = menu_tree_get_path($menu_name); // Load the menu item corresponding to the current page. - if ($item = menu_get_item()) { + if ($item = menu_get_item($active_path)) { if (isset($max_depth)) { $max_depth = min($max_depth, MENU_MAX_DEPTH); } @@ -1159,8 +1193,9 @@ function menu_tree_page_data($menu_name, $max_depth = NULL, $only_active_trail = // If the item for the current page is accessible, build the tree // parameters accordingly. if ($item['access']) { - // Find a menu link corresponding to the current path. - if ($active_link = menu_link_get_preferred()) { + // Find a menu link corresponding to the current path. If $active_path + // is NULL, let menu_link_get_preferred() determine the path. + if ($active_link = menu_link_get_preferred($active_path)) { // The active link may only be taken into account to build the // active trail, if it resides in the requested menu. Otherwise, // we'd needlessly re-run _menu_build_tree() queries for every menu diff --git modules/simpletest/tests/menu.test modules/simpletest/tests/menu.test index 0c002e2..f2e1148 100644 --- modules/simpletest/tests/menu.test +++ modules/simpletest/tests/menu.test @@ -560,6 +560,42 @@ class MenuTreeDataTestCase extends DrupalUnitTestCase { } /** + * Menu tree display related tests. + */ +class MenuTreeTestCase extends DrupalWebTestCase { + public static function getInfo() { + return array( + 'name' => 'Menu tree display', + 'description' => 'Tests menu tree display functions.', + 'group' => 'Menu', + ); + } + + /** + * Test that menu_tree_set_path() affects menu tree generation. + */ + function testMenuTreeSetPath() { + $path = 'admin/config/system/site-information'; + $menu_name = 'management'; + + // Verify the test path is not originally in the menu tree. + $tree = drupal_render(menu_tree($menu_name)); + $this->assert(strpos($tree, $path) === FALSE, t('Test link does not exist in menu tree.')); + + // Set the active path of the menu tree to the test path. + drupal_flush_all_caches(); + menu_tree_set_path($menu_name, $path); + + // Check if the test path is returned by menu_tree_get_path(). + $this->assertIdentical($path, menu_tree_get_path($menu_name), t('Test link set by menu_tree_set_path().')); + + // Check if the test path is in the menu tree. + $tree = drupal_render(menu_tree($menu_name)); + $this->assert(strpos($tree, $path) !== FALSE, t('Test link exists in menu tree.')); + } +} + +/** * Menu breadcrumbs related tests. */ class MenuBreadcrumbTestCase extends DrupalWebTestCase {