You are here

menu_block.module in Menu Block 5.2

Provides configurable blocks of menu items.

File

menu_block.module
View source
<?php

/**
 * @file
 * Provides configurable blocks of menu items.
 */

// @TODO: For PHP 4 compatibility we use foreach (array_keys($array) AS $key).
// When PHP 5 becomes required (Drupal 7.x), use the following faster
// implementation: foreach ($array AS $key => &$value) {}

/**
 * Implements hook_menu().
 */
function menu_block_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/build/block/add-menu-block',
      'title' => t('Add menu block'),
      'description' => t('Add a new menu block.'),
      'access' => user_access('administer blocks'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'menu_block_add_block_form',
      ),
      'type' => MENU_LOCAL_TASK,
    );
    $items[] = array(
      'path' => 'admin/build/block/delete-menu-block',
      'title' => t('Delete menu block'),
      'access' => user_access('administer blocks'),
      'callback' => 'drupal_get_form',
      'callback arguments' => array(
        'menu_block_delete',
      ),
      'type' => MENU_CALLBACK,
    );
    $items[] = array(
      'path' => 'admin/settings/menu_block',
      'title' => t('Menu block'),
      'description' => t('Add a new menu block.'),
      'access' => user_access('administer blocks'),
      'callback' => '_menu_block_by_module_hack',
    );
  }
  return $items;
}

/**
 * Implements hook_help().
 */
function menu_block_help($section) {
  switch ($section) {
    case 'admin/help#menu_block':
    case 'admin/build/block':
      include_once './' . drupal_get_path('module', 'menu_block') . '/menu_block.pages.inc';
      return _menu_block_help($section);
  }
}

/**
 * Alters the block admin form to add delete links next to menu blocks.
 */
function menu_block_form_alter($form_id, &$form) {
  switch ($form_id) {
    case 'block_admin_display':
      include_once './' . drupal_get_path('module', 'menu_block') . '/menu_block.admin.inc';
      _menu_block_form_block_admin_display_alter($form);
      break;
    case 'menu_block_add_block_form':
      include_once './' . drupal_get_path('module', 'menu_block') . '/menu_block.admin.inc';
      _menu_block_form_menu_block_add_block_form_alter($form);
      break;
  }
}

/**
 * Menu callback: display the menu block addition form.
 */
function menu_block_add_block_form() {
  include_once './' . drupal_get_path('module', 'menu_block') . '/menu_block.admin.inc';
  return _menu_block_add_block_form();
}

/**
 * Menu callback: confirm deletion of menu blocks.
 */
function menu_block_delete($delta = 0) {
  include_once './' . drupal_get_path('module', 'menu_block') . '/menu_block.admin.inc';
  return _menu_block_delete($delta);
}

/**
 * This page is simply to make Menu block visible on admin pages.
 *
 * In Drupal 5, the admin/by-module page won't display Menu block's help link
 * because it doesn't have any non-tab menu links. So to allow Menu block to
 * have some "visibility" in the admin pages, we add a fake-ish page to
 * admin/settings/menu_block that redirects to the "Add menu block" tab.
 */
function _menu_block_by_module_hack() {
  drupal_goto('admin/build/block/add-menu-block', NULL, NULL, 301);
}

/**
 * Implements hook_block().
 */
function menu_block_block($op = 'list', $delta = NULL, $edit = NULL) {
  $function = '_menu_block_block_' . $op;
  if (function_exists($function)) {
    return $function($delta, $edit);
  }
  else {

    // "op"s besides "view" are seldom used, so we store them in a separate file.
    include_once './' . drupal_get_path('module', 'menu_block') . '/menu_block.admin.inc';
    if (function_exists($function)) {
      return $function($delta, $edit);
    }
  }
}

/**
 * Returns the 'view' $op info for hook_block().
 *
 * @param $delta
 *   string The name of the block to render.
 */
function _menu_block_block_view($delta) {
  $data = array();

  // Get the block configuration options.
  $mid = variable_get("menu_block_{$delta}_menu_name", 1);
  $level = variable_get("menu_block_{$delta}_level", 1);
  $depth = variable_get("menu_block_{$delta}_depth", 0);
  $expanded = variable_get("menu_block_{$delta}_expanded", 0);

  // Render the block if the active menu item is in this menu.
  if ($level == 1 || menu_in_active_trail($mid)) {
    if ($level != 1) {

      // Get the menu item of the n-level link in the active trail.
      $active_trail = _menu_get_active_trail();
      $mid = $active_trail[$level - 1];
    }
    $menu_item = menu_get_item($mid);
    $data['subject'] = check_plain($menu_item['title']);
    $data['content'] = theme('menu_block_tree', $mid, $depth, $depth == 1 ? FALSE : $expanded);
  }
  return $data;
}

