menu_helper.module

<?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;
}