You are here

breadcrumb_manager.module in Breadcrumb Manager 7

Same filename and directory in other branches
  1. 8 breadcrumb_manager.module

Code for Breadcrumb Manager module.

File

breadcrumb_manager.module
View source
<?php

/**
 * @file
 * Code for Breadcrumb Manager module.
 */

/**
 * Implements hook_permission().
 */
function breadcrumb_manager_permission() {
  return array(
    'administer breadcrumb_manager' => array(
      'title' => t('Administer Breadcrumb Manager'),
    ),
  );
}

/**
 * Implements hook_menu().
 */
function breadcrumb_manager_menu() {
  $items = array();
  $items['admin/structure/breadcrumb_manager'] = array(
    'title' => 'Breadcrumb Manager',
    'description' => 'Breadcrumb Manager module configuration',
    'page callback' => 'drupal_get_form',
    'access arguments' => array(
      'administer breadcrumb_manager',
    ),
    'page arguments' => array(
      'breadcrumb_manager_settings_form',
    ),
    'type' => MENU_NORMAL_ITEM,
    'file' => 'breadcrumb_manager.admin.inc',
    'file path' => drupal_get_path('module', 'breadcrumb_manager') . '/includes',
  );
  return $items;
}

/**
 * Implements hook_page_delivery_callback_alter().
 */
function breadcrumb_manager_page_delivery_callback_alter() {
  breadcrumb_manager_set_breadcrumb();
}

/**
 * Magic function: Evaluates correct breadcrumb from the given path.
 *
 * @param string $current_path
 *   The path to be checked.
 * @param bool $set_breadcrumb
 *   TRUE by default. If set to FALSE, the generated breadcrumb will not be set.
 *
 * @return bool|array
 *   The generated breadcrumb array or FALSE if given path is an excluded one.
 */
function breadcrumb_manager_set_breadcrumb($current_path = NULL, $set_breadcrumb = TRUE) {
  if (breadcrumb_manager_is_excluded_path($current_path)) {
    return FALSE;
  }
  if (empty($current_path)) {
    $current_path = drupal_get_path_alias(current_path());
  }
  $front = variable_get('site_frontpage', 'node');
  $show_home = variable_get('breadcrumb_manager_show_home', TRUE);
  $show_current = variable_get('breadcrumb_manager_show_current', TRUE);
  $show_current_as_link = variable_get('breadcrumb_manager_show_current_as_link', TRUE);
  $set_active_trail = variable_get('breadcrumb_manager_set_active_trail', FALSE);
  $breadcrumb = array();
  if ($show_home) {
    $home = variable_get('breadcrumb_manager_home', 'Home');
    $home = trim(check_plain($home));
    if (empty($home)) {
      $home = 'Home';
    }
    $breadcrumb[] = l(t($home), '<front>');
  }
  $segments = explode('/', $current_path);
  $total = count($segments);
  $path = '';
  $preferred_item = NULL;
  $last_title = NULL;
  foreach ($segments as $i => $segment) {
    $path = empty($path) ? $segment : implode('/', array(
      $path,
      $segment,
    ));
    $source = drupal_lookup_path('source', $path);
    $current = $i + 1;
    $is_last = $total == $current;
    if (!$is_last || $show_current) {
      $title = breadcrumb_manager_get_title($path);
      $last_title = $title;
      if (empty($title)) {
        $title = drupal_get_title();
        if (empty($title) || $title == $home && current_path() != $front) {
          $title = ucfirst(str_replace('-', ' ', $segment));
          $title = str_replace('_', ' ', $title);
        }
        $last_title = $title;
        $breadcrumb[$current] = l($title, current_path(), _breadcrumb_manager_get_options($total, $i));
        break;
      }
      else {
        $breadcrumb[$current] = l(t('!title', array(
          '!title' => $title,
        )), $path, _breadcrumb_manager_get_options($total, $i));
      }
    }

    // Get active trail.
    if ($set_active_trail) {
      $link_path = $source ? $source : $path;
      $preferred = menu_link_get_preferred($link_path, 'main-menu');
      if (!empty($preferred) && $preferred['menu_name'] == 'main-menu') {
        $preferred_item = $preferred;
      }
    }
  }
  if ($show_current && !$show_current_as_link) {
    $breadcrumb[$total] = $last_title;
  }

  // Set active trail.
  if ($set_active_trail && !empty($preferred_item)) {
    menu_tree_set_path('main-menu', $preferred_item['href']);
  }

  // Allow other modules to alter the generated breadcrumb.
  drupal_alter('breadcrumb', $breadcrumb, $current_path);

  // Set breadcrumb.
  if ($set_breadcrumb) {
    drupal_set_breadcrumb($breadcrumb);
  }
  return $breadcrumb;
}

