You are here

webmaster_menu.module in Webmaster menu 7

Display a dropdown menu at the top of the window.

File

webmaster_menu.module
View source
<?php

/**
 * @file
 * Display a dropdown menu at the top of the window.
 */

/**
 * Implements hook_menu().
 */
function webmaster_menu_menu() {

  // Config page.
  $items['admin/config/webmaster_menu'] = array(
    'title' => 'Webmaster menu configuration',
    'description' => 'Configure Webmaster menu',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'webmaster_menu_config_form',
    ),
    'access arguments' => array(
      'administer webmaster menu',
    ),
    'file' => 'webmaster_menu.config_page.inc',
  );
  return $items;
}

/**
 *  Determines if user has access to webmaster menu
 */
function webmaster_menu_enabled() {
  global $user;

  // Determine if the "webmaster_menu_show_root" setting grants access
  if ((int) $user->uid === 1 && (bool) variable_get('webmaster_menu_show_root', 1)) {
    return TRUE;
  }

  // Determine if the "webmaster_menu_show_roles" setting grants access
  // This is done by intersecting the roles that are enabled in webmaster menu
  // settings with the roles that the current user has (plus anonymous).
  $enabled_roles = variable_get('webmaster_menu_roles', array());
  $user_roles = array_keys($user->roles);

  // Add anonymous (role id: 1)
  array_push($user_roles, 1);
  $matched_roles = array_intersect($enabled_roles, $user_roles);
  return !empty($matched_roles);
}

/**
 * Implements hook_page_alter().
 */
function webmaster_menu_page_alter(&$page) {

  // Do not show menu, if user hasn't access to it
  if (!webmaster_menu_enabled()) {
    return '';
  }

  // Do not display with core overlay, this creates duplicates menus, one in the
  // main page and one in the overlay iframe
  if (function_exists('overlay_get_mode')) {
    if (overlay_get_mode() == 'child') {
      return FALSE;
    }
  }

  // Do not show menu on dialog page in the "media" module.
  if ($page['#theme'] == 'media_dialog_page') {
    return '';
  }

  // Do not show menu on dialog created by references dialog module (https://drupal.org/project/references_dialog)
  if ($page['#theme'] == 'references_dialog_page') {
    return '';
  }
  $page['page_top']['webmaster_menu'] = array(
    '#markup' => webmaster_menu_output(),
    '#weight' => -50,
  );
  $settings = array(
    'has_admin_menu' => module_exists('admin_menu'),
  );
  $page['page_top']['webmaster_menu']['#attached']['js'][] = array(
    'data' => array(
      'webmaster_menu' => $settings,
    ),
    'type' => 'setting',
  );
  if (variable_get('webmaster_menu_positioning', 'fixed') == 'fixed') {
    drupal_add_js(drupal_get_path('module', 'webmaster_menu') . '/webmaster_menu_fixed.js');
  }
  else {
    if (module_exists('admin_menu') || module_exists('toolbar')) {
      drupal_add_js(drupal_get_path('module', 'webmaster_menu') . '/webmaster_menu_relative.js');
    }
  }
}

/**
 * Implementation of hook_overlay_child_initialize();
 *
 * Push down the overlay to prevent webmaster menu covering the top of the overlay,
 * also integrates with admin menu.
 */
function webmaster_menu_overlay_child_initialize() {
  global $user;
  $offset = 0;
  $show_webmaster_menu = webmaster_menu_enabled();
  if ($show_webmaster_menu) {
    $offset += 28;
  }
  if (user_access('access administration menu')) {
    $offset += 28;
  }
  if ($offset) {
    drupal_add_css('body.overlay { padding-top: ' . $offset . 'px!important; }', array(
      'type' => 'inline',
      'group' => CSS_THEME + 1,
    ));
  }
}

/**
 *  Helper to create a data structure representing a menu item in the dropdown.
 *
 * @param string $title
 *   The title of the menu item.
 * @param string $href
 *   The link of the menu item.
 * @param array $classes
 *   CSS classes that will be put on the menu item (with default theming, these
 *   are put on the <li> tag).
 */
function webmaster_menu_create_menu_item($title, $href, $classes = array(), $localized_options = array()) {
  return array(
    'title' => $title,
    'href' => $href,
    'classes' => $classes,
    'localized_options' => $localized_options,
    'children' => NULL,
  );
}

/**
 *  Create the webmaster menu.
 *
 *  If it turns out not to include any items besides Home and Logout, an empty
 *  string is returned.
 */
function webmaster_menu_output() {
  $menu_name = variable_get('webmaster_menu_menu', '');
  $tree = webmaster_menu_get_tree($menu_name);
  $extra_menu_name = variable_get('webmaster_menu_extra_menu', '_no_extra_menu_');
  if ($extra_menu_name != '_no_extra_menu_') {
    $extra_tree = webmaster_menu_get_tree($extra_menu_name);
    foreach ($extra_tree as $subtree) {
      array_push($tree, $subtree);
    }
  }
  if (count($tree) == 0) {

    // Don't show any menu if there are no links (besides Home and Logout).
    // (this behaviour was decided here: http://drupal.org/node/1464194)
    return '';
  }
  if (variable_get('webmaster_menu_add_home', TRUE)) {
    $home = webmaster_menu_create_menu_item(t('Home'), '<front>', array(
      'home',
    ));
    $home_menu_name = variable_get('webmaster_menu_home_menu', '_no_menu_');
    if ($home_menu_name != '_no_menu_') {
      $home['children'] = webmaster_menu_get_tree($home_menu_name);
    }
    array_unshift($tree, $home);
  }
  if (variable_get('webmaster_menu_add_logout', TRUE) && user_is_logged_in()) {
    $logout = webmaster_menu_create_menu_item(t('Log out'), 'user/logout', array(
      'logout',
    ));

    // allow other modules to alter the logout link
    drupal_alter('webmaster_menu_logout', $logout);
    array_push($tree, $logout);
  }
  return theme('webmaster_menu_toolbar', array(
    'tree' => $tree,
  ));
}

