function menu_link_get_preferred

Looks up the preferred menu link for a given system path.

Parameters

$path: The path, for example 'node/5'. The function will find the corresponding menu link ('node/5' if it exists, or fallback to 'node/%').

$selected_menu: The name of a menu used to restrict the search for a preferred menu link. If not specified, all the menus returned by menu_get_active_menu_names() will be used.

Return value

A fully translated menu link, or FALSE if no matching menu link was found. The most specific menu link ('node/5' preferred over 'node/%') in the most preferred menu (as defined by menu_get_active_menu_names()) is returned.

Related topics

3 calls to menu_link_get_preferred()
DesignTestController::categoryPage in drupal/core/modules/system/tests/modules/design_test/lib/Drupal/design_test/Controller/DesignTestController.php
Menu for a category listing page.
menu_set_active_trail in drupal/core/includes/menu.inc
Sets the active trail (path to the menu tree root) of the current page.
menu_tree_page_data in drupal/core/includes/menu.inc
Gets the data structure for a named menu tree, based on the current page.
1 string reference to 'menu_link_get_preferred'
menu_reset_static_cache in drupal/core/includes/menu.inc
Resets the menu system static cache.

File

drupal/core/includes/menu.inc, line 2479
API for the Drupal menu system.

Code

function menu_link_get_preferred($path = NULL, $selected_menu = NULL) {
  $preferred_links =& drupal_static(__FUNCTION__);
  if (!isset($path)) {
    $path = current_path();
  }
  if (empty($selected_menu)) {

    // Use an illegal menu name as the key for the preferred menu link.
    $selected_menu = MENU_PREFERRED_LINK;
  }
  if (!isset($preferred_links[$path])) {

    // Look for the correct menu link by building a list of candidate paths,
    // which are ordered by priority (translated hrefs are preferred over
    // untranslated paths). Afterwards, the most relevant path is picked from
    // the menus, ordered by menu preference.
    $item = menu_get_item($path);
    $path_candidates = array();

    // 1. The current item href.
    $path_candidates[$item['href']] = $item['href'];

    // 2. The tab root href of the current item (if any).
    if ($item['tab_parent'] && ($tab_root = menu_get_item($item['tab_root_href']))) {
      $path_candidates[$tab_root['href']] = $tab_root['href'];
    }

    // 3. The current item path (with wildcards).
    $path_candidates[$item['path']] = $item['path'];

    // 4. The tab root path of the current item (if any).
    if (!empty($tab_root)) {
      $path_candidates[$tab_root['path']] = $tab_root['path'];
    }

    // Retrieve a list of menu names, ordered by preference.
    $menu_names = menu_get_active_menu_names();

    // Put the selected menu at the front of the list.
    array_unshift($menu_names, $selected_menu);
    $menu_links = entity_load_multiple_by_properties('menu_link', array(
      'link_path' => $path_candidates,
    ));

    // Sort candidates by link path and menu name.
    $candidates = array();
    foreach ($menu_links as $candidate) {
      $candidates[$candidate['link_path']][$candidate['menu_name']] = $candidate;

      // Add any menus not already in the menu name search list.
      if (!in_array($candidate['menu_name'], $menu_names)) {
        $menu_names[] = $candidate['menu_name'];
      }
    }

    // Store the most specific link for each menu. Also save the most specific
    // link of the most preferred menu in $preferred_link.
    foreach ($path_candidates as $link_path) {
      if (isset($candidates[$link_path])) {
        foreach ($menu_names as $menu_name) {
          if (empty($preferred_links[$path][$menu_name]) && isset($candidates[$link_path][$menu_name])) {
            $candidate_item = $candidates[$link_path][$menu_name];
            $map = explode('/', $path);
            _menu_translate($candidate_item, $map);
            if ($candidate_item['access']) {
              $preferred_links[$path][$menu_name] = $candidate_item;
              if (empty($preferred_links[$path][MENU_PREFERRED_LINK])) {

                // Store the most specific link.
                $preferred_links[$path][MENU_PREFERRED_LINK] = $candidate_item;
              }
            }
          }
        }
      }
    }
  }
  return isset($preferred_links[$path][$selected_menu]) ? $preferred_links[$path][$selected_menu] : FALSE;
}