advanced_menu_submenu.module in Advanced Menu 7
Provides advanced menu submenus.
File
submenu/advanced_menu_submenu.moduleView source
<?php
// $Id: advanced_menu_submenu.module $
/**
* @file
* Provides advanced menu submenus.
*/
/**
* Implementation of hook_permission().
*/
function advanced_menu_submenu_permission() {
return array(
'use sub menus' => array(
'title' => t('Use Sub Menus'),
'description' => t('Allow menus to be embedded within other menus.'),
),
);
}
/**
* Implements hook_menu().
*/
function advanced_menu_submenu_menu() {
$items['admin/structure/menu/manage/%menu/add-submenu'] = array(
'title' => 'Add submenu',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'menu_edit_item',
'add',
NULL,
4,
),
'access arguments' => array(
'use sub menus',
),
'type' => MENU_LOCAL_ACTION,
'file' => 'menu.admin.inc',
'file path' => drupal_get_path('module', 'menu'),
);
$items['advanced-menus/sub-menus/%menu'] = array(
'title' => 'Sub Menus',
'access callback' => TRUE,
'page callback' => '_advanced_menu_submenu_callback',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implementation of hook_form_alter().
*/
function advanced_menu_submenu_form_alter(&$form, $form_state, $form_id) {
switch ($form_id) {
case 'menu_edit_item':
$url_comp = explode('/', request_path());
$url_action = array_pop($url_comp);
$url_menu = array_pop($url_comp);
$default_value = NULL;
if ($url_action == 'add-submenu' || substr($form['link_path']['#default_value'], 0, 24) == "advanced-menus/sub-menus") {
if (substr($form['link_path']['#default_value'], 0, 24) == "advanced-menus/sub-menus") {
$url_menu = $form['original_item']['#value']['menu_name'];
$default_value = $form['link_path']['#default_value'];
}
$form['link_title'] = array(
'#type' => 'hidden',
'#value' => 'Sub-Menu',
'#required' => FALSE,
);
$menus = _advanced_menu_submenu_menus($url_menu, $default_value);
$options = array();
foreach ($menus as $key => $value) {
$options['advanced-menus/sub-menus/' . $key] = $value;
}
$form['link_path'] = array(
'#type' => 'select',
'#title' => t('Sub Menu'),
'#options' => $options,
'#description' => t('The menu to include as a sub menu.'),
'#attributes' => array(
'class' => array(
'menu-title-select',
),
),
);
if (!empty($default_value)) {
$form['link_path']['#default_value'] = $default_value;
}
$form['description'] = array(
'#type' => 'hidden',
);
$form['expanded'] = array(
'#type' => 'hidden',
'#value' => 0,
);
}
break;
}
}
/**
* Implements hook_block_view_alter().
*/
function advanced_menu_submenu_block_view_alter(&$data, $block) {
global $user, $language;
$system_menus = array(
'navigation',
'management',
'user-menu',
'main-menu',
);
if ($block->module == 'superfish') {
list($menu_name, $mlid) = explode(':', variable_get('superfish_menu_' . $block->delta, 'main-menu:0'));
$cache_key = 'links:' . $menu_name . ':all-cid:' . $mlid . ':' . $user->uid . ':' . $language->language;
_advanced_menu_submenu_cache($cache_key);
$data = superfish_contents($block->delta);
}
if (in_array($block->delta, $system_menus) && $block->module == 'system' || ($block->module == 'menu' || $block->module == 'menu_block')) {
$new_content = array();
$orig_content = $data['content'];
if ($block->module == 'menu_block') {
$orig_content = $data['content']['#content'];
}
foreach ($orig_content as $key => $item) {
if (is_numeric($key)) {
$new_data = _advanced_menu_submenu_trees($item);
if ($new_data != $orig_content[$key]) {
$orig_content[$key] = $new_data;
if (is_array($new_data)) {
$new_content = array_merge($new_content, $new_data);
}
else {
$new_content[$key] = $new_data;
}
}
else {
$new_content[$key] = $item;
}
}
else {
$new_content[$key] = $item;
}
}
if ($block->module == 'menu_block') {
$data['content']['#content'] = $new_content;
}
else {
$data['content'] = $new_content;
}
}
}
/**
* Implements hook_menu_link_alter().
*/
function advanced_menu_submenu_menu_link_alter(&$item) {
$original_path = explode('/', $item['link_path']);
$alter_path = array_pop($original_path);
$original_path = implode('/', $original_path);
if ($original_path == 'advanced-menus/sub-menus') {
$query = db_select('menu_custom', 'm')
->fields('m', array(
'title',
))
->condition('menu_name', $alter_path)
->execute()
->fetchAssoc();
$item['link_title'] = 'Submenu : ' . $query['title'];
}
}
/**
* Helper function to update menu cache for block display.
*/
function _advanced_menu_submenu_cache($cache_key) {
$cache = cache_get($cache_key, 'cache_menu');
if ($cache && isset($cache->data)) {
//Update the menu cache if needed.
foreach ($cache->data['menu'] as $key => $menu) {
$cache->data['menu'][$key] = _advanced_menu_submenu_cache_recursive($menu);
}
cache_set($cache_key, $cache->data, 'cache_menu');
}
else {
//Build the menu cache.
$cache = array();
$cache['menu'] = menu_tree_all_data($menu_name);
foreach ($cache['menu'] as $key => $menu) {
$cache['menu'][$key] = _advanced_menu_submenu_cache_recursive($menu);
}
cache_set($cache_key, $cache, 'cache_menu');
}
}
/**
* Recursive helper function for menu cache.
*/
function _advanced_menu_submenu_cache_recursive($menu_item) {
$new_items = $menu_item;
if (isset($menu_item['link']) && $menu_item['link']['router_path'] == 'advanced-menus/sub-menus/%') {
$original_path = explode('/', $menu_item['link']['link_path']);
$alter_path = array_pop($original_path);
$original_path = implode('/', $original_path);
$new_items = menu_tree_all_data($alter_path);
}
if (isset($new_items['below'])) {
$below = array();
foreach ($new_items['below'] as $key => $menu) {
if (isset($menu['link']) && $menu['link']['router_path'] == 'advanced-menus/sub-menus/%') {
$below = _advanced_menu_submenu_cache_recursive($menu);
}
}
if (!empty($below)) {
$new_items['below'] = $below;
}
}
return $new_items;
}
/**
* Helper function to build out sub-menus for block display.
*/
function _advanced_menu_submenu_trees($item) {
$new_items = $item;
$alter_path = '';
if (is_array($new_items)) {
if (isset($item['#original_link']) && $item['#original_link']['router_path'] == 'advanced-menus/sub-menus/%') {
$original_path = explode('/', $item['#original_link']['link_path']);
$alter_path = array_pop($original_path);
$original_path = implode('/', $original_path);
$new_items = menu_tree($alter_path);
foreach ($new_items as $key => $new_item) {
$new_items[$key] = _advanced_menu_submenu_trees($new_item);
}
}
if (!empty($new_items['#below'])) {
foreach ($new_items['#below'] as $key => $below) {
$new_data = _advanced_menu_submenu_trees($below);
if (is_array($new_data)) {
if (isset($new_items['#below'][$key]['#original_link']) && $new_items['#below'][$key]['#original_link']['router_path'] == 'advanced-menus/sub-menus/%') {
unset($new_items['#below'][$key]);
}
$new_items['#below'] = array_merge($new_items['#below'], $new_data);
}
else {
$new_items['#below'][$key] = $new_data;
}
if (is_array($new_data) && _advanced_menu_submenu_is_active($new_data)) {
$new_items['#attributes']['class'][] = 'active-trail';
$new_items['#localized_options']['attributes']['class'][] = 'active-trail';
}
}
}
}
return $new_items;
}
/**
* Helper function to determine if the given items are in the active menu path.
*/
function _advanced_menu_submenu_is_active($new_item) {
$is_active = FALSE;
foreach ($new_item as $item) {
if (is_array($item)) {
if (isset($item['#original_link']) && $item['#original_link']['in_active_trail'] == 1) {
$is_active = TRUE;
}
}
}
return $is_active;
}
/**
* Helper function to determine what menus can be linked to from a given menu.
*/
function _advanced_menu_submenu_menus($menu, $default_value = NULL) {
//Load available menus.
if (module_exists('advanced_menu_menu_admin')) {
$menus = _advanced_menu_menu_admin_menus();
}
else {
$menus = menu_get_menus();
}
$exclude_menus = _advanced_menu_submenu_cycle($menu, $default_value);
//Remove menus which would create a circular reference.
foreach ($exclude_menus as $key => $value) {
unset($menus[$value]);
}
if (empty($menus)) {
drupal_set_message('No eligible sub menus were found.', 'warning');
}
return $menus;
}
/**
* Recursive Helper function to cycle through the menus and determine what links where.
*/
function _advanced_menu_submenu_cycle($menu, $default_value = NULL) {
$menus = array();
$menus[$menu] = $menu;
$query = db_select('menu_links', 'm')
->fields('m', array(
'menu_name',
))
->condition('link_path', 'advanced-menus/sub-menus/' . $menu, '=')
->execute();
if ($query) {
while ($record = $query
->fetchAssoc()) {
$p_menus = _advanced_menu_submenu_cycle($record['menu_name']);
$menus = array_merge($menus, $p_menus);
}
}
if (!empty($default_value)) {
$query = db_select('menu_links', 'm')
->fields('m', array(
'link_path',
))
->condition('link_path', 'advanced-menus/sub-menus/%', 'LIKE')
->condition('link_path', $default_value, '!=')
->condition('menu_name', $menu, '=')
->execute();
if ($query) {
while ($record = $query
->fetchAssoc()) {
$p_path = explode('/', $record['link_path']);
$p_menu = array_pop($p_path);
$p_menus = array(
$p_menu,
);
$menus = array_merge($menus, $p_menus);
}
}
}
return $menus;
}
function _advanced_menu_submenu_callback() {
drupal_goto('<front>');
}
Functions
Name | Description |
---|---|
advanced_menu_submenu_block_view_alter | Implements hook_block_view_alter(). |
advanced_menu_submenu_form_alter | Implementation of hook_form_alter(). |
advanced_menu_submenu_menu | Implements hook_menu(). |
advanced_menu_submenu_menu_link_alter | Implements hook_menu_link_alter(). |
advanced_menu_submenu_permission | Implementation of hook_permission(). |
_advanced_menu_submenu_cache | Helper function to update menu cache for block display. |
_advanced_menu_submenu_cache_recursive | Recursive helper function for menu cache. |
_advanced_menu_submenu_callback | |
_advanced_menu_submenu_cycle | Recursive Helper function to cycle through the menus and determine what links where. |
_advanced_menu_submenu_is_active | Helper function to determine if the given items are in the active menu path. |
_advanced_menu_submenu_menus | Helper function to determine what menus can be linked to from a given menu. |
_advanced_menu_submenu_trees | Helper function to build out sub-menus for block display. |