View source
<?php
define('MENU_TREE__CURRENT_PAGE_MENU', '_active');
function menu_block_menu() {
$items['admin/build/block/add-menu-block'] = array(
'title' => 'Add menu block',
'description' => 'Add a new menu block.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'menu_block_add_block_form',
),
'access arguments' => array(
'administer blocks',
),
'type' => MENU_LOCAL_TASK,
'file' => 'menu_block.admin.inc',
);
$items['admin/build/block/delete-menu-block'] = array(
'title' => 'Delete menu block',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'menu_block_delete',
),
'access arguments' => array(
'administer blocks',
),
'type' => MENU_CALLBACK,
'file' => 'menu_block.admin.inc',
);
$items['admin/settings/menu_block'] = array(
'title' => 'Menu block',
'description' => 'Configure menu block.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'menu_block_admin_settings_form',
),
'access arguments' => array(
'administer blocks',
),
'type' => MENU_NORMAL_ITEM,
'file' => 'menu_block.admin.inc',
);
return $items;
}
function menu_block_help($path, $arg) {
switch ($path) {
case 'admin/build/block/configure':
if ($arg[4] != 'menu_block') {
break;
}
case 'admin/help#menu_block':
case 'admin/build/block':
case 'admin/build/block/add-menu-block':
module_load_include('inc', 'menu_block', 'menu_block.pages');
return _menu_block_help($path, $arg);
}
}
function menu_block_theme(&$existing, $type, $theme, $path) {
$existing['menu_tree']['pattern'] = 'menu_tree__';
$existing['menu_item']['pattern'] = 'menu_item__';
$existing['menu_item_link']['pattern'] = 'menu_item_link__';
return array(
'menu_block_wrapper' => array(
'template' => 'menu-block-wrapper',
'arguments' => array(
'content' => NULL,
'settings' => NULL,
'delta' => NULL,
),
'pattern' => 'menu_block_wrapper__',
),
'menu_block_menu_order' => array(
'arguments' => array(
'element' => NULL,
),
'file' => 'menu_block.admin.inc',
),
);
}
function menu_block_ctools_plugin_directory($module, $plugin) {
if ($plugin == 'content_types') {
return 'plugins/' . $plugin;
}
}
function template_preprocess_menu_block_wrapper(&$variables) {
$variables['classes_array'][] = 'menu-block-' . $variables['delta'];
$variables['classes_array'][] = 'menu-name-' . $variables['settings']['menu_name'];
$variables['classes_array'][] = 'parent-mlid-' . $variables['settings']['parent_mlid'];
$variables['classes_array'][] = 'menu-level-' . $variables['settings']['level'];
$variables['classes'] = check_plain(implode(' ', $variables['classes_array']));
$variables['template_files'][] = 'menu-block-wrapper-' . $variables['settings']['menu_name'];
}
function menu_block_form_block_admin_display_form_alter(&$form, $form_state) {
module_load_include('inc', 'menu_block', 'menu_block.admin');
_menu_block_form_block_admin_display_form_alter($form, $form_state);
}
function menu_block_get_all_menus() {
static $all_menus;
if (!$all_menus) {
if ($cached = cache_get('menu_block_menus', 'cache_menu')) {
$all_menus = $cached->data;
}
else {
$all_menus = menu_get_menus();
$all_menus = array_merge($all_menus, module_invoke_all('menu_block_get_menus'));
$all_menus[MENU_TREE__CURRENT_PAGE_MENU] = '<' . t('the menu selected by the page') . '>';
asort($all_menus);
cache_set('menu_block_menus', $all_menus, 'cache_menu');
}
}
return $all_menus;
}
function menu_block_block($op = 'list', $delta = NULL, $edit = NULL) {
$function = '_menu_block_block_' . $op;
if (function_exists($function)) {
return $function($delta, $edit);
}
else {
module_load_include('inc', 'menu_block', 'menu_block.admin');
if (function_exists($function)) {
return $function($delta, $edit);
}
}
}
function menu_block_get_config($delta = NULL) {
$config = array(
'delta' => $delta,
'menu_name' => 'primary-links',
'parent_mlid' => 0,
'title_link' => 0,
'admin_title' => '',
'level' => 1,
'follow' => 0,
'depth' => 0,
'expanded' => 0,
'sort' => 0,
);
if ($delta) {
$config['title_link'] = variable_get("menu_block_{$delta}_title_link", $config['title_link']);
$config['admin_title'] = variable_get("menu_block_{$delta}_admin_title", $config['admin_title']);
$config['level'] = variable_get("menu_block_{$delta}_level", $config['level']);
$config['follow'] = variable_get("menu_block_{$delta}_follow", $config['follow']);
$config['depth'] = variable_get("menu_block_{$delta}_depth", $config['depth']);
$config['expanded'] = variable_get("menu_block_{$delta}_expanded", $config['expanded']);
$config['sort'] = variable_get("menu_block_{$delta}_sort", $config['sort']);
list($config['menu_name'], $config['parent_mlid']) = explode(':', variable_get("menu_block_{$delta}_parent", $config['menu_name'] . ':' . $config['parent_mlid']));
}
return $config;
}
function _menu_block_block_view($delta) {
return menu_tree_build(menu_block_get_config($delta));
}
function menu_tree_build($config) {
if ($config['menu_name'] == MENU_TREE__CURRENT_PAGE_MENU) {
$menu_order = variable_get('menu_block_menu_order', array(
'primary-links' => '',
'secondary-links' => '',
));
$patterns = array();
foreach (array_keys($menu_order) as $pattern) {
if ($pattern[0] == '/') {
$patterns[$pattern] = NULL;
}
}
$result = db_query("SELECT menu_name FROM {menu_links} WHERE link_path = '%s'", $_GET['q'] ? $_GET['q'] : '<front>');
while ($item = db_fetch_array($result)) {
if (isset($menu_order[$item['menu_name']])) {
$menu_order[$item['menu_name']] = MENU_TREE__CURRENT_PAGE_MENU;
}
else {
foreach (array_keys($patterns) as $pattern) {
if (preg_match($pattern, $item['menu_name'])) {
$menu_order[$pattern] = MENU_TREE__CURRENT_PAGE_MENU;
$patterns[$pattern] = $item['menu_name'];
}
}
}
}
$config['menu_name'] = array_search(MENU_TREE__CURRENT_PAGE_MENU, $menu_order);
if (!empty($patterns[$config['menu_name']])) {
$config['menu_name'] = $patterns[$config['menu_name']];
}
$config['parent_mlid'] = 0;
if (empty($config['menu_name'])) {
return array();
}
}
$menu_names = menu_block_get_all_menus();
menu_block_set_title(t($menu_names[$config['menu_name']]));
if ($config['expanded'] || $config['parent_mlid']) {
$tree = menu_tree_all_data($config['menu_name']);
menu_tree_add_active_path($tree);
}
else {
$tree = menu_tree_page_data($config['menu_name']);
}
$alter_data =& $tree;
$alter_data['__drupal_alter_by_ref'] = array(
&$config,
);
drupal_alter('menu_block_tree', $alter_data);
if (module_exists('i18nmenu')) {
i18nmenu_localize_tree($tree);
}
if ($config['level'] > 1 || $config['parent_mlid']) {
if ($config['parent_mlid']) {
$parent_item = menu_link_load($config['parent_mlid']);
menu_tree_prune_tree($tree, $config['level'], $parent_item);
}
else {
menu_tree_prune_tree($tree, $config['level']);
}
}
if ($config['follow']) {
menu_tree_prune_active_tree($tree, $config['follow']);
}
if ($config['parent_mlid'] && !$config['expanded']) {
menu_tree_trim_active_path($tree);
}
if ($config['depth'] > 0) {
menu_tree_depth_trim($tree, $config['depth']);
}
if ($config['sort']) {
menu_tree_sort_active_path($tree);
}
$data = array();
$data['subject'] = menu_block_get_title($config['title_link'], $config);
$data['content'] = menu_block_tree_output($tree, $config);
if ($data['content']) {
$hooks = array();
$hooks[] = 'menu_block_wrapper__' . str_replace('-', '_', $config['delta']);
$hooks[] = 'menu_block_wrapper__' . str_replace('-', '_', $config['menu_name']);
$hooks[] = 'menu_block_wrapper';
$data['content'] = theme($hooks, $data['content'], $config, $config['delta']);
}
return $data;
}
function menu_block_get_title($render_title_as_link = TRUE, $config = array()) {
$menu_item = menu_block_set_title();
if (is_string($menu_item)) {
$title = check_plain($menu_item);
}
elseif ($render_title_as_link) {
if (!empty($menu_item['in_active_trail'])) {
if (!empty($menu_item['localized_options']['attributes']['class'])) {
$menu_item['localized_options']['attributes']['class'] .= ' active-trail';
}
else {
$menu_item['localized_options']['attributes']['class'] = 'active-trail';
}
}
$hooks = array();
if (!empty($config['delta'])) {
$hooks[] = 'menu_item_link__menu_block__' . str_replace('-', '_', $config['delta']);
}
$hooks[] = 'menu_item_link__menu_block__' . str_replace('-', '_', $menu_item['menu_name']);
$hooks[] = 'menu_item_link__menu_block';
$hooks[] = 'menu_item_link';
$title = theme($hooks, $menu_item);
}
else {
$title = check_plain($menu_item['title']);
}
return $title;
}
function menu_block_set_title($item = NULL) {
static $menu_item;
if (!is_null($item)) {
$menu_item = $item;
}
return $menu_item;
}
function menu_tree_add_active_path(&$tree) {
$menu_item = current($tree);
$tree_with_trail = menu_tree_page_data($menu_item['link']['menu_name']);
$subtree_pointer =& $tree;
while ($tree_with_trail) {
foreach (array_keys($tree_with_trail) as $key) {
if ($tree_with_trail[$key]['link']['in_active_trail']) {
$subtree_pointer[$key]['link']['in_active_trail'] = TRUE;
$tree_with_trail =& $tree_with_trail[$key]['below'];
$subtree_pointer =& $subtree_pointer[$key]['below'];
break;
}
else {
unset($tree_with_trail[$key]);
}
}
}
}
function menu_tree_trim_active_path(&$tree) {
foreach (array_keys($tree) as $key) {
if (($tree[$key]['link']['in_active_trail'] || $tree[$key]['link']['expanded']) && $tree[$key]['below']) {
menu_tree_trim_active_path($tree[$key]['below']);
}
else {
$tree[$key]['below'] = FALSE;
}
}
}
function menu_tree_sort_active_path(&$tree) {
module_load_include('inc', 'menu_block', 'menu_block.sort');
_menu_tree_sort_active_path($tree);
}
function menu_tree_prune_tree(&$tree, $level, $parent_item = FALSE) {
if (!empty($parent_item)) {
for ($i = 1; $i <= MENU_MAX_DEPTH && $parent_item["p{$i}"] != '0'; $i++) {
$plid = $parent_item["p{$i}"];
$found_active_trail = FALSE;
foreach (array_keys($tree) as $key) {
if ($tree[$key]['link']['mlid'] == $plid) {
menu_block_set_title($tree[$key]['link']);
$tree = $tree[$key]['below'] ? $tree[$key]['below'] : array();
$found_active_trail = TRUE;
break;
}
}
if (!$found_active_trail) {
$tree = array();
break;
}
}
}
for ($i = 1; $i < $level; $i++) {
$found_active_trail = FALSE;
foreach (array_keys($tree) as $key) {
if ($tree[$key]['link']['in_active_trail']) {
menu_block_set_title($tree[$key]['link']);
$tree = $tree[$key]['below'] ? $tree[$key]['below'] : array();
$found_active_trail = TRUE;
break;
}
}
if (!$found_active_trail) {
$tree = array();
break;
}
}
}
function menu_tree_prune_active_tree(&$tree, $level) {
module_load_include('inc', 'menu_block', 'menu_block.follow');
_menu_tree_prune_active_tree($tree, $level);
}
function menu_tree_depth_trim(&$tree, $depth_limit) {
if ($depth_limit < 1) {
return;
}
foreach (array_keys($tree) as $key) {
if ($tree[$key]['below']) {
if ($depth_limit > 1) {
menu_tree_depth_trim($tree[$key]['below'], $depth_limit - 1);
}
else {
$tree[$key]['below'] = FALSE;
}
}
if ($depth_limit == 1 && $tree[$key]['link']['has_children']) {
$tree[$key]['link']['has_children'] = FALSE;
$tree[$key]['link']['leaf_has_children'] = TRUE;
}
}
}
function menu_block_tree_output(&$tree, $config = array()) {
$output = '';
$items = array();
if (empty($config)) {
$config['delta'] = 0;
$menu_item = current($tree);
$config['menu_name'] = $menu_item['link']['menu_name'];
}
$hook_delta = str_replace('-', '_', $config['delta']);
$hook_menu_name = str_replace('-', '_', $config['menu_name']);
foreach (array_keys($tree) as $key) {
if (!$tree[$key]['link']['hidden']) {
$items[$key] = array(
'link' => $tree[$key]['link'],
'below' => !empty($tree[$key]['below']) ? menu_block_tree_output($tree[$key]['below'], $config) : '',
);
}
}
$num_items = count($items);
$i = 1;
foreach (array_keys($items) as $key) {
$link_class = array();
if (!empty($items[$key]['link']['localized_options']['attributes']['class'])) {
$link_class[] = $items[$key]['link']['localized_options']['attributes']['class'];
}
if ($items[$key]['link']['in_active_trail']) {
$link_class[] = 'active-trail';
}
if (!empty($link_class)) {
$items[$key]['link']['localized_options']['attributes']['class'] = implode(' ', $link_class);
}
$hooks = array();
$hooks[] = 'menu_item_link__menu_block__' . $hook_delta;
$hooks[] = 'menu_item_link__menu_block__' . $hook_menu_name;
$hooks[] = 'menu_item_link__menu_block';
$hooks[] = 'menu_item_link';
$link = theme($hooks, $items[$key]['link']);
$extra_class = array();
if ($i == 1) {
$extra_class[] = 'first';
}
if ($i == $num_items) {
$extra_class[] = 'last';
}
$extra_class[] = 'menu-mlid-' . $items[$key]['link']['mlid'];
if (!empty($items[$key]['link']['leaf_has_children'])) {
$extra_class[] = 'has-children';
}
if ($items[$key]['link']['href'] == $_GET['q'] || $items[$key]['link']['href'] == '<front>' && drupal_is_front_page()) {
$extra_class[] = 'active';
}
$extra_class = !empty($extra_class) ? implode(' ', $extra_class) : NULL;
$hooks = array();
$hooks[] = 'menu_item__menu_block__' . $hook_delta;
$hooks[] = 'menu_item__menu_block__' . $hook_menu_name;
$hooks[] = 'menu_item__menu_block';
$hooks[] = 'menu_item';
$output .= theme($hooks, $link, $items[$key]['link']['has_children'], $items[$key]['below'], $items[$key]['link']['in_active_trail'], $extra_class);
$i++;
}
$hooks = array();
$hooks[] = 'menu_tree__menu_block__' . $hook_delta;
$hooks[] = 'menu_tree__menu_block__' . $hook_menu_name;
$hooks[] = 'menu_tree__menu_block';
$hooks[] = 'menu_tree';
return $output ? theme($hooks, $output) : '';
}
function book_menu_block_get_menus() {
$menus = array();
foreach (book_get_books() as $book) {
$menus[$book['menu_name']] = $book['title'];
}
return $menus;
}
function book_menu_block_get_sort_menus() {
return array(
'/^book\\-toc\\-.+/' => t('Book navigation'),
);
}