Add system menu's to a Taxonomy Menu Block. Each menu item is checked for access and the altered tree gets cached. UPDATE: If the current node isn't part of the tree, the active trail is still set UPDATE2: Implemented the_aim_taxonomy_menu_block_alter_theme_registry_alter(&$theme_registry) to override the theming
<?php
/**
* @file the_aim_taxonomy_menu_block_alter
*
* @description
* Add the menu items of main-menu to the taxonomy menu block called main-menu
**/
// Define the TMB to be altered as an serialized array like
// array(vid => array(tbm-delta => array(system-menu, system-menu))).
define(
'TMB_ALTER', serialize(
array(
2 => array(
1 => array('main-menu'),
3 => array('main-menu', 'secondary-menu'),
),
)
)
);
define('TMB_ALTER_CLASSES', TRUE);
/**
* Implements hook_taxonomy_menu_block_alter().
*
* Alters the taxonomy menu block data.
**/
function the_aim_taxonomy_menu_block_alter_taxonomy_menu_block_alter(&$tree, $config) {
foreach (unserialize(TMB_ALTER) as $vid => $deltas) {
if ($config['vid'] == $vid) {
foreach ($deltas as $delta => $system_menus) {
// Alter the output of the specified taxonomy menu block.
if($config['delta'] == $delta) {
// Get the language object
global $language;
// If the active page is a node, get the object for setting the active trail.
$obj = new stdClass();
if(arg(0) == 'node') {
$obj = menu_get_object();
// Find parents
$parent_candidates = _the_aim_mtbp_get_parent_candidates(drupal_get_path_alias());
// Don't even bother if current page is root
if (!empty($parent_candidates)) {
// Find link items matching the parent candidates in all menus
$matched_menus = array();
$matched_link_titles = array();
$results = db_select('menu_links', 'ml')
->fields('ml', array('link_path'))
->condition('link_path', $parent_candidates, 'IN')
->execute()->fetchCol();
if(!empty($results)) {
$obj->the_aim_mtbp = $results;
}
}
}
// Add each system menu to the tmb
foreach($system_menus as $system_menu) {
// Get the build info from the system menu.
$menu_build = _menu_build_tree($system_menu);
$menu_build['menu_links'] = array();
// Add the menu link ids and their weights
foreach ($menu_build['tree'] as $mlid => $mitem) {
if (isset($mitem['link']['weight'])) {
$menu_build['menu_links'][$mlid] = $mitem['link']['weight'];
}
}
// Sort the menu links by their weight
asort($menu_build['menu_links'], SORT_NUMERIC);
// BYPASS THE CHECK ACCESS, RELATED ISSUE https://drupal.org/node/1697570
// // Check access for the current user to each item in the tree.
// menu_tree_check_access($menu_build['tree'], $menu_build['node_links']);
// Transform the menu items into tmb menu items.
foreach ($menu_build['menu_links'] as $mlid => $weight) {
$menu_item = $menu_build['tree'][$mlid];
// For multilingual menu's, check the menu item's language
if(isset($menu_item['link']['language'])) {
if($menu_item['link']['language'] == $language->language) {
the_aim_taxonomy_menu_block_alter_tmb_transform_menu_item($menu_item, $tree, $menu_build, 0, $config['depth'], $obj);
}
}
else {
the_aim_taxonomy_menu_block_alter_tmb_transform_menu_item($menu_item, $tree, $menu_build, 0, $config['depth'], $obj);
}
}
}
}
}
}
}
}
/**
* Transform a regular menu item to a tmb menu item.
**/
function the_aim_taxonomy_menu_block_alter_tmb_transform_menu_item($menu_item, &$tree, $menu_build, $depth = 0, $max_depth = 8, $obj) {
// Set the menu item's parent
$parents = array('0');
if (isset($menu_build['menu_links'][$menu_item['link']['plid']])) {
$parents[0] = 'main_menu_mlid_' . $menu_item['link']['plid'];
}
// Set the active trail
$active_trail = 0;
// If the active item is a node, check if this menu item matches it.
if (isset($obj->nid)) {
if ($menu_item['link']['link_path'] == 'node/' . $obj->nid) {
// Setting the active trail to 2 gives the list item the class active.
$active_trail = 2;
// If the item has a parent, add the active-trail class
if($parents[0] <> 0) {
the_aim_taxonomy_menu_block_alter_tbm_active_trail($menu_build['node_links'][$menu_item['link']['plid']], $tree);
}
}
elseif (isset($obj->the_aim_mtbp) && in_array($menu_item['link']['link_path'], $obj->the_aim_mtbp)) {
$active_trail = 1;
}
}
// Create the new tmb menu item
$tree['main_menu_mlid_'.$menu_item['link']['mlid']] = array(
'name' => $menu_item['link']['link_title'],
'path' => drupal_get_path_alias($menu_item['link']['link_path']),
'depth' => $depth++,
'parents' => $parents,
'active_trail' => $active_trail,
);
// Add system menu class
if (TMB_ALTER_CLASSES) {
$tree['main_menu_mlid_'.$menu_item['link']['mlid']]['attributes'] = array(
'class' => array($menu_item['link']['menu_name'] . '-item'),
);
}
// Create the deeper levels if the maximum depth is not reached.
if(!empty($menu_item['below']) && $depth < $max_depth) {
foreach ($menu_item['below'] as $child_menu_item) {
the_aim_taxonomy_menu_block_alter_tmb_transform_menu_item($child_menu_item, $tree, $menu_build, $depth, $max_depth, $obj);
}
}
}
/**
* Set the parents active trail.
**/
function the_aim_taxonomy_menu_block_alter_tbm_active_trail($parent, &$tree) {
// Setting active trail to 1 gives the list class the class active-trail.
$tree[$parent]['active_trail'] = 1;
// Prevent the top level from going deeper
if($tree[$parent]['parents'][0] <> 0) {
the_aim_taxonomy_menu_block_alter_tbm_active_trail($tree[$parent]['parents'][0], $tree);
}
}
/**
* Implement hook_theme_registry_alter().
*/
function the_aim_taxonomy_menu_block_alter_theme_registry_alter(&$theme_registry) {
$theme_registry['taxonomy_menu_block']['function'] = 'theme_the_aim_taxonomy_menu_block_alter';
$theme_registry['taxonomy_menu_block']['theme path'] = drupal_get_path('module', 'the_aim_taxonomy_menu_block_alter');
}
function theme_the_aim_taxonomy_menu_block_alter($variables) {
$tree = $variables['items'];
$config = $variables['config'];
$num_items = count($tree);
$i = 0;
$output = '<ul>';
foreach ($tree as $tid => $term) {
$i++;
// Add classes.
$attributes = array();
$link_attributes = array();
if (isset($term['attributes'])) {
$attributes += $term['attributes'];
}
if ($i == 1) {
$attributes['class'][] = 'first';
}
if ($i == $num_items) {
$attributes['class'][] = 'last';
}
if ($term['active_trail'] == '1') {
$attributes['class'][] = 'active-trail';
$link_attributes['class'][] = 'active-trail';
}
if ($term['active_trail'] == '2') {
$attributes['class'][] = 'active';
$link_attributes['class'][] = 'active';
}
$attributes['class'][] = ($i%2) ? 'odd' : 'even';
// Alter link text if we have to display the nodes attached.
if (isset($term['nodes'])) {
$term['name'] = $term['name'] . ' (' . $term['nodes'] . ')';
}
// Set alias option to true so we don't have to query for the alias every
// time, as this is cached anyway.
$output .= '<li' . drupal_attributes($attributes) . '>';
$output .= l($term['name'], $term['path'], array('alias' => TRUE, 'attributes' => $link_attributes));
if (!empty($term['children'])) {
$output .= theme('taxonomy_menu_block__' . $config['delta'], (array('items' => $term['children'], 'config' => $config)));
}
$output .= '</li>';
}
$output .= '</ul>';
return $output;
}
name = the AIM taxonomy menu block alter
description = Add system menus to a taxonomy menu block
core = 7.x
package = the AIM
dependencies[] = taxonomy_menu_block
dependencies[] = the_aim_mtbp
version = 7.x-1.0