/**
 * Helper function: retrieve link options
 *
 * @param int $total
 *   The total number of breadcrumb segments.
 * @param int $current
 *   The current segment index.
 *
 * @return array
 *   An array of options needed to set the active class.
 */
function _breadcrumb_manager_get_options($total, $current) {
  $options = array(
    'html' => TRUE,
  );
  if ($total == $current + 1) {
    $options['attributes']['class'][] = 'active';
  }
  return $options;
}

/**
 * Helper function: retrieve correct title by path.
 *
 * @param string $path
 *   The path to be checked.
 *
 * @return string
 *   The page title.
 */
function breadcrumb_manager_get_title($path) {
  $titles =& drupal_static(__FUNCTION__);
  if (!isset($titles[$path])) {
    $title = '';
    $source = db_select('url_alias', 'ua')
      ->fields('ua', array(
      'source',
      'language',
    ))
      ->condition('ua.alias', $path)
      ->execute()
      ->fetchObject();
    if (!empty($source)) {
      $source_arr = explode('/', $source->source);
      switch ($source_arr[0]) {
        case 'node':
          $node = node_load($source_arr[1]);
          $title = $node->title;
          break;
        case 'taxonomy':
          $term = taxonomy_term_load($source_arr[2]);
          $title = $term->name;
          break;
      }
      if (empty($title)) {
        $title = '';
        $source_path = drupal_lookup_path('source', $source->source);
        if (empty($source_path)) {
          $language = module_exists('i18n_menu') ? $source->language : NULL;
          $title = _breadcrumb_manager_get_title_by_menu_link($source->source, $language);
        }
      }
      $titles[$path] = $title;
    }
    else {

      // First of all: try to get title by language if i18n_menu exists.
      $language = module_exists('i18n_menu') ? $GLOBALS['language']->language : NULL;
      $title = _breadcrumb_manager_get_title_by_menu_link($path, $language);

      // In case of failure try to get title without language.
      if (empty($title)) {
        $title = _breadcrumb_manager_get_title_by_menu_link($path);
      }

      // Finally try to extract title from menu router.
      if (empty($title)) {
        $title = _breadcrumb_manager_get_title_by_menu_router($path);
      }
      $titles[$path] = t($title);
    }
  }
  return $titles[$path];
}

/**
 * Helper function: try to find a valid title from the menu_links table.
 *
 * @param string $path
 *   The path to be checked.
 * @param string $language
 *   The language code.
 *
 * @return string
 *   The menu link title.
 */
function _breadcrumb_manager_get_title_by_menu_link($path, $language = NULL) {
  $query = db_select('menu_links', 'ml');
  $query
    ->fields('ml', array(
    'link_title',
  ))
    ->condition('ml.link_path', $path);
  if (!empty($language)) {
    $query
      ->condition('ml.language', $language);
  }
  return $query
    ->execute()
    ->fetchField();
}

/**
 * Helper function: try to find a valid title from the menu_router table.
 *
 * @param string $path
 *   The path to be checked.
 *
 * @return string
 *   The menu router title.
 */
function _breadcrumb_manager_get_title_by_menu_router($path) {
  $title = '';
  $item = db_select('menu_router', 'mr')
    ->fields('mr')
    ->condition('mr.path', $path)
    ->execute()
    ->fetchObject();
  if (!empty($item->title)) {
    $title = $item->title;
  }
  else {

    // Try to get a valid title from a view display even if it doesn't set a
    // menu item.
    if (!empty($item->page_callback) && $item->page_callback == 'views_page') {
      list($view_name, $display) = unserialize($item->page_arguments);
      $view = views_get_view($view_name);
      if (is_array($display)) {
        $display = reset($display);
      }
      if (!empty($view) && !empty($view->display[$display])) {
        $display_title = '';
        if (count($view->display) == 2 && isset($view->display['default']) && empty($view->display[$display]->display_options['title'])) {
          $display_title = !empty($view->display['default']->display_options['title']) ? $view->display['default']->display_options['title'] : '';
        }
        if (!empty($view->display[$display]->display_options['title'])) {
          $display_title = $view->display[$display]->display_options['title'];
        }
        $title = !empty($display_title) ? $display_title : $view->display[$display]->display_title;
      }
    }
  }
  return $title;
}

/**
 * Check if the breadcrumb for the current path can be overwritten.
 *
 * @param string $current_path
 *   The path to be checked.
 *
 * @return bool
 *   Whether or not the given path is an excluded one.
 */
