i18n_menu_init

  1. drupal
    1. 7 i18n_menu.module function
Drupal 7 i18n_menu_init()

Implements hook_init().

File

sites/all/modules/i18n/i18n_menu/i18n_menu.module, line 770
Internationalization (i18n) submodule: Menu translation.

Code

function i18n_menu_init() {

  // The only way to override the default preferred menu link for a path is to
  // inject it into the static cache of the function menu_link_get_preferred().

  // The problem with the default implementation is that it does not take the
  // language of a menu link into account. Whe having different menu trees for
  // different menus, this means that the active trail will not work for all but
  // one language.

  // The code below is identical to the mentioned function except the added
  // language condition on the query.

  // TODO: Adding an alter tag to the query would allow to do this with a simple
  // hook_query_alter() implementation.

  $preferred_links = &drupal_static('menu_link_get_preferred');

  $path = $_GET['q'];

  // 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();
  // Use an illegal menu name as the key for the preferred menu link.
  $selected_menu = MENU_PREFERRED_LINK;
  // Put the selected menu at the front of the list.
  array_unshift($menu_names, $selected_menu);

  $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC));
  $query->leftJoin('menu_router', 'm', 'm.path = ml.router_path');
  $query->fields('ml');
  // Weight must be taken from {menu_links}, not {menu_router}.
  $query->addField('ml', 'weight', 'link_weight');
  $query->fields('m');
  $query->condition('ml.menu_name', $menu_names, 'IN');
  $query->condition('ml.link_path', $path_candidates, 'IN');

  // Only look menu links with none or the current language.
  $query->condition('ml.language', array(LANGUAGE_NONE, $GLOBALS['language']->language), 'IN');

  // Sort candidates by link path and menu name.
  $candidates = array();
  foreach ($query->execute() as $candidate) {
    $candidate['weight'] = $candidate['link_weight'];
    $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;
            }
          }
        }
      }
    }
  }
}