/**
 * Render the toolbar.
 *
 * @param array $variables
 *   - tree: A hierarical data structure suitable for
 *           theme_webmaster_menu_tree().
 *
 * @ingroup themeable
 */
function theme_webmaster_menu_toolbar($variables) {
  drupal_add_css(drupal_get_path('module', 'webmaster_menu') . '/webmaster_menu.css');
  $tree = $variables['tree'];
  $html = '<div class="webmaster-menu overlay-displace-top">';
  $html .= theme('webmaster_menu_tree', array(
    'tree' => $tree,
  ));
  $html .= '</div>';
  return $html;
}

/**
 * Render a menu tree.
 *
 * @param array $variables
 *   An associative array containing:
 *   - tree: An array of menu items. Each menu item is
 *           suitable for being rendered by theme_webmaster_menu_subtree
 *
 * @ingroup themeable
 */
function theme_webmaster_menu_tree($variables) {
  $menu_items = $variables['tree'];
  $html = '<ul class="menu">';
  foreach ($menu_items as $menu_item) {
    $html .= theme('webmaster_menu_item', array(
      'menu_item' => $menu_item,
    ));
  }
  $html .= '</ul>';
  return $html;
}

/**
 * Render a menu item, including its children.
 *
 * @param array $variables
 *   An associative array containing:
 *   - menu_item: An associative array containing:
 *       - title: The title of the menu link
 *       - href: The link
 *       - classes: An array of classes
 *       - children: An array of menu items. Suitable for being rendered by
 *                   theme_webmaster_menu_tree.
 *
 * @ingroup themeable
 */
function theme_webmaster_menu_item($variables) {
  $menu_item = $variables['menu_item'];
  $html = '<li class="' . implode(" ", $menu_item['classes']) . '">';
  $html .= l($menu_item['title'], $menu_item['href'], $menu_item['localized_options']);
  if (isset($menu_item['children'])) {
    $html .= theme('webmaster_menu_tree', array(
      'tree' => $menu_item['children'],
    ));
  }
  $html .= '</li>';
  return $html;
}

/**
 * Get a tree.
 *
 * @param string $menu_name
 *   The name of the menu.
 *
 * @return array
 *   A data structure suitable for theme_webmaster_menu_tree().
 */
function webmaster_menu_get_tree($menu_name) {
  $tree = menu_tree_all_data($menu_name);

  // Allow i18n module to translate strings where available.
  if (module_exists('i18n_menu')) {
    $tree = i18n_menu_localize_tree($tree);
  }
  $menu_items = webmaster_menu_create_datastructure_from_tree($tree);
  return $menu_items;
}

/**
 * Build a datastructure suitable for theme_webmaster_menu_tree.
 *
 * @param array $tree
 *   A tree structure like the returned by menu_tree_all_data.
 *
 * @return array
 *   A data structure suitable for theme_webmaster_menu_tree().
 */
function webmaster_menu_create_datastructure_from_tree($tree) {
  $new_menu_list = array();
  foreach ($tree as $element) {

    // Skip disabled links.
    if ($element['link']['hidden'] == 1) {
      continue;
    }
    $new_menu_item = webmaster_menu_create_menu_item($element['link']['title'], $element['link']['href'], array(), $element['link']['localized_options']);
    if (isset($element['below']) && count($element['below']) > 0) {
      $new_menu_item['classes'][] = 'expanded';
      $new_menu_item['children'] = webmaster_menu_create_datastructure_from_tree($element['below']);
    }
    $new_menu_list[] = $new_menu_item;
  }
  return $new_menu_list;
}

/**
 * Implements hook_permission().
 */
function webmaster_menu_permission() {
  return array(
    'administer webmaster menu' => array(
      'title' => t('Administer webmaster menu'),
      'description' => t('Configure webmaster menu'),
    ),
  );
}

/**
 * Implements hook_theme().
 */
function webmaster_menu_theme() {
  return array(
    'webmaster_menu_toolbar' => array(
      'variables' => array(
        'tree' => array(),
      ),
    ),
    'webmaster_menu_tree' => array(
      'variables' => array(
        'tree' => array(),
      ),
    ),
    'webmaster_menu_item' => array(
      'variables' => array(
        'menu_item' => array(),
      ),
    ),
  );
}

Functions

Namesort descending Description
theme_webmaster_menu_item Render a menu item, including its children.
theme_webmaster_menu_toolbar Render the toolbar.
theme_webmaster_menu_tree Render a menu tree.
webmaster_menu_create_datastructure_from_tree Build a datastructure suitable for theme_webmaster_menu_tree.
webmaster_menu_create_menu_item Helper to create a data structure representing a menu item in the dropdown.
webmaster_menu_enabled Determines if user has access to webmaster menu
webmaster_menu_get_tree Get a tree.
webmaster_menu_menu Implements hook_menu().
webmaster_menu_output Create the webmaster menu.
webmaster_menu_overlay_child_initialize Implementation of hook_overlay_child_initialize();
webmaster_menu_page_alter Implements hook_page_alter().
webmaster_menu_permission Implements hook_permission().
webmaster_menu_theme Implements hook_theme().