function breadcrumb_manager_is_excluded_path($current_path = NULL) {
  if (empty($current_path)) {
    $current_path = current_path();
  }

  // Avoid breadcrumb on front page.
  $show_on_front = variable_get('breadcrumb_manager_show_front', FALSE);
  if (breadcrumb_manager_is_front_page($current_path) && !$show_on_front) {
    return TRUE;
  }
  module_load_include('inc', 'pathauto', 'pathauto');
  $paths = explode("\n", trim(variable_get('breadcrumb_manager_excluded_paths', "node\nsearch/*")));
  $current_alias = drupal_get_path_alias($current_path);
  foreach ($paths as $path) {
    $path = _pathauto_clean_separators($path, '/');
    $path = str_replace('/', '\\/', preg_quote(trim($path)));
    $path = str_replace('\\*', '.*?', $path);
    if (preg_match("/^" . $path . "\$/", $current_path) || preg_match("/^" . $path . "\$/", $current_alias)) {
      return TRUE;
    }
  }
  return FALSE;
}

/**
 * Check if the page is the front page.
 *
 * @param string $path
 *   The path to be checked.
 *
 * @return bool
 *   TRUE if the current page is the front page; FALSE if otherwise.
 */
function breadcrumb_manager_is_front_page($path) {

  // Use the advanced drupal_static() pattern, since this is called very often.
  static $drupal_static_fast;
  if (!isset($drupal_static_fast)) {
    $drupal_static_fast['path_is_front_page'] =& drupal_static(__FUNCTION__);
  }
  $is_front_page =& $drupal_static_fast['path_is_front_page'];
  if (!isset($is_front_page)) {
    $is_front_page = $path == variable_get('site_frontpage', 'node');
  }
  return $is_front_page;
}

/**
 * Check if the current page title is missing or in blacklist.
 *
 * @return bool|string
 *   Returns the page title if it's required. Otherwise returns FALSE.
 */
function breadcrumb_manager_is_title_required() {
  $title = trim(drupal_get_title());
  $title_in_blacklist = FALSE;
  if (!empty($title)) {
    $titles_blacklist = explode("\n", trim(variable_get('breadcrumb_manager_titles_blacklist', '')));
    foreach ($titles_blacklist as $blacklist_title) {
      if ($title == trim($blacklist_title)) {
        $title_in_blacklist = TRUE;
        break;
      }
    }
  }
  if ((empty($title) || $title_in_blacklist) && variable_get('breadcrumb_manager_set_title', FALSE)) {
    $source = current_path();
    $alias = drupal_lookup_path('alias', $source);
    $path = !empty($alias) ? $alias : $source;
    $title = breadcrumb_manager_get_title($path);
    return !empty($title) ? $title : FALSE;
  }
  return FALSE;
}

/**
 * Implements hook_preprocess_html().
 */
function breadcrumb_manager_preprocess_html(&$vars) {
  if ($title = breadcrumb_manager_is_title_required()) {
    $vars['head_title_array']['title'] = $title;
    $vars['head_title'] = implode(' | ', $vars['head_title_array']);
  }
}

/**
 * Implements hook_preprocess_page().
 */
function breadcrumb_manager_preprocess_page(&$vars) {
  if ($title = breadcrumb_manager_is_title_required()) {
    drupal_set_title($title);
  }
}

/**
 * Implements hook_metatag_info_alter();
 */
function breadcrumb_manager_metatag_info_alter(&$info) {
  $info['tags']['title']['class'] = 'BreadcrumbManagerTitleMetaTag';
}

Functions

Namesort descending Description
breadcrumb_manager_get_title Helper function: retrieve correct title by path.
breadcrumb_manager_is_excluded_path Check if the breadcrumb for the current path can be overwritten.
breadcrumb_manager_is_front_page Check if the page is the front page.
breadcrumb_manager_is_title_required Check if the current page title is missing or in blacklist.
breadcrumb_manager_menu Implements hook_menu().
breadcrumb_manager_metatag_info_alter Implements hook_metatag_info_alter();
breadcrumb_manager_page_delivery_callback_alter Implements hook_page_delivery_callback_alter().
breadcrumb_manager_permission Implements hook_permission().
breadcrumb_manager_preprocess_html Implements hook_preprocess_html().
breadcrumb_manager_preprocess_page Implements hook_preprocess_page().
breadcrumb_manager_set_breadcrumb Magic function: Evaluates correct breadcrumb from the given path.
_breadcrumb_manager_get_options Helper function: retrieve link options
_breadcrumb_manager_get_title_by_menu_link Helper function: try to find a valid title from the menu_links table.
_breadcrumb_manager_get_title_by_menu_router Helper function: try to find a valid title from the menu_router table.