...
 
Commits (32)
image: php:5.6
variables:
DB_URL: 'mysql://root@127.0.0.1/db_drulenium'
drulenium:
before_script:
# Install git, the php image doesn't have it installed
# jq for parsing JSON
- apt-get update -yqq
- apt-get install default-jre -yqq # Immediately after apt-get update to avoid E: Failed to fetch http://httpredir.debian.org/debian/pool/mai
- apt-get install git wget jq -yqq
# Installing firefox browser
- apt-get install xvfb iceweasel unzip -yqq
- Xvfb :99 -ac &
- export DISPLAY=:99
# - firefox -v
# Firefox version 45.2.0 working with selenium-server-standalone-2.53.0
# Installing selenium
- wget http://selenium-release.storage.googleapis.com/2.53/selenium-server-standalone-2.53.0.jar
- java -jar selenium-server-standalone-2.53.0.jar &
# Installing MySQL server
- export DEBIAN_FRONTEND=noninteractive
- apt-get install mysql-server -yqq
# Installing imagemagick & PHP GD extension
- apt-get install libfreetype6-dev libjpeg62-turbo-dev libpng12-dev imagemagick -yqq
- docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
- docker-php-ext-install gd
## Installing drush
# Install composer dependencies
- curl -sS https://getcomposer.org/installer | php
- php composer.phar global require drush/drush:6.*
- export PATH="$HOME/.composer/vendor/bin:$PATH"
script:
- drush dl drupal-7 --drupal-project-rename=docroot
- cd docroot
- service mysql start
- drush site-install minimal --db-url=$DB_URL --site-name=Drulenium --account-name=admin --account-pass=admin --yes
# Start server
- drush runserver --server=builtin 8080 > /dev/null 2>&1 &
- drush dl drulenium -y
- drush en libraries -y
- drush en drulenium drulenium_local_selenium drulenium_hosting_client -y
- drush vr-download-webdriver
- drush vset --yes drulenium_vr_config_server_opt 'drulenium_local_selenium'
- drush vset --yes drulenium_vr_config_image_server_opt 'drulenium_local_selenium'
- drush vset --yes drulenium_vr_release_imagemagick_path '/usr/bin'
- drush vset --yes drulenium_vr_release_selenium_browser_width $BROWSER_WIDTH
- drush vset --yes drulenium_vr_release_selenium_browser_height $BROWSER_HEIGHT
# Test as admin user
- drush vset --yes drulenium_vr_release_user_name 'admin' -q
- drush vset --yes drulenium_vr_release_user_pass 'admin' -q
# Set admin theme for responsive widths
- drush vset admin_theme seven
# Uncomment below lines if you want to dynamically pull the test cases from the project on http://drulenium.org/
- export TEST_PAGES=$(echo `wget -O- http://drulenium.org/api/v1/project/$DRULENIUM_ORG_PROJECT_UUID -q | jq -r '.tests | join(",")'`)
- echo "$TEST_PAGES";
- IFS=',' read -ra ADDR <<< "$TEST_PAGES"
- for i in "${ADDR[@]}"; do drush vr-test-import $i CI-regression; done
- |
if [ "$PATCH_FILE_URL" != "" ]; then
drush dl $PROJECT_NAME-$PROJECT_DEV_VERSION -y
PATCH_FILE_NAME=$(basename "$PATCH_FILE_URL")
elif [ "$PROJECT_STABLE_VERSION" != "" ]; then
drush dl $PROJECT_NAME-$PROJECT_STABLE_VERSION -y
PATCH_FILE_NAME=""
fi
- drush en $PROJECT_NAME -y
- drush vrc "http://127.0.0.1:8080/" $PATCH_FILE_NAME --preset_category=CI-regression
- |
if [ "$PATCH_FILE_URL" != "" ]; then
cd sites/all/modules/$PROJECT_NAME
echo "Applying PATCH $PATCH_FILE_URL"
wget $PATCH_FILE_URL
PATCH_FILE_NAME=$(basename "$PATCH_FILE_URL")
patch -p1 < $PATCH_FILE_NAME
cd ../../../../
elif [ "$PROJECT_STABLE_VERSION" != "" ]; then
drush dl $PROJECT_NAME-$PROJECT_DEV_VERSION -y
PATCH_FILE_NAME=""
fi
- drush updb -y
- drush cc all
- drush vrc "http://127.0.0.1:8080/" "$PATCH_FILE_NAME" --preset_category=CI-regression
- drush vr-diff
- drush vset --yes drulenium_vr_api_secret $DRULENIUM_ORG_API_SECRET -q
- drush dl gitlab_api_client-7.x-1.x-dev drulenium_gitlab-7.x-1.x-dev -y
- drush en gitlab_api_client drulenium_gitlab -y
- drush vset --yes gitlab_project "$CI_PROJECT_PATH"
- drush vset --yes gitlab_build_id $CI_BUILD_ID
- drush vr-diff-upload --project_id=$DRULENIUM_ORG_PROJECT_UUID
- cd ..
- mv docroot/sites/default/files/drulenium .
except:
- master
artifacts:
name: "drulenium-artifacts"
paths:
- drulenium
Menu Block 7.x-2.x-dev, xxxx-xx-xx (development release)
----------------------------------
- #1420180 by jweowu: Assign the panel panes for menu block blocks to the "Menus" category
- #1937038: Use $max_depth parameter of menu_tree_all_data() and menu_tree_page_data()
- #907292: Add API to obtain raw menu data (not the render element)
- #1327472 by tim.plunkett, pjcdawkins and giginos: Child menu items don't appear when current page is front page
- #1698992: hook_uninstall assumes block module dependency
- #1594684 by pfournier: Menu block export ids may be too long, plus unquoted string
- #1812824 by gabriel.achille: Incompatibility with modules like menu_position
- #1203646 by jweowu: Pane generates illegal choice error when editing
- #1909366 by lund.mikkel: Menu block names get translated twice
- #1910420 by simongeorges: Remove useless files[] directive from .info files
- #1204064 by MrHaroldA, pjcdawkins and BartK: Fix undefined index notices in menu_tree_add_active_path()
- #810362: Make Menu Block require 'administer menus' permission
- #1524674 by Crell: Use of $_GET['q'] ignores menu_position module
- #1688168 by tim.plunkett: Undefined index errors when using CTools content type and '_active' menu
- #1701702: Disabled menu items still trigger "the menu selected by the page"
Menu Block 7.x-2.3, 2012-02-04
------------------------------
- #1105372 by mikl, fabsor and JohnAlbin: Add menu tree ctools content type to D7
- #1425342 by JohnAlbin and Dave Reid: Menu block fails with Drupal core 7.12; remove work-around for core bug #942782.
- #1243978 by Dave Reid: Fixed menu_block_export_menu() items were not translatable since they were not located in menu_block_export.module.
- #1243978 by Dave Reid: Fixed menu_block_menu() items were not translatable since they were not located in menu_block.module.
- by Dave Reid: Moved menu_block_menu_alter() to menu_block.menu so that it doesn't cause a module hook cache miss.
- #1155052 by Dave Reid: Fixed errors if block module is not enabled.
- #1162038 by Dave Reid: Fixed 'Add menu block' local action only appears on default theme.
- #1114722 by dropcube: Fixed i18n menu support
- #1154122 by Dave Reid: Moved block module hook implementations to menu_block.module to prevent problems with hook implementation caching.
- #1078806 by Dave Reid: Fixed string untranslated warning from coder.
- #1139530 by Dave Reid: Add a base form ID of block_add_block_form to menu_block_add_block_form so other modules can properly and easily alter it.
- #1139522 by Dave Reid: Fixed fatal error with current page menu trees.
Menu Block 7.x-2.2, 2011-03-09
------------------------------
- #1086376: Custom menu fix doesn't work for new installations
Menu Block 7.x-2.1, 2011-02-06
------------------------------
- #1051988: Fix wrong path in menu_block_help()
- #1050766: Improve usability of "Parent item" UI
- #1050040 by AgentRickard: Remove performance-killing variable_set() calls on non-admin pages
Menu Block 7.x-2.0, 2011-01-11
------------------------------
- #1022478: Add "Edit book outline" contextual link for book menu blocks
- #1022428: Contextual links for all menu blocks disappear if book menu_block used
- #1017142: except for one menu, all other menus (including books) never receive an active trail
- #1017122 by becw, mfer and JohnAlbin: Core bug work-around: add active trail to custom menus
- Always show core menu blocks if they are in a region
- #993998 by tgf: Core menu suppression broken
- #993998 by jackinloadup: Delete links misplaced on menu list form
- #958166 by Simon Georges and JohnAlbin: secondary-menu removed from core; replace with user-menu
- #825132: Performance problem on sites with many books
- #945714 by pedrochristopher: theme override misidentified in README
- #593126: hook_get_menus() causes conflicts with Menu Access, og_menu, etc
- #825132: Add hook_menu_block_get_sort_menus() for improved performance and UX of book integration
- #957362 by blixxxa: Add Swedish translation
- Fix theme hook suggestions for non-numeric block deltas
Menu Block 7.x-2.0-beta4, 2010-09-29
------------------------------------
- #891690: Never accept a fix not in patch form. And if you do, test it!
Menu Block 7.x-2.0-beta3, 2010-09-29
------------------------------------
- #891698 by Chris Gillis: Incorrect link to configuration page
- #891690 by Chris Gillis: Undefined function db_fetch_array
- Updated menu_block_get_title() to return a renderable array
- Add #bid context to menu_link theme hook
Menu Block 7.x-2.0-beta2, 2010-04-16
------------------------------------
- Add ability to suppress core's standard menu blocks on block admin page
- #693302: Add simple bulk export module
- Fixed import of exportable menu_blocks
- Fixed bug causing missing "delete" link for menu blocks
- Fixed configure link on modules page
Menu Block 7.x-2.0-beta1, 2010-03-26
------------------------------------
- #693302: Add API for exportable menu_blocks
- #749838: Port to Drupal 7
Menu Block 6.x-2.3, 2010-03-24
------------------------------
- #739282: Users with "administer menu" privileges can exploit XSS vulnerability
- #343061 by sun and JohnAlbin: CSS styling breaks form layout
- #345552 by Dmitriy.trt: Inconsistent display of starting level set to children
of active item
- #474784: Menu title as link is incorrectly always marked as in active trail
- #540842 by JohnAlbin and agentrickard: Add option to use current page's
selected menu
- #580348: Add administrative title to config form to help organize blocks
- #350029: Add theme hook suggestions for all theme function calls
- #741284 by JohnAlbin, sdboyer, and hefox: Add "menu tree" content types to
Chaos Tools/Panels.
- #741284 by JohnAlbin and hefox: Add menu_block_get_config() and
menu_block_configure_form() to make the configuration form reusable by
separating it from the Block API functions.
- #553842 by apodran and JohnAlbin: split() is deprecated in PHP 5.3
- #398888: "exanded" elements of a menu-item-rooted tree aren't expanded
- #703968 by hefox and JohnAlbin: Add menu_tree_build() to allow reuse of tree
building code outside of blocks
- Refactored API for menu_block_get_title() and menu_block_set_title()
- Added HOOK_menu_block_tree_alter() to allow direct tree manipulation
- by Denes Szabo and Zoltan Balogh: Added Hungarian translation
- Make default menu be "Primary links" instead of "Navigation"
- #378206 by sbordage: Added French translation
- #345419: Add option for menu title as link
- #347805: Add delta to variables and classes in menu-block-wrapper.tpl
Menu Block 6.x-2.2, 2008-12-16
------------------------------
- #342498: Give unique class to depth-limited leaves that have children
- #341436: Depth-limited leaves that have children get "collapsed" icon
- #341345: WSOD on "Add menu block" page with some PHP versions
Menu Block 6.x-2.1, 2008-12-01
------------------------------
- #300086: Add option to make starting level follow active menu item
- #340868: Clean up display of block configuration options
- #300094: Add option to sort active trail to top of menu tree
- #328238 by gorbeia: Add support for i18n menu translation
- #331934: Add option to select parent item of menu tree
- #330978: Add hook_get_menus() and implement Book module integration
- #331935: Replace admin/by-module hack with README.txt
- #332974: Collapsed menu items get "leaf" class when using "depth" option
- #333988: Create template for menu-block-wrapper
- #331933 by sun: Help links are displayed if Help module is disabled
- #338263: Migration from 5.x-1.x to 6.x-2.x is broken
- #305267: Menu blocks incorrectly cached per role
Menu Block 6.x-2.0, 2008-08-25
------------------------------
- Added extensive documentation help text
- Added extended classes to menu trees
- Menu block's administrative interface now matches the block module's standard
add, configure, and delete interface
- #266230: Port Menu block to D6
Menu Block 5.x-2.0, 2008-11-24
------------------------------
- #304675: Port 6.x admin interface to 5.x
- Added missing dependency on menu module
Menu Block 5.x-1.0, 2008-08-05
------------------------------
- Simplified block configuration
Menu Block 5.x-0.9, 2008-08-05
------------------------------
- #266223: Add option to limit the depth of the tree to an arbitrary level
- Added block config to specify whether to expand all children
- Added settings to enable specific menu blocks
......@@ -4,40 +4,6 @@
* Provides infrequently used functions and hooks for menu_block.
*/
/**
* Implements hook_theme().
*/
function _menu_block_theme(&$existing, $type, $theme, $path) {
// Add theme hook suggestion patterns for the core theme functions used in
// this module. We can't add them during hook_theme_registry_alter() because
// we will already have missed the opportunity for the theme engine's
// theme_hook() to process the pattern. And we can't run the pattern ourselves
// because we aren't given the type, theme and path in that hook.
$existing['menu_tree']['pattern'] = 'menu_tree__';
$existing['menu_link']['pattern'] = 'menu_link__';
return array(
'menu_block_wrapper' => array(
'template' => 'menu-block-wrapper',
'variables' => array('content' => array(), 'config' => array(), 'delta' => NULL),
'pattern' => 'menu_block_wrapper__',
),
'menu_block_menu_order' => array(
'render element' => 'element',
'file' => 'menu_block.admin.inc',
),
);
}
/**
* Implements hook_ctools_plugin_directory().
*/
function _menu_block_ctools_plugin_directory($module, $plugin) {
if ($plugin == 'content_types') {
return 'plugins/' . $plugin;
}
}
/**
* Menu callback: display the menu block addition form.
*
......@@ -117,19 +83,19 @@ function menu_block_add_block_form_submit($form, &$form_state) {
* Alters the block admin form to add delete links next to menu blocks.
*/
function _menu_block_form_block_admin_display_form_alter(&$form, $form_state) {
$blocks = module_invoke_all('menu_block_blocks');
foreach (variable_get('menu_block_ids', array()) AS $delta) {
if (empty($blocks[$delta])) {
$exported = menu_block_get_exported_blocks();
foreach (variable_get('menu_block_ids', array()) as $delta) {
if (!isset($exported[$delta])) {
$form['blocks']['menu_block_' . $delta]['delete'] = array('#type' => 'link', '#title' => t('delete'), '#href' => 'admin/structure/block/delete-menu-block/' . $delta);
}
}
if (variable_get('menu_block_suppress_core')) {
foreach (array_keys(menu_get_menus(FALSE)) AS $delta) {
foreach (array_keys(menu_get_menus(FALSE)) as $delta) {
if (empty($form['blocks']['menu_' . $delta]['region']['#default_value'])) {
unset($form['blocks']['menu_' . $delta]);
}
}
foreach (array_keys(menu_list_system_menus()) AS $delta) {
foreach (array_keys(menu_list_system_menus()) as $delta) {
if (empty($form['blocks']['system_' . $delta]['region']['#default_value'])) {
unset($form['blocks']['system_' . $delta]);
}
......@@ -140,7 +106,7 @@ function _menu_block_form_block_admin_display_form_alter(&$form, $form_state) {
/**
* Menu callback: confirm deletion of menu blocks.
*/
function menu_block_delete($form, &$form_state, $delta = 0) {
function menu_block_delete_form($form, &$form_state, $delta = 0) {
$title = _menu_block_format_title(menu_block_get_config($delta));
$form['block_title'] = array('#type' => 'hidden', '#value' => $title);
$form['delta'] = array('#type' => 'hidden', '#value' => $delta);
......@@ -151,30 +117,10 @@ function menu_block_delete($form, &$form_state, $delta = 0) {
/**
* Deletion of menu blocks.
*/
function menu_block_delete_submit($form, &$form_state) {
function menu_block_delete_form_submit($form, &$form_state) {
// Remove the menu block configuration variables.
$delta = $form_state['values']['delta'];
$block_ids = variable_get('menu_block_ids', array());
unset($block_ids[array_search($delta, $block_ids)]);
sort($block_ids);
variable_set('menu_block_ids', $block_ids);
variable_del("menu_block_{$delta}_title_link");
variable_del("menu_block_{$delta}_admin_title");
variable_del("menu_block_{$delta}_parent");
variable_del("menu_block_{$delta}_level");
variable_del("menu_block_{$delta}_follow");
variable_del("menu_block_{$delta}_depth");
variable_del("menu_block_{$delta}_expanded");
variable_del("menu_block_{$delta}_sort");
db_delete('block')
->condition('module', 'menu_block')
->condition('delta', $delta)
->execute();
db_delete('block_role')
->condition('module', 'menu_block')
->condition('delta', $delta)
->execute();
menu_block_delete($delta);
drupal_set_message(t('The block "%name" has been removed.', array('%name' => $form_state['values']['block_title'])));
cache_clear_all();
$form_state['redirect'] = 'admin/structure/block';
......@@ -187,10 +133,9 @@ function menu_block_delete_submit($form, &$form_state) {
function _menu_block_block_info() {
$blocks = array();
$deltas = variable_get('menu_block_ids', array());
foreach (array_keys(module_invoke_all('menu_block_blocks')) as $delta) {
$deltas[] = $delta;
}
foreach ($deltas AS $delta) {
$exported = menu_block_get_exported_blocks();
$deltas = array_unique(array_merge($deltas, array_keys($exported)));
foreach ($deltas as $delta) {
$blocks[$delta]['info'] = _menu_block_format_title(menu_block_get_config($delta));
// Menu blocks can't be cached because each menu item can have
// a custom access callback. menu.inc manages its own caching.
......@@ -214,9 +159,12 @@ function _menu_block_format_title($config) {
}
$menus = menu_block_get_all_menus();
$menus[MENU_TREE__CURRENT_PAGE_MENU] = t('Current menu');
if (empty($config['menu_name']) || empty($menus[$config['menu_name']])) {
if (empty($config['menu_name'])) {
$title = t('Unconfigured menu block');
}
elseif (!isset($menus[$config['menu_name']])) {
$title = t('Deleted/missing menu @menu', array('@menu' => $config['menu_name']));
}
else {
// Show the configured levels in the block info
$replacements = array(
......@@ -282,7 +230,7 @@ function menu_block_configure_form($form, &$form_state) {
}
}
// Merge in the default configuration.
$config += menu_block_get_config();
$config += menu_block_default_config();
// Don't display the config form if this delta is exported to code.
if (!empty($config['exported_to_code'])) {
......@@ -351,15 +299,15 @@ function menu_block_configure_form($form, &$form_state) {
'#title' => t('Starting level'),
'#default_value' => $config['level'],
'#options' => array(
'1' => t('1st level (primary)'),
'2' => t('2nd level (secondary)'),
'3' => t('3rd level (tertiary)'),
'4' => t('4th level'),
'5' => t('5th level'),
'6' => t('6th level'),
'7' => t('7th level'),
'8' => t('8th level'),
'9' => t('9th level'),
'1' => t('1st level (primary)'),
'2' => t('2nd level (secondary)'),
'3' => t('3rd level (tertiary)'),
'4' => t('4th level'),
'5' => t('5th level'),
'6' => t('6th level'),
'7' => t('7th level'),
'8' => t('8th level'),
'9' => t('9th level'),
),
'#description' => t('Blocks that start with the 1st level will always be visible. Blocks that start with the 2nd level or deeper will only be visible when the trail to the active menu item passes though the block’s starting level.'),
);
......@@ -399,19 +347,30 @@ function menu_block_configure_form($form, &$form_state) {
'#title' => t('Maximum depth'),
'#default_value' => $config['depth'],
'#options' => array(
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
'8' => '8',
'9' => '9',
'0' => t('Unlimited'),
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
'7' => '7',
'8' => '8',
'9' => '9',
'0' => t('Unlimited'),
),
'#description' => t('From the starting level, specify the maximum depth of the menu tree.'),
);
$form['depth_relative'] = array(
'#type' => 'checkbox',
'#title' => t('Make the maximum depth relative to the starting level while following the active menu item.'),
'#default_value' => $config['depth_relative'],
'#states' => array(
'visible' => array(
':input[name=follow]' => array('checked' => TRUE),
':input[name=depth]' => array('!value' => '0'),
),
),
);
$form['expanded'] = array(
'#type' => 'checkbox',
'#title' => t('<strong>Expand all children</strong> of this tree.'),
......@@ -436,7 +395,7 @@ function menu_block_configure_form($form, &$form_state) {
$form['menu-block-wrapper-close'] = array('#markup' => '</div>');
// Set visibility of advanced options.
foreach (array('title_link', 'follow', 'follow_parent', 'expanded', 'sort', 'parent') as $key) {
foreach (array('title_link', 'follow', 'depth_relative', 'follow_parent', 'expanded', 'sort', 'parent') as $key) {
$form[$key]['#states']['visible'][':input[name=display_options]'] = array('value' => 'advanced');
}
if ($config['title_link'] || $follow || $config['expanded'] || $config['sort'] || $config['parent_mlid']) {
......@@ -485,6 +444,7 @@ function _menu_block_block_save($delta = '', $edit = array()) {
variable_set("menu_block_{$delta}_level", $edit['level']);
variable_set("menu_block_{$delta}_follow", $edit['follow']);
variable_set("menu_block_{$delta}_depth", $edit['depth']);
variable_set("menu_block_{$delta}_depth_relative", $edit['depth_relative']);
variable_set("menu_block_{$delta}_expanded", $edit['expanded']);
variable_set("menu_block_{$delta}_sort", $edit['sort']);
}
......@@ -561,12 +521,9 @@ function menu_block_admin_settings_form($form, &$form_state) {
'#markup' => '<p>' . t('The above list will <em>not</em> affect menu blocks that are configured to use a specific menu.') . '</p>',
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save configuration'),
);
$form['#submit'][] = 'menu_block_admin_settings_form_submit';
return $form;
return system_settings_form($form);
}
/**
......@@ -574,26 +531,25 @@ function menu_block_admin_settings_form($form, &$form_state) {
*/
function menu_block_admin_settings_form_submit($form, &$form_state) {
$menu_order = array();
foreach ($form_state['values']['menu_order'] AS $menu_name => $row) {
foreach ($form_state['values']['menu_order'] as $menu_name => $row) {
if ($row['available']) {
// Add available menu and its weight to list.
$menu_order[$menu_name] = (int) $row['weight'];
}
}
// Clear menu_order before it's written to the variable table by system_settings_form_submit().
unset($form_state['values']['menu_order']);
// Sort the keys by the weight stored in the value.
asort($menu_order);
foreach ($menu_order AS $menu_name => $weight) {
foreach ($menu_order as $menu_name => $weight) {
// Now that the array is sorted, the weight is redundant data.
$menu_order[$menu_name] = '';
}
variable_set('menu_block_menu_order', $menu_order);
if ($form_state['values']['menu_block_suppress_core']) {
variable_set('menu_block_suppress_core', 1);
}
else {
variable_del('menu_block_suppress_core');
}
drupal_set_message(t('The configuration options have been saved.'));
// Add the menu_order to the values.
$form_state['values']['menu_block_menu_order'] = $menu_order;
}
/**
......
......@@ -92,6 +92,19 @@ function hook_menu_block_get_sort_menus() {
return $menus;
}
/**
* Respond to menu block deletion.
*
* @param array $config
* The menu block configuration.
*/
function hook_menu_block_delete(array $config) {
db_delete('block_data')
->condition('module', 'menu_block')
->condition('delta', $config['delta'])
->execute();
}
/**
* @} End of "addtogroup hooks".
*/
......@@ -18,7 +18,7 @@ function _menu_tree_prune_active_tree(&$tree, $level) {
do {
$found_active_trail = FALSE;
// Examine each element at this level for the active trail.
foreach ($tree AS $key => &$value) {
foreach ($tree as $key => &$value) {
if ($tree[$key]['link']['in_active_trail']) {
$found_active_trail = TRUE;
// If the active trail item has children, examine them.
......@@ -26,7 +26,7 @@ function _menu_tree_prune_active_tree(&$tree, $level) {
// If we are pruning to the active menu item's level, check if this
// is the active menu item by checking its children.
if ($level == 'active') {
foreach ($tree[$key]['below'] AS $child_key => &$value) {
foreach ($tree[$key]['below'] as $child_key => &$value) {
if ($tree[$key]['below'][$child_key]['link']['in_active_trail']) {
// Get the title for the pruned tree.
menu_block_set_title($tree[$key]['link']);
......
......@@ -9,31 +9,25 @@
*/
function menu_block_uninstall() {
// Delete menu block variables.
foreach (variable_get('menu_block_ids', array()) AS $delta) {
variable_del("menu_block_{$delta}_title_link");
variable_del("menu_block_{$delta}_admin_title");
variable_del("menu_block_{$delta}_parent");
variable_del("menu_block_{$delta}_level");
variable_del("menu_block_{$delta}_follow");
variable_del("menu_block_{$delta}_depth");
variable_del("menu_block_{$delta}_expanded");
variable_del("menu_block_{$delta}_sort");
drupal_load('module', 'menu_block');
$variable_keys = array_keys(menu_block_default_config());
foreach (variable_get('menu_block_ids', array()) as $delta) {
foreach ($variable_keys as $key) {
variable_del("menu_block_{$delta}_{$key}");
}
}
variable_del('menu_block_ids');
variable_del('menu_block_suppress_core');
variable_del('menu_block_menu_order');
// Remove block configurations.
if (module_exists('block')) {
db_delete('block')
->condition('module', 'menu_block')
->execute();
db_delete('block_role')
->condition('module', 'menu_block')
->execute();
foreach (array('block', 'block_node_type', 'block_role') as $table) {
if (db_table_exists($table)) {
db_delete($table)
->condition('module', 'menu_block')
->execute();
}
}
cache_clear_all();
}
/**
......@@ -43,13 +37,6 @@ function menu_block_enable() {
drupal_set_message(t('To use menu blocks, find the "Add menu block" link on the <a href="@url">administer blocks page</a>.', array('@url' => url('admin/structure/block'))));
}
/**
* Implements hook_install().
*/
function menu_block_install() {
// No-op.
}
/**
* Converts pre-5.x-1.0 block names to the new format.
*/
......@@ -58,7 +45,7 @@ function menu_block_update_5100() {
$enabled_blocks = array();
// Find the old enabled blocks.
foreach (variable_get('menu_block_enabled_blocks', array()) AS $old_delta => $enabled) {
foreach (variable_get('menu_block_enabled_blocks', array()) as $old_delta => $enabled) {
list($mid, $level) = explode('-', $old_delta);
if ($enabled) {
$enabled_blocks[++$delta] = TRUE;
......@@ -81,7 +68,7 @@ function menu_block_update_5100() {
*/
function menu_block_update_5200() {
$block_ids = array();
foreach (variable_get('menu_block_enabled_blocks', array()) AS $delta => $enabled) {
foreach (variable_get('menu_block_enabled_blocks', array()) as $delta => $enabled) {
if ($enabled) {
$block_ids[] = $delta; // Build new $menu_block_ids.
// Convert $menu_block_DELTA_mid to $menu_block_DELTA_menu_name.
......@@ -122,7 +109,7 @@ function menu_block_update_5200() {
*/
function menu_block_update_6200() {
$menus = menu_get_menus();
foreach (variable_get('menu_block_ids', array()) AS $delta) {
foreach (variable_get('menu_block_ids', array()) as $delta) {
// Drupal 6 uses the menu title to create the new menu_name.
$menu_name = preg_replace('/[^a-zA-Z0-9]/', '-', strtolower(variable_get("menu_block_{$delta}_title", '')));
// If we can't find the new menu_name, default to the navigation menu.
......@@ -140,7 +127,7 @@ function menu_block_update_6200() {
*/
function menu_block_update_6201() {
$menus = menu_get_menus();
foreach (variable_get('menu_block_ids', array()) AS $delta) {
foreach (variable_get('menu_block_ids', array()) as $delta) {
variable_set("menu_block_{$delta}_parent", variable_get("menu_block_{$delta}_menu_name", 'navigation') . ':0');
variable_del("menu_block_{$delta}_menu_name");
}
......@@ -151,7 +138,7 @@ function menu_block_update_6201() {
* Converts to Drupal 7 menu names.
*/
function menu_block_update_7200() {
foreach (variable_get('menu_block_ids', array()) AS $delta) {
foreach (variable_get('menu_block_ids', array()) as $delta) {
$menu_name = '';
list($old_menu_name, $parent_mlid) = explode(':', variable_get("menu_block_{$delta}_parent", ' : '));
switch ($old_menu_name) {
......@@ -200,3 +187,10 @@ function menu_block_fix_custom_menus() {
function menu_block_update_7202() {
menu_block_fix_custom_menus();
}
/**
* Trigger a menu rebuild.
*/
function menu_block_update_7203() {
// Nothing needed here.
}
......@@ -5,15 +5,11 @@
*/
/**
* Denotes that the tree should use the menu picked by the curent page.
* Denotes that the tree should use the menu picked by the current page.
*/
define('MENU_TREE__CURRENT_PAGE_MENU', '_active');
// Off-load the following infrequently called hooks to another file.
function menu_block_theme(&$existing, $type, $theme, $path) {
module_load_include('inc', 'menu_block', 'menu_block.admin');
return _menu_block_theme($existing, $type, $theme, $path);
}
function menu_block_block_info() {
module_load_include('inc', 'menu_block', 'menu_block.admin');
return _menu_block_block_info();
......@@ -30,20 +26,6 @@ function menu_block_form_block_admin_display_form_alter(&$form, $form_state) {
module_load_include('inc', 'menu_block', 'menu_block.admin');
return _menu_block_form_block_admin_display_form_alter($form, $form_state);
}
function menu_block_ctools_plugin_directory($module, $plugin) {
module_load_include('inc', 'menu_block', 'menu_block.admin');
return _menu_block_ctools_plugin_directory($module, $plugin);
}
/**
* Implements hook_ctools_block_info().
*
* @see ctools_block_content_type_content_types().
*/
function menu_block_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_contrib_menu.png';
$info['category'] = t('Menus');
}
/**
* Implements hook_menu().
......@@ -77,7 +59,7 @@ function menu_block_menu() {
$items['admin/structure/block/delete-menu-block'] = array(
'title' => 'Delete menu block',
'page callback' => 'drupal_get_form',
'page arguments' => array('menu_block_delete'),
'page arguments' => array('menu_block_delete_form'),
'access callback' => 'menu_block_access',
'type' => MENU_CALLBACK,
'file' => 'menu_block.admin.inc',
......@@ -114,6 +96,50 @@ function menu_block_menu_alter(&$items) {
$items['admin/content/book/%node']['tab_root'] = 'admin/content/book';
}
/**
* Implements hook_ctools_plugin_directory().
*/
function menu_block_ctools_plugin_directory($module, $plugin) {
if ($plugin == 'content_types') {
return 'plugins/' . $plugin;
}
}
/**
* Implements hook_ctools_block_info().
*
* @see ctools_block_content_type_content_types().
*/
function menu_block_ctools_block_info($module, $delta, &$info) {
$info['icon'] = 'icon_contrib_menu.png';
$info['category'] = t('Menus');
}
/**
* Implements hook_theme().
*/
function menu_block_theme(&$existing, $type, $theme, $path) {
// Add theme hook suggestion patterns for the core theme functions used in
// this module. We can't add them during hook_theme_registry_alter() because
// we will already have missed the opportunity for the theme engine's
// theme_hook() to process the pattern. And we can't run the pattern ourselves
// because we aren't given the type, theme and path in that hook.
$existing['menu_tree']['pattern'] = 'menu_tree__';
$existing['menu_link']['pattern'] = 'menu_link__';
return array(
'menu_block_wrapper' => array(
'template' => 'menu-block-wrapper',
'variables' => array('content' => array(), 'config' => array(), 'delta' => NULL),
'pattern' => 'menu_block_wrapper__',
),
'menu_block_menu_order' => array(
'render element' => 'element',
'file' => 'menu_block.admin.inc',
),
);
}
/**
* Implements hook_help().
*/
......@@ -135,18 +161,24 @@ function menu_block_help($path, $arg) {
*/
function menu_block_block_view($delta = '') {
$config = menu_block_get_config($delta);
$data = menu_tree_build($config);
// Add contextual links for this block.
if (!empty($data['content'])) {
if (in_array($config['menu_name'], array_keys(menu_get_menus()))) {
$data['content']['#contextual_links']['menu_block'] = array('admin/structure/menu/manage', array($config['menu_name']));
}
elseif (strpos($config['menu_name'], 'book-toc-') === 0) {
$node = str_replace('book-toc-', '', $config['menu_name']);
return menu_tree_build($config);
}
/**
* Implements hook_block_view_alter().
*/
function menu_block_block_view_alter(&$data, $block) {
// Add contextual links for menu blocks.
if ($block->module == 'menu_block' && !empty($data['content']['#config'])) {
$menu_name = $data['content']['#config']['menu_name'];
if (in_array($menu_name, array_keys(menu_get_menus()))) {
$data['content']['#contextual_links']['menu_block'] = array('admin/structure/menu/manage', array($menu_name));
}
elseif (strpos($menu_name, 'book-toc-') === 0) {
$node = str_replace('book-toc-', '', $menu_name);
$data['content']['#contextual_links']['menu_block'] = array('admin/content/book', array($node));
}
}
return $data;
}
/**
......@@ -157,21 +189,29 @@ function menu_block_block_view($delta = '') {
function template_preprocess_menu_block_wrapper(&$variables) {
$variables['classes_array'][] = 'menu-block-' . $variables['delta'];
$variables['classes_array'][] = 'menu-name-' . $variables['config']['menu_name'];
$variables['classes_array'][] = 'parent-mlid-' . $variables['config']['parent_mlid'];
$variables['classes_array'][] = 'parent-mlid-' . menu_block_clean_css_identifier($variables['config']['parent_mlid']);
$variables['classes_array'][] = 'menu-level-' . $variables['config']['level'];
}
/**
* A copy of drupal_clean_css_identifier() that cleans up colon characters.
*/
function menu_block_clean_css_identifier($identifier, $filter = array(' ' => '-', '_' => '-', '/' => '-', '[' => '-', ']' => '', ':' => '-')) {
return drupal_clean_css_identifier($identifier, $filter);
}
/**
* Returns a list of menu names implemented by all modules.
*
* @return
* array A list of menu names and titles.
* @return array
* An array of menu titles keyed by menu machine name.
*/
function menu_block_get_all_menus() {
$all_menus = &drupal_static(__FUNCTION__);
if (!$all_menus) {
if ($cached = cache_get('menu_block_menus', 'cache_menu')) {
$cid = 'menu_block_menus:' . $GLOBALS['language']->language;
if ($cached = cache_get($cid, 'cache_menu')) {
$all_menus = $cached->data;
}
else {
......@@ -179,81 +219,135 @@ function menu_block_get_all_menus() {
$all_menus = menu_get_menus();
// Retrieve all the menu names provided by hook_menu_block_get_menus().
$all_menus = array_merge($all_menus, module_invoke_all('menu_block_get_menus'));
// Add an option to use the menu for the active menu item.
$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');
// Add an option to use the menu for the active menu item.
$all_menus = array(MENU_TREE__CURRENT_PAGE_MENU => '<' . t('the menu selected by the page') . '>') + $all_menus;
cache_set($cid, $all_menus, 'cache_menu');
}
}
return $all_menus;
}
/**
* The default menu block configuration.
*
* @return array
*/
function menu_block_default_config() {
return array(
'parent' => 'main-menu:0',
'title_link' => 0,
'admin_title' => '',
'level' => 1,
'follow' => 0,
'depth' => 0,
'depth_relative' => 0,
'expanded' => 0,
'sort' => 0,
);
}
/**
* Fetch all exported menu blocks.
*
* @return array
*/
function menu_block_get_exported_blocks() {
$blocks = &drupal_static(__FUNCTION__);
if (!isset($blocks)) {
$blocks = array();
// Do not use module_invoke_all() since it rewrites numeric indexes.
// Although exported menu blocks should not be using numeric IDs, we
// should still prevent them from being changed.
foreach (module_implements('menu_block_blocks') as $module) {
$blocks += module_invoke($module, 'menu_block_blocks');
}
}
return $blocks;
}
/**
* Returns the configuration for the requested block delta.
*
* @param $delta
* string The delta that uniquely identifies the block in the block system. If
* @param string $delta
* The delta that uniquely identifies the block in the block system. If
* not specified, the default configuration will be returned.
* @return
* array An associated array of configuration options.
* This is deprecated. Use menu_block_default_config() instead.
*
* @return array
* An associated array of configuration options.
*
* @see menu_block_default_config()
*/
function menu_block_get_config($delta = NULL) {
$config = array(
'delta' => $delta,
'menu_name' => 'main-menu',
'parent_mlid' => 0,
'parent' => '',
'title_link' => 0,
'admin_title' => '',
'level' => 1,
'follow' => 0,
'depth' => 0,
'expanded' => 0,
'sort' => 0,
);
static $defaults, $exported;
if (!isset($defaults)) {
$defaults = menu_block_default_config();
}
if (!isset($delta)) {
return $defaults;
}
if (!isset($exported)) {
$exported = menu_block_get_exported_blocks();
}
$configs = &drupal_static(__FUNCTION__, array());
if (!isset($configs[$delta])) {
$config = array();
// Get the block configuration options.
if ($delta) {
static $blocks;
if (!isset($blocks)) {
$blocks = module_invoke_all('menu_block_blocks');
}
if (!empty($blocks[$delta])) {
// Merge the default values.
$config = $blocks[$delta] + $config;
// Set the delta.
$config['delta'] = $delta;
// Flag the block as exported.
// Check if this an exported menu block.
if (isset($exported[$delta])) {
$config += $exported[$delta];
$config['exported_to_code'] = TRUE;
// Exported blocks generally have 'menu_name' and 'parent_mlid' defined
// but not 'parent'
if (!isset($config['parent'])) {
$config['parent'] = $config['menu_name'] . ':' . $config['parent_mlid'];
}
}
$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']);
$config['parent'] = variable_get("menu_block_{$delta}_parent", $config['menu_name'] . ':' . $config['parent_mlid']);
list($config['menu_name'], $config['parent_mlid']) = explode(':', $config['parent']);
// Add in variable overrides and defaults.
foreach ($defaults as $key => $default) {
$override = variable_get("menu_block_{$delta}_{$key}");
if (isset($override)) {
$config[$key] = $override;
}
elseif (!isset($config[$key])) {
$config[$key] = $default;
}
}
// Split out the 'parent' item into 'menu_name' and 'parent_mlid'.
if (!isset($config['menu_name']) && !isset($config['parent_mlid'])) {
list($config['menu_name'], $config['parent_mlid']) = explode(':', $config['parent']);
}
$config['delta'] = $delta;
$configs[$delta] = $config;
}
return $config;
return $configs[$delta];
}
/**
* Gets the data structure representing a menu tree for the given configuration.
*
* @param $config
* @param array $config
* See the $config param of menu_tree_build().
*
* @return array
*/
function menu_tree_block_data(&$config) {
function menu_tree_block_data(array &$config) {
// Determine the max depth based on level and depth setting.
$max_depth = ($config['depth'] == 0) ? NULL : min($config['level'] + $config['depth'] - 1, MENU_MAX_DEPTH);
if ($config['expanded'] || $config['parent_mlid']) {
// Get the full, un-pruned tree.
if ($config['parent_mlid']) {
if ($config['parent_mlid'] || !empty($config['depth_relative'])) {
$tree = menu_tree_all_data($config['menu_name']);
}
else {
......@@ -263,8 +357,13 @@ function menu_tree_block_data(&$config) {
menu_tree_add_active_path($tree);
}
else {
// Get the tree pruned for just the active trail.
$tree = menu_tree_page_data($config['menu_name'], $max_depth);
if (!empty($config['depth_relative'])) {
// Get the tree pruned for just the active trail.
$tree = menu_tree_page_data($config['menu_name']);
}
else {
$tree = menu_tree_page_data($config['menu_name'], $max_depth);
}
}
// Allow alteration of the tree and config before we begin operations on it.
......@@ -279,6 +378,13 @@ function menu_tree_block_data(&$config) {
if ($config['level'] > 1 || $config['parent_mlid']) {
if ($config['parent_mlid']) {
$parent_item = menu_link_load($config['parent_mlid']);
if (!$parent_item) {
watchdog('menu_block', "Menu block @delta is set to use parent menu link @plid but the menu link was not loadable or does not exist.", array(
'@delta' => $config['delta'],
'@plid' => $config['parent_mlid'],
), WATCHDOG_ERROR);
$parent_item = NULL;
}
menu_tree_prune_tree($tree, $config['level'], $parent_item);
}
else {
......@@ -311,6 +417,9 @@ function menu_tree_block_data(&$config) {
/**
* Returns the current page's menu.
*
* @return string|bool
* The current page's menu, or FALSE if no menu applied.
*/
function menu_block_get_current_page_menu() {
// Retrieve the list of available menus.
......@@ -366,8 +475,8 @@ function menu_block_get_current_page_menu() {
/**
* Build a menu tree based on the provided configuration.
*
* @param $config
* array An array of configuration options that specifies how to build the
* @param array $config
* An array of configuration options that specifies how to build the
* menu tree and its title.
* - delta: (string) The menu_block's block delta.
* - menu_name: (string) The machine name of the requested menu. Can also be
......@@ -386,13 +495,14 @@ function menu_block_get_current_page_menu() {
* - expanded: (boolean) Specifies if the entire tree be expanded or not.
* - sort: (boolean) Specifies if the tree should be sorted with the active
* trail at the top of the tree.
* @return
* array An associative array containing several pieces of data.
*
* @return array
* An associative array containing several pieces of data.
* - content: The tree as a renderable array.
* - subject: The title rendered as HTML.
* - subject_array: The title as a renderable array.
*/
function menu_tree_build(&$config) {
function menu_tree_build(array &$config) {
// Retrieve the active menu item from the database.
if ($config['menu_name'] == MENU_TREE__CURRENT_PAGE_MENU) {
$config['menu_name'] = menu_block_get_current_page_menu();
......@@ -409,19 +519,21 @@ function menu_tree_build(&$config) {
}
// Get the default block name.
drupal_static_reset('menu_block_set_title');
$menu_names = menu_block_get_all_menus();
menu_block_set_title($menu_names[$config['menu_name']]);
// Get the raw menu tree data.
$tree = menu_tree_block_data($config);
$title = menu_block_get_title($config['title_link'], $config);
$title = menu_block_get_title($config['title_link']);
// Create a renderable tree.
$data = array();
$data['subject_array'] = $title;
$data['subject'] = drupal_render($title);
$data['content']['#content'] = menu_block_tree_output($tree, $config);
if (!empty($data['content']['#content'])) {
$data['content'] = array();
if (!empty($tree) && $output = menu_block_tree_output($tree, $config)) {
$data['content']['#content'] = $output;
$data['content']['#theme'] = array(
'menu_block_wrapper__' . str_replace('-', '_', $config['delta']),
'menu_block_wrapper__' . str_replace('-', '_', $config['menu_name']),
......@@ -430,9 +542,6 @@ function menu_tree_build(&$config) {
$data['content']['#config'] = $config;
$data['content']['#delta'] = $config['delta'];
}
else {
$data['content'] = '';
}
return $data;
}
......@@ -440,28 +549,24 @@ function menu_tree_build(&$config) {
/**
* Retrieves the menu item to use for the tree's title.
*
* @param $render_title_as_link
* @param bool $render_title_as_link
* boolean A boolean that says whether to render the title as a link or a
* simple string.
* @return
* array A renderable array containing the tree's title.
*
* @return array|string
* A render array or string containing the tree's title.
*/
function menu_block_get_title($render_title_as_link = TRUE) {
$menu_item = menu_block_set_title();
// The tree's title is a menu title, a normal string.
if (is_string($menu_item)) {
// The tree's title is a menu title, a normal string.
$title = array('#markup' => check_plain($menu_item));
}
// The tree's title is a menu item with a link.
elseif ($render_title_as_link) {
// The tree's title is a menu item with a 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';
}
$menu_item['localized_options']['attributes']['class'][] = 'active-trail';
}
$title = array(
'#type' => 'link',
......@@ -480,11 +585,14 @@ function menu_block_get_title($render_title_as_link = TRUE) {
/**
* Sets the menu item to use for the tree's title.
*
* @param $item
* array The menu item (an array) or the menu item's title as a string.
* @param array|string $item
* The menu item (an array) or the menu item's title as a string.
*
* @return array|string
* The saved title value.
*/
function menu_block_set_title($item = NULL) {
$menu_item = &drupal_static(__FUNCTION__);
$menu_item = &drupal_static(__FUNCTION__, '');
// Save the menu item.
if (!is_null($item)) {
......@@ -502,12 +610,10 @@ function menu_block_set_title($item = NULL) {
* menu_tree_all_data() does not contain the active trail indicators. This is a
* helper function that adds it back in.
*
* @param $tree
* array The menu tree.
* @return
* void
* @param array $tree
* The menu tree.
*/
function menu_tree_add_active_path(&$tree) {
function menu_tree_add_active_path(array &$tree) {
// Grab any menu item to find the menu_name for this tree.
$menu_item = current($tree);
$tree_with_trail = menu_tree_page_data($menu_item['link']['menu_name']);
......@@ -517,7 +623,7 @@ function menu_tree_add_active_path(&$tree) {
// Find each key in the active trail.
while ($tree_with_trail) {
foreach ($tree_with_trail AS $key => &$value) {
foreach ($tree_with_trail as $key => &$value) {
if ($tree_with_trail[$key]['link']['in_active_trail'] && isset($subtree_pointer[$key])) {
// Set the active trail info in the original tree.
$subtree_pointer[$key]['link']['in_active_trail'] = TRUE;
......@@ -536,13 +642,11 @@ function menu_tree_add_active_path(&$tree) {
/**
* Trim everything but the active trail in the tree.
*
* @param $tree
* array The menu tree to trim.
* @return
* void
* @param array $tree
* The menu tree to trim.
*/
function menu_tree_trim_active_path(&$tree) {
foreach ($tree AS $key => &$value) {
function menu_tree_trim_active_path(array &$tree) {
foreach ($tree as $key => &$value) {
if (($tree[$key]['link']['in_active_trail'] || $tree[$key]['link']['expanded']) && $tree[$key]['below']) {
// Continue in the subtree, if it exists.
menu_tree_trim_active_path($tree[$key]['below']);
......@@ -557,12 +661,10 @@ function menu_tree_trim_active_path(&$tree) {
/**
* Sort the active trail to the top of the tree.
*
* @param $tree
* @param array $tree
* array The menu tree to sort.
* @return
* void
*/
function menu_tree_sort_active_path(&$tree) {
function menu_tree_sort_active_path(array &$tree) {
module_load_include('inc', 'menu_block', 'menu_block.sort');
_menu_tree_sort_active_path($tree);
}
......@@ -572,23 +674,21 @@ function menu_tree_sort_active_path(&$tree) {
*
* This function will follow the active menu trail to the specified level.
*
* @param $tree
* array The menu tree to prune.
* @param $level
* int The level of the original tree that will start the pruned tree.
* @param $parent_item
* array The menu item that should be used as the root of the tree.
* @return
* void
*/
function menu_tree_prune_tree(&$tree, $level, $parent_item = FALSE) {
* @param array $tree
* The menu tree to prune.
* @param int $level
* The level of the original tree that will start the pruned tree.
* @param array $parent_item
* The menu item that should be used as the root of the tree.
*/
function menu_tree_prune_tree(array &$tree, $level, array $parent_item = NULL) {
if (!empty($parent_item)) {
// Prune the tree along the path to the menu item.
for ($i = 1; $i <= MENU_MAX_DEPTH && $parent_item["p$i"] != '0'; $i++) {
$plid = $parent_item["p$i"];
$found_active_trail = FALSE;
// Examine each element at this level for the ancestor.
foreach ($tree AS $key => &$value) {
foreach ($tree as $key => &$value) {
if ($tree[$key]['link']['mlid'] == $plid) {
menu_block_set_title($tree[$key]['link']);
// Prune the tree to the children of this ancestor.
......@@ -610,7 +710,7 @@ function menu_tree_prune_tree(&$tree, $level, $parent_item = FALSE) {
for ($i = 1; $i < $level; $i++) {
$found_active_trail = FALSE;
// Examine each element at this level for the active trail.
foreach ($tree AS $key => &$value) {
foreach ($tree as $key => &$value) {
// Also include the children of the front page.
if ($tree[$key]['link']['in_active_trail'] || ($tree[$key]['link']['link_path'] == '<front>' && $is_front_page)) {
// Get the title for the pruned tree.
......@@ -632,14 +732,12 @@ function menu_tree_prune_tree(&$tree, $level, $parent_item = FALSE) {
/**
* Prune a tree so that it begins at the active menu item.
*
* @param $tree
* array The menu tree to prune.
* @param $level
* string The level which the tree will be pruned to: 'active' or 'child'.
* @return
* void
*/
function menu_tree_prune_active_tree(&$tree, $level) {
* @param array $tree
* The menu tree to prune.
* @param string $level
* The level which the tree will be pruned to: 'active' or 'child'.
*/
function menu_tree_prune_active_tree(array &$tree, $level) {
module_load_include('inc', 'menu_block', 'menu_block.follow');
_menu_tree_prune_active_tree($tree, $level);
}
......@@ -647,21 +745,19 @@ function menu_tree_prune_active_tree(&$tree, $level) {
/**
* Prune a tree so it does not extend beyond the specified depth limit.
*
* @param $tree
* array The menu tree to prune.
* @param $depth_limit
* int The maximum depth of the returned tree; must be a positive integer.
* @return
* void
*/
function menu_tree_depth_trim(&$tree, $depth_limit) {
* @param array $tree
* The menu tree to prune.
* @param int $depth_limit
* The maximum depth of the returned tree; must be a positive integer.
*/
function menu_tree_depth_trim(array &$tree, $depth_limit) {
// Prevent invalid input from returning a trimmed tree.
if ($depth_limit < 1) {
return;
}
// Examine each element at this level to find any possible children.
foreach ($tree AS $key => &$value) {
foreach ($tree as $key => &$value) {
if ($tree[$key]['below']) {
if ($depth_limit > 1) {
menu_tree_depth_trim($tree[$key]['below'], $depth_limit-1);
......@@ -685,12 +781,14 @@ function menu_tree_depth_trim(&$tree, $depth_limit) {
* This is a copy of menu_tree_output() with additional classes added to the
* output.
*
* @param $tree
* array A data structure representing the tree as returned from menu_tree_data.
* @return
* string The rendered HTML of that data structure.
* @param array $tree
* A data structure representing the tree as returned from menu_tree_data.
* @param array $config
*
* @return array
* The menu tree as a render array.
*/
function menu_block_tree_output(&$tree, $config = array()) {
function menu_block_tree_output(array &$tree, array $config = array()) {
$build = array();
$items = array();
......@@ -795,7 +893,7 @@ function menu_block_tree_output(&$tree, $config = array()) {
*/
function book_menu_block_get_menus() {
$menus = array();
foreach (book_get_books() AS $book) {
foreach (book_get_books() as $book) {
$menus[$book['menu_name']] = $book['title'];
}
return $menus;
......@@ -809,3 +907,166 @@ function book_menu_block_get_sort_menus() {
'/^book\-toc\-.+/' => t('Book navigation'),
);
}
/**
* Implements hook_get_pane_links_alter().
*/
function menu_block_get_pane_links_alter(&$links, $pane, $content_type) {
if ($pane->type === 'menu_tree') {
if (in_array($pane->subtype, array_keys(menu_get_menus()))) {
$links['top'][] = array(
'title' => t('Edit menu links'),
'href' => url('admin/structure/menu/manage/' . $pane->subtype, array('absolute' => TRUE)),
'attributes' => array('target' => array('_blank')),
);
}
}
}
/**
* Implements hook_menu_insert().
*/
function menu_block_menu_insert($menu) {
if (!empty($menu['menu_block_menu_order'])) {
menu_block_menu_order_set_menu($menu['menu_name'], TRUE);
}
}
/**
* Implements hook_menu_update().
*/
function menu_block_menu_update($menu) {
if (isset($menu['menu_block_menu_order'])) {
menu_block_menu_order_set_menu($menu['menu_name'], $menu['menu_block_menu_order']);
}
}
/**
* Implements hook_menu_delete().
*/
function menu_block_menu_delete($menu) {
// Delete menu block variables.
foreach (variable_get('menu_block_ids', array()) as $delta) {
$config = menu_block_get_config($delta);
if ($config['menu_name'] === $menu['menu_name']) {
menu_block_delete($delta);
}
}
menu_block_menu_order_set_menu($menu['menu_name'], FALSE);
}
/**
* Delete a menu block.
*
* @param string $delta
* The delta of the menu block.
*/
function menu_block_delete($delta) {
// Since this used to be a form callback, prevent unintentional uses.
if (is_array($delta)) {
variable_set('menu_rebuild_needed', TRUE);
return;
}
$block_ids = variable_get('menu_block_ids', array());
$index = array_search($delta, $block_ids);
if ($index !== FALSE && $config = menu_block_get_config($delta)) {
module_invoke_all('menu_block_delete', $config);
// Remove the delta from the list of custom IDs.
unset($block_ids[$index]);
sort($block_ids);
variable_set('menu_block_ids', $block_ids);
// Remove all the individual variables.
$variable_keys = array_keys(menu_block_default_config());
foreach ($variable_keys as $key) {
variable_del("menu_block_{$delta}_{$key}");
}
}
}
/**
* Implements hook_menu_block_delete() on behalf of block.module.
*/
function block_menu_block_delete(array $config) {
db_delete('block')
->condition('module', 'menu_block')
->condition('delta', $config['delta'])
->execute();
db_delete('block_role')
->condition('module', 'menu_block')
->condition('delta', $config['delta'])
->execute();
}
/**
* Implements hook_menu_block_delete() on behalf of node.module.
*/
function node_menu_block_delete(array $config) {
db_delete('block_node_type')
->condition('module', 'menu_block')
->condition('delta', $config['delta'])
->execute();
}
/**
* Implements hook_form_FORM_ID_alter().
*/
function menu_block_form_menu_edit_menu_alter(&$form, &$form_state) {
$menus = variable_get('menu_block_menu_order', array('main-menu' => '', 'user-menu' => ''));
$form['menu_block_menu_order'] = array(
'#type' => 'checkbox',
'#title' => t('Include this menu in the <em>"the menu selected by the page"</em> menu available to menu blocks.'),
'#default_value' => isset($menus[$form['old_name']['#value']]),
);
}
/**
* Add or remove a menu from the menu_block_menu_order variable.
*
* @param string $menu_name
* A menu machine name.
* @param mixed $status
* If $status evaluates to TRUE, the menu will be added. If $status evaluates
* to FALSE, the menu will be removed.
*/
function menu_block_menu_order_set_menu($menu_name, $status) {
$menus = variable_get('menu_block_menu_order', array('main-menu' => '', 'user-menu' => ''));
if ($status && !isset($menus[$menu_name])) {
$menus[$menu_name] = '';