<?php
// $Id$
/**
* @defgroup menu_helper Menu helper
*
* Enhances Drupal's core menu system and module.
*
* Menu helpers - menu_helper.module
* - menu_helper_active.module
* - menu_helper_auto.module
* - menu_helper_blocks.module
* - menu_helper_submenu.module
* - menu_helper_redirect.module
* - menu_helper_reset.module
*/
/**
* @file
* Enhances Drupal's core menu system and module.
*
* The goal of the menu helper modules is:
* - To make it easier to build and manage your menus.
* - Help syncronize a node with its related menu item.
* - Fix minor menu issues.
*
* This module creates 'menu helper' navigation blocks, labeled 'menu name[Menu helper]' for all existing menus.
*
* These sub-modules integrate with 'Menu helper' navigation blocks :
* - menu_helper_active.module
* - menu_helper_redirect.module
* - menu_helper_reset.module
*
* These sub-modules do not require the 'Menu helper' module.
* - menu_helper_auto.module
* - menu_helper_blocks.module
* - menu_helper_submenu.module
*
* Todo - Submodules
* - Menu_helper_book
* - Display a book's navigation appended to the active trail in the navigation.
* - Menu helper delete
* - Add ability to delete multiple menu items. - @link http://drupal.org/node/287440 http://drupal.org/node/287440 @endlink
* - Menu helper alias
* - Display the related path alias when editing a menu item. Must use AJAX to sync alias when the link path is changed.
*
* Recommended Modules
* - @link http://drupal.org/project/menu_breadcrumb Menu Breadcrumb @endlink
* - @link http://drupal.org/project/custom_breadcrumbs Custom BreadCrumbs @endlink
* - @link http://drupal.org/project/menu_attributes Menu Attributes @endlink
* - @link http://drupal.org/project/ctm Menu Settings per Content Type @endlink
*/
/**
* Implementation of hook_menu().
*/
function menu_helper_menu() {
$items['admin/build/menu/helper'] = array(
'title' => 'Helper',
'access arguments' => array('administer menu'),
'page callback' => 'module_helper_admin',
'page arguments' => array('Menu helper', 'admin/build/menu/helper'),
'file' => 'module_helper.admin.inc',
'type' => MENU_LOCAL_TASK,
'weight' => 50,
);
return $items;
}
/**
* Implementation of hook_block().
*/
function menu_helper_block($op = 'list', $delta = 0, $edit = array()) {
$menus = menu_get_menus();
// Remove navigation and devel menus from menu block list
unset($menus['navigation']);
unset($menus['devel']);
if ($op == 'list') {
$blocks = array();
foreach ($menus as $name => $title) {
$blocks[$name .'-helper']['info'] = check_plain($title .' [Menu helper]');
$blocks[$name .'-helper']['cache'] = BLOCK_NO_CACHE;
}
return $blocks;
}
else if ($op == 'view') {
$menu_name = str_replace('-helper', '', $delta);
$data['subject'] = check_plain($menus[$menu_name]);
$data['content'] = menu_helper_tree_output($menu_name);
return $data;
}
}
/**
* Looks for any menu item with a reset depth, re-positions it, and then renders the menu tree.
*
* This function can be called directly from a theme template, especially if blocks are not being
* used to manage the display of a web site's menus.
*
* Based on the @link http://api.drupal.org/api/function/menu_tree_output menu_tree_output @endlink
*/
function menu_helper_tree_output($menu_name) {
// Change the current path to active item path, if there is one
if ( module_exists('menu_helper_active') ) {
menu_helper_active_item_state_on();
}
// If 'Module helper reset' exists then use it to build the tree
if ( module_exists('menu_helper_reset') ) {
$output = menu_helper_reset_tree($menu_name);
}
else {
$output = menu_tree($menu_name);
}
// Change the active item path back to current path - $_GET['q']
if ( module_exists('menu_helper_active') ) {
menu_helper_active_item_state_off();
}
// If 'Module helper redirect' exists then hide all 'menu-redirect/' from the output
if ( module_exists('menu_helper_redirect') ) {
$output = str_replace('menu-redirect/', '', $output);
}
return $output;
}
/**
* Get menu depths as readable string
*/
function _menu_helper_get_depth_titles() {
return array(
t('Main Navigation'),
t('1st level'),
t('2nd level'),
t('3rd level'),
t('4th level'),
t('5th level'),
t('6th level'),
t('7th level'),
t('8th level'),
t('9th level'),
);
}
/**
* Gets and sets a custom home menu item.
*
* Function is shared by menu_helper_reset.module and menu_helper_subcontent.module
*/
function _menu_helper_home_menu_item($menu_item=NULL) {
static $home_item;
// Build generic home item
if (!isset($home_item)) {
$home_item= array('title' => 'Home', 'link_path' => ''); // aka <front>
}
// get home item
if ($menu_item == NULL) {
return $home_item;
}
// Set home item from the passed menu_item
// If menu item's link_path is the current page
if ( $menu_item['link_path'] == $_GET['q'] ) {
// Check if menu has parent and then use the parent as the home item
if ($menu_item['plid']) {
$home_item = menu_link_load($menu_item['plid']);
}
}
else {
$home_item = $menu_item;
}
}
/**
* Gets the custom home menu item.
*
* Used when a back to link is created by theme_menu_helper_submenu_back($menu_item, $settings).
*/
function _menu_helper_get_home_menu_item() {
return _menu_helper_home_menu_item();
}
/**
* Sets a custom home menu item.
*
* Used when the menu's is home is reset by menu_helper_reset_tree_data($menu_name).
*/
function _menu_helper_set_home_menu_item($path) {
_menu_helper_home_menu_item($path);
}
/**
* Gets an associated array keyed on menu names with each value set to the menu title.
*/
function _menu_helper_get_menu_names() {
// Get friendly label
$result = db_query("SELECT DISTINCT({menu_links}.menu_name), {menu_custom}.title FROM {menu_links} INNER JOIN {menu_custom} ON {menu_custom}.menu_name = {menu_links}.menu_name WHERE module='menu' ORDER BY menu_name");
while ($name = db_fetch_array($result)) {
$menu_names[$name['menu_name']] = $name['title'];
}
return $menu_names;
}