/**
 * Generate the HTML for a menu tree.
 *
 * @ingroup themeable
 *
 * @param $pid
 *   int The parent id of the menu.
 * @param $depth_limit
 *   int The maximum depth of the returned tree, 0 for unlimited.
 * @param $expanded
 *   boolean Whether to expand the entire menu tree.
 * @return
 *   string The rendered menu tree.
 */
function theme_menu_block_tree($pid = 1, $depth_limit = 0, $expanded = FALSE) {
  if ($tree = menu_block_tree($pid, $depth_limit, $expanded)) {
    return '<ul class="menu menu-tree menu-' . $pid . '">' . $tree . '</ul>';
  }
  else {
    return '';
  }
}

/**
 * Returns a rendered menu tree or menu list.
 *
 * @param $pid
 *   int The parent id of the menu.
 * @param $depth_limit
 *   int The maximum depth of the returned tree, 0 for unlimited.
 * @param $expanded
 *   boolean Whether to expand the entire menu tree.
 * @return
 *   string The rendered items of a menu.
 */
function menu_block_tree($pid = 1, $depth_limit = 0, $expanded = FALSE) {
  $menu = menu_get_menu();
  $output = '';
  if (isset($menu['visible'][$pid]) && $menu['visible'][$pid]['children']) {
    $active_id = menu_get_active_item();
    $count = 1;
    $total_children = count($menu['visible'][$pid]['children']);
    foreach ($menu['visible'][$pid]['children'] as $mid) {

      // Theme the menu link
      $in_active_trail = menu_in_active_trail_in_submenu($mid, $pid);
      $item = menu_get_item($mid);
      $item['attributes'] = array();
      if (!empty($item['description'])) {
        $item['attributes']['title'] = $item['description'];
      }
      if ($in_active_trail) {
        $item['attributes']['class'] = 'active-trail';
      }
      while ($item['type'] & MENU_LINKS_TO_PARENT) {

        // Weirdness in D5's menu system
        $link_item = menu_get_item($item['pid']);
        $item['path'] = $link_item['path'];
      }
      $link = theme('menu_block_item_link', $item);

      // Theme the menu tree containing the children
      $has_children = !empty($menu['visible'][$mid]['children']);
      $children = '';
      if ($has_children) {
        $type = isset($menu['visible'][$mid]['type']) ? $menu['visible'][$mid]['type'] : FALSE;
        if ($depth_limit != 1 && ($type & MENU_EXPANDED || $expanded || $in_active_trail)) {
          $children = theme('menu_block_tree', $mid, $depth_limit ? $depth_limit - 1 : 0, $expanded);
        }
      }

      // Theme the menu item
      $extra_class = "menu-{$mid}";
      $extra_class .= $count == 1 ? ' first' : '';
      $extra_class .= $count == $total_children ? ' last' : '';
      $extra_class .= $mid == $active_id || $item['path'] == '<front>' && drupal_is_front_page() ? ' active' : '';
      $output .= theme('menu_block_item', $link, $has_children, $children, $in_active_trail, $extra_class);
      $count++;
    }
  }
  return $output;
}

/**
 * Generate the HTML output for a single menu link.
 *
 * @ingroup themeable
 *
 * @param $link
 *   array The menu item to render.
 * @return
 *   string The rendered menu link.
 */
function theme_menu_block_item_link($link) {
  if (empty($link['attributes'])) {
    $link['attributes'] = array();
  }
  return l($link['title'], $link['path'], $link['attributes'], isset($link['query']) ? $link['query'] : NULL);
}

/**
 * Generate the HTML output for a menu item and submenu.
 *
 * @ingroup themeable
 */
function theme_menu_block_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
  $class = $menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf');
  if (!empty($extra_class)) {
    $class .= ' ' . $extra_class;
  }
  if ($in_active_trail) {
    $class .= ' active-trail';
  }
  return '<li class="' . $class . '">' . $link . $menu . "</li>";
}

Functions

Namesort descending Description
menu_block_add_block_form Menu callback: display the menu block addition form.
menu_block_block Implements hook_block().
menu_block_delete Menu callback: confirm deletion of menu blocks.
menu_block_form_alter Alters the block admin form to add delete links next to menu blocks.
menu_block_help Implements hook_help().
menu_block_menu Implements hook_menu().
menu_block_tree Returns a rendered menu tree or menu list.
theme_menu_block_item Generate the HTML output for a menu item and submenu.
theme_menu_block_item_link Generate the HTML output for a single menu link.
theme_menu_block_tree Generate the HTML for a menu tree.
_menu_block_block_view Returns the 'view' $op info for hook_block().
_menu_block_by_module_hack This page is simply to make Menu block visible on admin pages.