View source
<?php
define('CUSTOM_BREADCRUMBS_TYPE_FIELDS_WEIGHT', 30);
define('CUSTOM_BREADCRUMBS_SHOW_FORM_TABLE_DEFAULT', 1);
function custom_breadcrumbs_cb_breadcrumb_info() {
$breadcrumb_type_info = array();
$breadcrumb_type_info['node'] = array(
'table' => 'custom_breadcrumb',
'field' => 'node_type',
'type' => 'node',
'name_constructor' => '_custom_breadcrumbs_breadcrumb_name',
);
return $breadcrumb_type_info;
}
function _custom_breadcrumbs_breadcrumb_name($breadcrumb) {
if (isset($breadcrumb->node_type)) {
return $breadcrumb->node_type;
}
}
function custom_breadcrumbs_theme() {
return array(
'custom_breadcrumbs_filter_form' => array(
'arguments' => array(
'form' => array(),
),
'file' => 'custom_breadcrumbs.admin.inc',
),
'custom_breadcrumbs_filters' => array(
'arguments' => array(
'form' => array(),
),
'file' => 'custom_breadcrumbs.admin.inc',
),
'custom_breadcrumbs_help_identifiers' => array(
'arguments' => array(),
),
'custom_breadcrumbs_module_weight' => array(
'arguments' => array(
'form' => array(),
),
'file' => 'custom_breadcrumbs.admin.inc',
),
);
}
function custom_breadcrumbs_menu() {
$items = array();
$items['admin/build/custom_breadcrumbs'] = array(
'title' => 'Custom Breadcrumbs',
'description' => 'Customize the breadcrumb trail for pages on your site.',
'page callback' => 'custom_breadcrumbs_page',
'access arguments' => array(
'administer custom breadcrumbs',
),
'file' => 'custom_breadcrumbs.admin.inc',
);
$items['admin/build/custom_breadcrumbs/list'] = array(
'title' => 'List',
'page callback' => 'custom_breadcrumbs_page',
'access arguments' => array(
'administer custom breadcrumbs',
),
'file' => 'custom_breadcrumbs.admin.inc',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => 0,
);
$items['admin/build/custom_breadcrumbs/node/add'] = array(
'title' => 'Node',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'custom_breadcrumbs_form',
'node',
),
'access arguments' => array(
'administer custom breadcrumbs',
),
'file' => 'custom_breadcrumbs.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 1,
);
$items['admin/build/custom_breadcrumbs/node/edit'] = array(
'title' => 'Edit custom breadcrumb for nodes',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'custom_breadcrumbs_form',
'node',
),
'access arguments' => array(
'administer custom breadcrumbs',
),
'file' => 'custom_breadcrumbs.admin.inc',
'type' => MENU_CALLBACK,
);
$items['admin/settings/custom-breadcrumbs'] = array(
'title' => 'Custom Breadcrumb Settings',
'description' => 'Manage sitewide configuration settings to customize the breadcrumb trail.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'custom_breadcrumbs_admin_settings',
),
'access arguments' => array(
'administer custom breadcrumbs',
),
'file' => 'custom_breadcrumbs.admin.inc',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function custom_breadcrumbs_preprocess_page(&$variables) {
if (!custom_breadcrumbs_exclude_path()) {
if (variable_get('custom_breadcrumbs_set_global_home_breadcrumb', FALSE)) {
$trail = drupal_get_breadcrumb();
if (!empty($trail) && strip_tags($trail[0]) == t('Home')) {
array_shift($trail);
$cb_home = custom_breadcrumbs_home_crumb();
if (!empty($cb_home)) {
array_unshift($trail, array_pop($cb_home));
}
drupal_set_breadcrumb($trail);
$variables['breadcrumb'] = theme('breadcrumb', drupal_get_breadcrumb());
}
}
}
}
function custom_breadcrumbs_init() {
if (variable_get('custom_breadcrumbs_set_menu_breadcrumb', FALSE)) {
custom_breadcrumbs_set_menu_breadcrumb();
}
}
function custom_breadcrumbs_perm() {
return array(
'administer custom breadcrumbs',
'use php in custom breadcrumbs',
);
}
function custom_breadcrumbs_help($path, $arg) {
switch ($path) {
case 'admin/help#custom_breadcrumbs':
$output = '<p>' . t("Custom Breadcrumbs allows you to create and modify your own breadcrumbs based on node type. After enabling the module, click on Administer > Site building > Custom breadcrumbs. Select <em>Node Type</em> at the top of the page to create breadcrumbs according to node type. Other types (such as views, paths, nd taxonomy) may also be present, depending on what modules have been installed.") . '</p>';
$output .= '<p>' . t("On the <em>Node Type</em> page, select the node type the breadcrumb will apply to. There are two text fields below-- 'Titles' and 'Paths.' When creating a breadcrumb, you are simply creating a link. In the custom breadcrumbs interface 'Titles' describes the text of the breadcrumb while 'Paths' describes the Drupal path the breadcrumb links to. Each Title must have a corresponding Path.") . '</p>';
$output .= '<p>' . t("To give a very simple example of how to use this module, let's say I have a blog on my web site called 'Deep Thoughts.' To create this, I use the Views module to create a page at /blog that displays all the node types 'blog post.' Whenever a user views a blog post I want the breadcrumb to show Home > Deep Thoughts instead of simply Home. To do this I would simply type 'Deep Thoughts' in the 'Titles' field and and 'blog' in the 'Paths' field and save my breadcrumb.") . '</p>';
$output .= '<p>' . t("Using the Tokens module, the Custom breadcrumbs module becomes much more flexible because breadcrumbs can become dynamic. You can create a breadcrumb like Home > Deep Thoughts > [Month of Blog Post] [Year of Blog Post], where 'Deep Thoughts' links to my main blog page and '[Month of Blog Post] [Year of Blog Post]' links to a view that shows only blog posts from the month and year the blog post was created (e.g. June 2007). For this, you would do the following:") . '</p>';
$output .= '<p>' . t("Node Type:<br />Blog Post<br /><br />Titles:<br />Deep Thoughts<br />[month] [yyyy]<br /><br />Paths:<br />blog<br />blog/[mm]_[yyyy]<br />(where of course, blog/[mm]_[yyyy] is the path to the view of blog posts from that month and year). So if you created a blog post on June 13, 2007 your breadcrumb would show Home > Deep Thoughts > June 2007 and 'June 2007' links to 'blog/06_2007' which is a view of all blog posts from June 2007.") . '</p>';
$output .= '<p>' . t("Also, note that Custom Breadcrumbs doesn't actually check to be sure that a particular path exists, so you'll have to check yourself to avoid 404 errors.") . '</p>';
$output .= '<p>' . t("Only users with 'administer custom breadcrumbs' permission will be allowed to create or modify custom breadcrumbs.") . '</p>';
$output .= '<h2>' . t("Breadcrumb Visibility") . '</h2>';
$output .= '<p>' . t("Users given 'use php in custom breadcrumbs' permission can include php code snippet that returns TRUE or FALSE to control whether or not the breadcrumb is displayed. Note that this code has access to the %node variable, and can check its type or any other property.", array(
'%node' => '$node',
)) . '</p>';
$output .= '<h2>' . t("Special Identifiers") . '</h2>';
$output .= '<p>' . t("Special identifiers are now provided through optional modules implementing hook_cb_identifier_list(), to provide a description of the identifer, and hook_cb_identifier_values(), to prepare the appropriate crumb items. See the custom_breadcrumbs_identifiers.module file for examples of how to do this.") . '</p>';
$output .= '<p>' . t("Currently, the following identifiers can be used to achieve a special behavior:") . '</p>';
$output .= theme('custom_breadcrumbs_help_identifiers');
$output .= '<p>' . t("Identifiers should be added to the paths area in the following format: identifier|path. To be recognized, the identifier must be enclosed in angular brackets and proceed any part of the path. For example: %pathauto|[ogname-raw]", array(
'%pathauto' => '<pathauto>',
)) . '</p>';
return $output;
case 'admin/build/custom_breadcrumbs':
$output = '<p>' . t("To create a custom breadcrumb, choose one of the breadcrumb types listed above. The following table lists all of the custom breadcrumbs that have been defined. The list can be filtered by breadcrumb type or language, or sorted by clicking on one of the column headings.") . '</p>';
$output .= '<p>' . t('You can configure Custom Breadcrumb settings at <a href="@link">admin/settings/custom-breadcrumbs</a>.', array(
'@link' => url('admin/settings/custom-breadcrumbs'),
)) . '</p>';
return $output;
}
}
function custom_breadcrumbs_nodeapi($node, $op, $teaser, $page) {
if ($op == 'alter' && empty($teaser) && !empty($page)) {
global $language;
$languages = array(
'language' => $language->language,
'all' => '',
);
$breadcrumbs = custom_breadcrumbs_load_breadcrumbs('custom_breadcrumbs', NULL, array(
'node_type' => $node->type,
), $languages);
if (!empty($breadcrumbs)) {
$objs = array(
'node' => $node,
);
if ($breadcrumb = custom_breadcrumbs_select_breadcrumb($breadcrumbs, $objs)) {
custom_breadcrumbs_set_breadcrumb($breadcrumb, $objs);
}
}
}
}
function custom_breadcrumbs_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'comment_form' && isset($form['nid']['#value'])) {
$node = node_load($form['nid']['#value']);
custom_breadcrumbs_nodeapi($node, 'alter', array(), array(
1,
));
}
elseif (isset($form['#node']->type) && variable_get('custom_breadcrumbs_show_form_table_' . $form['#node']->type, CUSTOM_BREADCRUMBS_SHOW_FORM_TABLE_DEFAULT) && user_access('administer custom breadcrumbs') && isset($form['type']) && isset($form['#node']) && $form['type']['#value'] . '_node_form' == $form_id) {
$node = $form['#node'];
$breadcrumbs = custom_breadcrumbs_load_breadcrumbs('custom_breadcrumbs', 'custom_breadcrumb', array(
'node_type' => $form['type']['#value'],
));
foreach (module_implements('cb_node_form_table') as $module) {
$func = $module . '_cb_node_form_table';
$more = $func($node);
if (!empty($more)) {
$breadcrumbs = array_merge($breadcrumbs, $more);
}
}
$output = NULL;
if (count($breadcrumbs) > 0) {
$output = '<p>' . t('Custom breadcrumbs have been created for this %type page. Use the <a href="@link">Custom Breadcrumbs Administration Page</a> to add additional breadcrumbs, or follow the links in the table below to edit or delete existing custom breadcrumbs.', array(
'%type' => $form['type']['#value'],
'@link' => url('admin/build/custom_breadcrumbs'),
)) . '</p>';
}
module_load_include('inc', 'custom_breadcrumbs', 'custom_breadcrumbs.admin');
$output .= custom_breadcrumbs_simple_breadcrumb_table($breadcrumbs);
$form['custom_breadcrumbs'] = array(
'#type' => 'fieldset',
'#title' => t('Custom Breadcrumbs'),
'#access' => user_access('administer custom breadcrumbs'),
'#group' => 'additional_settings',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => function_exists('content_extra_field_weight') && isset($form['type']) ? content_extra_field_weight($form['type']['#value'], 'custom_breadcrumbs') : CUSTOM_BREADCRUMBS_TYPE_FIELDS_WEIGHT,
);
$form['custom_breadcrumbs']['breadcrumb_table'] = array(
'#value' => $output,
);
}
if (user_access('administer custom breadcrumbs') && $form_id == 'node_type_form') {
$form['custom_breadcrumbs'] = array(
'#type' => 'fieldset',
'#title' => t('Custom Breadcrumbs'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => function_exists('content_extra_field_weight') && isset($form['type']) ? content_extra_field_weight($form['type']['#value'], 'custom_breadcrumbs') : CUSTOM_BREADCRUMBS_TYPE_FIELDS_WEIGHT,
);
$form['custom_breadcrumbs']['custom_breadcrumbs_show_form_table'] = array(
'#type' => 'checkbox',
'#title' => t('Display defined custom breadcrumbs on node edit form'),
'#description' => t('Access is limited to users with administer custom breadcrumbs permission.'),
'#default_value' => variable_get('custom_breadcrumbs_show_form_table_' . $form['#node_type']->type, CUSTOM_BREADCRUMBS_SHOW_FORM_TABLE_DEFAULT),
);
}
}
function custom_breadcrumbs_content_extra_fields($type_name) {
$fields['custom_breadcrumbs'] = array(
'label' => t('Custom Breadcrumbs'),
'description' => t('Custom Breadcrumbs module form.'),
'weight' => CUSTOM_BREADCRUMBS_TYPE_FIELDS_WEIGHT,
);
return $fields;
}
function custom_breadcrumbs_select_breadcrumb($breadcrumbs, $objs = array()) {
while ($breadcrumb = array_pop($breadcrumbs)) {
if (custom_breadcrumbs_is_visible($breadcrumb, $objs)) {
return $breadcrumb;
}
}
}
function custom_breadcrumbs_set_breadcrumb($breadcrumb, $objs = array()) {
if ($breadcrumb && !custom_breadcrumbs_exclude_path()) {
$locations = array();
$trail = _custom_breadcrumbs_get_breadcrumb($breadcrumb, $objs, $locations);
if (variable_get('custom_breadcrumbs_force_active_trail', FALSE)) {
menu_set_active_trail($locations);
}
drupal_set_breadcrumb($trail);
custom_breadcrumbs_unique_breadcrumb_id($breadcrumb->breadcrumb_type, $breadcrumb->bid);
return TRUE;
}
}
function _custom_breadcrumbs_get_breadcrumb($breadcrumb, $objs, &$locations) {
if (!is_array($locations)) {
$locations = array();
}
elseif (isset($locations['title']) || isset($locations['href'])) {
$locations = array(
$locations,
);
}
$trail = custom_breadcrumbs_home_crumb();
if (!empty($trail)) {
$title = variable_get('custom_breadcrumb_home', t('Home'));
$locations[] = array(
'title' => variable_get('custom_breadcrumb_home', t('Home')),
'href' => '<front>',
'localized_options' => array(),
);
}
if (variable_get('custom_breadcrumbs_use_php_in_titles', FALSE)) {
$titles = extract_php($breadcrumb->titles, $objs);
if (isset($titles['titles']) && is_array($titles['titles']) && isset($titles['paths']) && is_array($titles['paths'])) {
$paths = $titles['paths'];
$titles = $titles['titles'];
}
else {
$paths = extract_php($breadcrumb->paths, $objs);
}
}
if (!isset($titles) || is_null($titles)) {
$titles = preg_split("/[\n]+/", $breadcrumb->titles);
}
if (!isset($paths) || is_null($paths)) {
$paths = preg_split("/[\n]+/", $breadcrumb->paths);
}
if (module_exists('token')) {
$types = custom_breadcrumbs_token_types($objs);
foreach ($titles as $index => $value) {
$titles[$index] = token_replace_multiple($value, $types);
}
foreach ($paths as $index => $value) {
$paths[$index] = token_replace_multiple($value, $types);
}
}
if (variable_get('custom_breadcrumbs_append_page_title', FALSE) && !drupal_is_front_page()) {
$titles[] = drupal_get_title();
if (variable_get('custom_breadcrumbs_append_page_title_no_link', FALSE)) {
$paths[] = '<none>';
}
else {
$paths[] = $_GET['q'];
}
}
$items = _custom_breadcrumbs_get_trail_items($breadcrumb, $titles, $paths);
foreach ($items as $item) {
if ($item['crumb']) {
$trail[] = $item['crumb'];
}
if (variable_get('custom_breadcrumbs_force_active_trail', FALSE)) {
$locations[] = array(
'title' => $item['title'],
'href' => drupal_get_normal_path(trim($item['href'])),
);
}
}
return $trail;
}
function _custom_breadcrumbs_get_trail_items($breadcrumb, $titles, $paths) {
$trail_items = array();
for ($i = 0; $i < count($titles); $i++) {
$title = trim($titles[$i]);
if ($title != '' && $title != '<none>') {
$options = _custom_breadcrumbs_identifiers_option($i + 1, $breadcrumb->bid);
$crumb_items = _custom_breadcrumbs_create_crumb_items($title, trim($paths[$i]), $options);
$trail_items = array_merge($trail_items, $crumb_items);
}
}
return $trail_items;
}
function custom_breadcrumbs_unique_breadcrumb_id($type = NULL, $bid = NULL) {
static $stored_breadcrumb_id;
if (variable_get('custom_breadcrumbs_type_class', FALSE)) {
if (isset($type)) {
$base = 'custom-breadcrumbs';
$cbid = $base . '-' . $type;
if (variable_get('custom_breadcrumbs_append_bid_class', FALSE) && isset($bid)) {
$cbid .= '-' . $bid;
}
$stored_breadcrumb_id = $cbid;
}
if (isset($stored_breadcrumb_id)) {
return $stored_breadcrumb_id;
}
}
}
function custom_breadcrumbs_token_types($objs = array()) {
if (!isset($objs['user'])) {
global $user;
if ($user->uid) {
$user = user_load(array(
'uid' => $user->uid,
));
}
$objs['user'] = $user;
}
$objs['global'] = NULL;
return $objs;
}
function _custom_breadcrumbs_save_breadcrumb($module, $key, $breadcrumb) {
if (is_array($breadcrumb->paths)) {
$breadcrumb->paths = implode("\n", $breadcrumb->paths);
}
if (is_array($breadcrumb->titles)) {
$breadcrumb->titles = implode("\n", $breadcrumb->titles);
}
$info = module_invoke($module, 'cb_breadcrumb_info');
if (isset($info[$key])) {
if ((!isset($breadcrumb->name) || $breadcrumb->name == '') && isset($info[$key]['name_constructor']) && function_exists($info[$key]['name_constructor'])) {
$breadcrumb->name = $info[$key]['name_constructor']($breadcrumb);
}
if (isset($breadcrumb->bid)) {
drupal_write_record($info[$key]['table'], $breadcrumb, 'bid');
}
else {
drupal_write_record($info[$key]['table'], $breadcrumb);
}
}
}
function _custom_breadcrumbs_delete_breadcrumb($module, $key, $bid) {
$info = module_invoke($module, 'cb_breadcrumb_info');
if (isset($info[$key]['table'])) {
db_query('DELETE FROM {' . $info[$key]['table'] . '} WHERE bid = %d', $bid);
}
}
function custom_breadcrumbs_home_crumb() {
$hometext = variable_get('custom_breadcrumb_home', t('Home'));
if ($hometext != '') {
$options = _custom_breadcrumbs_identifiers_option();
$original_title = decode_entities($hometext);
$title_parts = explode("|", $original_title, 2);
if (isset($title_parts[1])) {
$options['attributes']['title'] = $title_parts[1];
}
$trail = array(
l($title_parts[0], '<front>', $options),
);
}
else {
$trail = array();
}
return $trail;
}
function _custom_breadcrumbs_create_crumb_items($title, $original_path, $attributes = array()) {
$crumbs = array();
$original_title = decode_entities($title);
$title_parts = explode("|", $original_title, 2);
$title = $title_parts[0];
if (isset($title_parts[1])) {
$attributes['attributes']['title'] = $title_parts[1];
}
$original_path = preg_replace('/\\/+/', '/', $original_path);
$original_path = preg_replace('/^\\/|\\/+$/', '', $original_path);
$path_parts = explode("|", $original_path, 2);
$values = NULL;
$identifier = trim($path_parts[0]);
$path = isset($path_parts[1]) ? $path_parts[1] : NULL;
$obj = array(
'title' => $title,
'path' => $path,
'attributes' => $attributes,
);
foreach (module_implements('cb_identifier_values') as $module) {
$values = module_invoke($module, 'cb_identifier_values', $identifier, $obj);
if (isset($values)) {
break;
}
}
if (isset($values)) {
if (!is_array($values)) {
$crumbs[] = array(
'crumb' => $values,
'title' => $title,
'href' => $path,
);
}
elseif (isset($values['crumb']) || isset($values['title']) || isset($values['href'])) {
$crumbs[] = $values;
}
else {
$crumbs = $values;
}
}
else {
if (!isset($path)) {
$path = $original_path;
}
if ($path != '<none>') {
$options = parse_url($path);
$options = array_merge($options, $attributes);
$crumbs[] = array(
'crumb' => l($title, $options['path'], $options),
'title' => $title,
'href' => $options['path'],
);
}
else {
$crumbs[] = array(
'crumb' => $title,
'title' => $title,
);
}
}
return $crumbs;
}
function theme_custom_breadcrumbs_help_identifiers() {
$identifiers = module_invoke_all('cb_identifier_list');
$headers = array(
t('Identifier'),
t('Behaviour'),
);
$rows = array();
if (!empty($identifiers)) {
foreach ($identifiers as $id => $description) {
$rows[] = array(
check_plain($id),
$description,
);
}
}
else {
$rows[] = array(
array(
'data' => t('No special identifiers have been defined. You must <a href="@link">enable the custom breadcrumbs identifiers module</a> or another module that implements hook_cb_identifier_list and hook_cb_identifier_values to enable this feature.', array(
'@link' => url('admin/build/modules'),
)),
'colspan' => 2,
),
);
}
return theme('table', $headers, $rows, array(
'class' => 'description',
));
}
function custom_breadcrumbs_load_breadcrumbs($module, $table = NULL, $param = array(), $languages = array()) {
static $breadcrumbs_cache = array();
$breadcrumbs = array();
$bc_info = module_invoke($module, 'cb_breadcrumb_info');
foreach ($bc_info as $info) {
if (!isset($table) || $info['table'] == $table) {
$args = array();
$cond = array();
$cond_string = array();
$sql = "SELECT * FROM {" . $info['table'] . "}";
if ($p = !empty($param)) {
$sql .= " WHERE ";
foreach ($param as $key => $value) {
$cond[] = db_escape_string($key) . " = '%s'";
$args[] = $value;
$cond_string[] = $key . '_' . $value;
}
if (!empty($cond)) {
$sql .= implode(' AND ', $cond);
}
}
if (!empty($languages)) {
$sql .= $p ? " AND " : " WHERE ";
$sql .= "language IN (" . db_placeholders($languages, 'text') . ") ORDER BY language ASC";
$args = array_merge($args, $languages);
}
$ckey = "{$info['table']}-{" . implode('_', $cond_string) . "}-" . implode('_', $languages);
if (isset($breadcrumbs_cache[$ckey])) {
$breadcrumbs = $breadcrumbs_cache[$ckey];
}
else {
$result = db_query($sql, $args);
while ($breadcrumb = db_fetch_object($result)) {
if (!isset($breadcrumb->name)) {
$breadcrumb->name = isset($info['name_constructor']) ? $info['name_constructor']($breadcrumb) : $breadcrumb->{$info}['field'];
}
$breadcrumb->breadcrumb_type = $info['type'];
$breadcrumbs[] = $breadcrumb;
}
$breadcrumbs_cache[$ckey] = $breadcrumbs;
}
}
}
return $breadcrumbs;
}
function custom_breadcrumbs_is_visible($breadcrumb, $objs = array()) {
$visibility = TRUE;
if (isset($breadcrumb->visibility_php)) {
$trimmed = trim($breadcrumb->visibility_php);
if ($trimmed != '') {
foreach ($objs as $key => $obj) {
${$key} = is_object($obj) ? drupal_clone($obj) : $obj;
}
ob_start();
$visibility = eval($trimmed);
ob_end_clean();
}
}
return $visibility;
}
function _custom_breadcrumbs_load_all_breadcrumbs($refresh = FALSE) {
static $breadcrumbs;
if ($refresh || !isset($breadcrumbs)) {
$breadcrumbs = array();
foreach (module_implements('cb_breadcrumb_info') as $module) {
$more = custom_breadcrumbs_load_breadcrumbs($module);
if (!empty($more)) {
$breadcrumbs = array_merge($more, $breadcrumbs);
}
}
}
return $breadcrumbs;
}
function custom_breadcrumbs_set_menu_breadcrumb() {
static $menu_id_cache = array();
$menu_item = menu_get_item();
$ckey = $menu_item['href'];
if (!isset($menu_id_cache[$ckey])) {
$result = db_query("SELECT mlid, menu_name FROM {menu_links} WHERE link_path = '%s'", $menu_item['href']);
$menu_link_menus = array();
while ($menu_link = db_fetch_array($result)) {
$menu_link_menus[$menu_link['mlid']] = $menu_link['menu_name'];
}
$menu_id_cache[$ckey] = $menu_link_menus;
}
$menu_links = $menu_id_cache[$ckey];
$use_menus = variable_get('custom_breadcrumbs_menu_list', array());
foreach ($menu_links as $mlid => $menu_name) {
if (in_array($menu_name, $use_menus)) {
menu_set_active_menu_name($menu_name);
$breadcrumb = menu_get_active_breadcrumb();
if (variable_get('custom_breadcrumbs_append_page_title', FALSE) && !drupal_is_front_page()) {
$title = drupal_get_title();
if (variable_get('custom_breadcrumbs_append_page_title_no_link', FALSE)) {
$breadcrumb[] = $title;
}
else {
$breadcrumb[] = l($title, $_GET['q'], array(
'html' => TRUE,
));
}
}
drupal_set_breadcrumb($breadcrumb);
return TRUE;
}
}
}
function custom_breadcrumbs_theme_registry_alter(&$theme_registry) {
if (variable_get('custom_breadcrumbs_force_active_trail', FALSE) && !empty($theme_registry['links'])) {
global $theme;
$themes = variable_get('custom_breadcrumbs_menu_theme', array());
$themes[$theme] = array(
'menu_item' => $theme_registry['menu_item']['function'],
'menu_item_link' => $theme_registry['menu_item_link']['function'],
);
variable_set('custom_breadcrumbs_menu_theme', $themes);
$theme_registry['links']['function'] = 'custom_breadcrumbs_override_links';
$theme_registry['menu_item_link']['function'] = 'custom_breadcrumbs_theme_menu_item_link';
$theme_registry['menu_item']['function'] = 'custom_breadcrumbs_theme_menu_item';
}
}
function custom_breadcrumbs_in_active_trail($link) {
if (!isset($link) || !isset($link['href'])) {
return FALSE;
}
$trail = menu_get_active_trail();
if (!isset($trail)) {
return FALSE;
}
foreach ($trail as $step) {
if (isset($step['href']) && ($step['href'] == $link['href'] || $step['href'] == drupal_get_path_alias($link['href']))) {
return TRUE;
}
}
return FALSE;
}
function custom_breadcrumbs_override_links($links, $attributes = array(
'class' => 'links',
)) {
$output = '';
if (count($links) > 0) {
$output = '<ul' . drupal_attributes($attributes) . '>';
$num_links = count($links);
$i = 1;
foreach ($links as $key => $link) {
$class = $key;
if ($i == 1) {
$class .= ' first';
}
if ($i == $num_links) {
$class .= ' last';
}
if (isset($link['href']) && ($link['href'] == $_GET['q'] || $link['href'] == '<front>' && drupal_is_front_page())) {
$class .= ' active';
}
if (custom_breadcrumbs_in_active_trail($link) && $link['href'] != '<front>') {
$class .= ' active-trail';
}
$output .= '<li' . drupal_attributes(array(
'class' => $class,
)) . '>';
if (isset($link['href'])) {
$output .= l($link['title'], $link['href'], $link);
}
elseif (!empty($link['title'])) {
if (empty($link['html'])) {
$link['title'] = check_plain($link['title']);
}
$span_attributes = '';
if (isset($link['attributes'])) {
$span_attributes = drupal_attributes($link['attributes']);
}
$output .= '<span' . $span_attributes . '>' . $link['title'] . '</span>';
}
$i++;
$output .= "</li>\n";
}
$output .= '</ul>';
}
return $output;
}
function custom_breadcrumbs_theme_menu_item_link($link) {
global $theme;
static $function;
if (!isset($function)) {
$registry = variable_get('custom_breadcrumbs_menu_theme', array());
$function = isset($registry[$theme]) ? $registry[$theme]['menu_item_link'] : 'theme_menu_item_link';
}
if (isset($link['mlid'])) {
$link['localized_options']['attributes']['id'] = 'custom_breadcrumbs_menu-' . _custom_breadcrumbs_menu_unique_id($link['mlid']);
$link['options']['attributes']['id'] = $link['localized_options']['attributes']['id'];
_custom_breadcrumbs_menu_stack($link);
if (custom_breadcrumbs_in_active_trail($link)) {
$link['localized_options']['attributes']['class'] = 'active';
}
}
return $function($link);
}
function custom_breadcrumbs_theme_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
global $theme;
static $function;
if (!isset($function)) {
$registry = variable_get('custom_breadcrumbs_menu_theme', array());
$function = isset($registry[$theme]) ? $registry[$theme]['menu_item'] : 'theme_menu_item';
}
$item = _custom_breadcrumbs_menu_stack();
if ($has_children && !$menu) {
$tree = _custom_breadcrumbs_menu_subtree($item);
$force_active_trail = FALSE;
if (!empty($tree)) {
foreach ($tree as $sub => $data) {
if (custom_breadcrumbs_in_active_trail($data['link'])) {
$force_active_trail = TRUE;
}
else {
$belows = (array) $data['below'];
foreach ($belows as $id => $below) {
if (custom_breadcrumbs_in_active_trail($below['link'])) {
$force_active_trail = TRUE;
}
else {
unset($tree[$sub]['below'][$id]);
}
}
}
}
}
if ($force_active_trail) {
$menu = menu_tree_output($tree);
$in_active_trail = TRUE;
}
if (!$menu) {
$has_children = FALSE;
}
}
if ($menu && !$in_active_trail) {
$extra_class .= ' collapsed start-collapsed ';
}
return $function($link, $has_children, $menu, $in_active_trail, $extra_class);
}
function _custom_breadcrumbs_menu_subtree($item) {
static $index = array();
static $indexed = array();
$tree = menu_tree_all_data($item['menu_name']);
if (!isset($indexed[$item['menu_name']])) {
$index += _custom_breadcrumbs_menu_index($tree);
$indexed[$item['menu_name']] = TRUE;
}
foreach ($index[$item['mlid']]['parents'] as $mlid) {
$key = $index[$mlid]['key'];
if (!isset($tree[$key])) {
return array();
}
$tree = $tree[$key]['below'];
}
$key = $index[$item['mlid']]['key'];
return isset($tree[$key]) ? $tree[$key]['below'] : array();
}
function _custom_breadcrumbs_menu_index($tree, $ancestors = array(), $parent = NULL) {
$index = array();
if ($parent) {
$ancestors[] = $parent;
}
foreach ($tree as $key => $item) {
$index[$item['link']['mlid']] = array(
'key' => $key,
'parents' => $ancestors,
);
if (!empty($item['below'])) {
$index += _custom_breadcrumbs_menu_index($item['below'], $ancestors, $item['link']['mlid']);
}
}
return $index;
}
function _custom_breadcrumbs_menu_unique_id($id) {
static $ids = array();
if (!isset($ids[$id])) {
$ids[$id] = 1;
return $id;
}
else {
return $id . '-' . $ids[$id]++;
}
}
function _custom_breadcrumbs_menu_stack($link = FALSE) {
static $stack = array();
if ($link) {
array_push($stack, $link);
}
else {
return array_pop($stack);
}
}
function _custom_breadcrumbs_get_module_weight($names) {
$weights = array();
$results = db_query("SELECT name, weight FROM {system} WHERE name IN (" . db_placeholders($names, 'text') . ") AND status = 1 ORDER BY weight ASC", $names);
while ($row = db_fetch_object($results)) {
$weights[$row->name] = (int) $row->weight;
}
return $weights;
}
function extract_php($text, $objs = array()) {
if (drupal_substr(trim($text), 0, 5) == '<?php') {
$text = str_replace(array(
'<?php',
'?>',
), '', $text);
foreach ($objs as $key => $obj) {
${$key} = is_object($obj) ? drupal_clone($obj) : $obj;
}
ob_start();
$output = eval($text);
ob_end_clean();
return is_array($output) ? $output : NULL;
}
}
function custom_breadcrumbs_exclude_path() {
static $excluded;
if (variable_get('custom_breadcrumbs_use_exclude_list', FALSE)) {
if (!isset($excluded)) {
$excluded = explode(',', variable_get('custom_breadcrumbs_exclude_list', ''));
}
if (!empty($excluded)) {
module_load_include('inc', 'custom_breadcrumbs', 'custom_breadcrumbs_common');
foreach ($excluded as $path) {
if (_custom_breadcrumbs_match_path($_REQUEST['q'], trim($path))) {
return TRUE;
}
}
}
}
return FALSE;
}
function _custom_breadcrumbs_identifiers_option($part = 0, $bid = NULL) {
$options = array(
'attributes' => array(),
);
$classes = array();
$base = 'custom-breadcrumbs';
if (variable_get('custom_breadcrumbs_home_id', FALSE) && $part == 0) {
$options['attributes']['id'] = $base . '-home';
}
elseif (variable_get('custom_breadcrumbs_parts_class', FALSE) && $part > 0) {
$classes[] = $base . '-item-' . $part;
}
if (variable_get('custom_breadcrumbs_even_odd_class', FALSE)) {
$classes[] = $part % 2 == 0 ? 'even' : 'odd';
}
if (!empty($classes)) {
$options['attributes']['class'] = implode(' ', $classes);
}
return $options;
}