m7v
3/20/2015 - 4:34 AM

Build breadcrumb by path. It can be used in theme_breadcrumb.

Build breadcrumb by path. It can be used in theme_breadcrumb.

<?php

/*
 * Get trail by path.
 * @param $path
 *  The path of page to get trail.
 */
function _my_module_get_trail_by_path($path = NULL, $parent_levels = NULL) {
  $trail = &drupal_static(__FUNCTION__);

  if (!isset($trail)) {
    $trail[] = array(
      'title' => t('Home'),
      'href' => '<front>',
      'link_path' => '',
      'localized_options' => array(),
      'type' => 0,
    );
  }
  if (isset($path)) {
    $trail = array();

    $trail[] = array(
      'title' => t('Home'),
      'href' => '<front>',
      'link_path' => '',
      'localized_options' => array(),
      'type' => 0,
    );

    // Try to retrieve a menu link corresponding to the current path. If more
    // than one exists, the link from the most preferred menu is returned.
    $preferred_link = menu_link_get_preferred($path, MY_PROJECT_SITE_MAIN_MENU);
    $parent_item = _menu_link_find_parent($preferred_link);
    $parent_link = !empty($parent_item['mlid']) ? menu_link_load($parent_item['mlid']) : '';

    $parent_trail = array();
    $level = 1;
    while ($parent_link) {
      if ($parent_link && $parent_link['href'] != variable_get('site_frontpage', 'node')) {
        if (!empty($parent_levels) && $level >= $parent_levels) {
          break;
        }
        array_unshift($parent_trail, $parent_link);
        $parent_item = _menu_link_find_parent($parent_link);
        $parent_link = !empty($parent_item['mlid']) ? menu_link_load($parent_item['mlid']) : '';
        $level++;
      }
      else {
        break;
      }
    }
    $trail = array_merge($trail, $parent_trail);

    if ($preferred_link && !drupal_is_front_page()) {
      $trail[] = $preferred_link;
    }
  }
  else {
    // Try to retrieve a menu link corresponding to the current path. If more
    // than one exists, the link from the most preferred menu is returned.
    $preferred_link = menu_link_get_preferred(NULL, MY_PROJECT_SITE_MAIN_MENU);
    $current_item = menu_get_item();
    if ($preferred_link) {
      // Pass TRUE for $only_active_trail to make menu_tree_page_data() build
      // a stripped down menu tree containing the active trail only, in case
      // the given menu has not been built in this request yet.
      $tree = menu_tree_page_data($preferred_link['menu_name'], NULL, TRUE);
      list($key, $curr) = each($tree);
    }
    // There is no link for the current path.
    else {
      $preferred_link = $current_item;
      $curr = FALSE;
    }
    while ($curr) {
      $link = $curr['link'];
      if ($link['in_active_trail']) {
        // Add the link to the trail, unless it links to its parent.
        if (!($link['type'] & MENU_LINKS_TO_PARENT)) {
          // The menu tree for the active trail may contain additional links
          // that have not been translated yet, since they contain dynamic
          // argument placeholders (%). Such links are not contained in regular
          // menu trees, and have only been loaded for the additional
          // translation that happens here, so as to be able to display them in
          // the breadcumb for the current page.
          // @see _menu_tree_check_access()
          // @see _menu_link_translate()
          if (strpos($link['href'], '%') !== FALSE) {
            _menu_link_translate($link, TRUE);
          }
          if ($link['access']) {
            $trail[] = $link;
          }
        }
        $tree = $curr['below'] ? $curr['below'] : array();
      }
      list($key, $curr) = each($tree);
    }
    // Make sure the current page is in the trail to build the page title, by
    // appending either the preferred link or the menu router item for the
    // current page. Exclude it if we are on the front page.
    $last = end($trail);
    if ($preferred_link && $last['href'] != $preferred_link['href'] && !drupal_is_front_page()) {
      $trail[] = $preferred_link;
    }
  }

  return $trail;
}