View source
<?php
function footermap_help($path, $arg) {
switch ($path) {
case 'admin/help#footermap':
return '<p>' . t('Displays a dynamic, flexible sitemap at the bottom of a page via the Drupal block system. This is routinely used as a way of providing quick links at the bottom of the page. It is not advised to generate a full site map at the footer without caching.') . '</p>';
break;
}
}
function footermap_menu() {
$items = array();
$items['admin/settings/footermap'] = array(
'title' => 'footermap',
'description' => 'Configure settings that footermap will use to dynamically generate the sitemap.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'footermap_settings',
),
'access arguments' => array(
'administer site configuration',
),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function footermap_settings() {
$form = array();
$form['recurse_limit'] = array(
'#type' => 'textfield',
'#title' => t('Recurse Limit'),
'#description' => t('Limit the footermap recursion function to <em>N</em> recursions. The default is 0, unlimited. This is useful if you have a deep hierarchy of child menu items that you do not want to display in the footermap.'),
'#size' => 3,
'#max_length' => 3,
'#default_value' => variable_get('recurse_limit', 0),
);
$form['footermap_heading'] = array(
'#type' => 'radios',
'#title' => t('Enable Menu Heading'),
'#description' => t('This will enable the menu-name property (e.g. navigation, user-menu) to be displayed as the heading above each menu column. This is nice if you have your menus setup in distinct blocks or controlled via the recurse-limit property above.'),
'#options' => array(
t('No'),
t('Yes'),
),
'#default_value' => variable_get('footermap_heading', 0),
);
$form['top_menu'] = array(
'#type' => 'textfield',
'#title' => t('Drupal Root Menu'),
'#description' => t('Set the menu id to use as the top level. Default is to start at 0 i .e. primary menus - primary, secondary, and navigation menus'),
'#default_value' => variable_get('top_menu', variable_get('menu_primary_menu', 0)),
'#max_length' => 3,
'#size' => 3,
);
$avail_menus = footermap_get_primary_menus(variable_get('top_menu', variable_get('menu_primary_menu', 0)));
$form['avail_menus'] = array(
'#type' => 'checkboxes',
'#title' => t('Available menus'),
'#description' => t('Limit the available menus under the "top menu" setting above to the following menu items and their children.'),
'#options' => $avail_menus,
'#default_value' => variable_get('avail_menus', array()),
);
$form['sys_menus'] = array(
'#type' => 'radios',
'#title' => t('Enable System Menu Items'),
'#description' => t('Enable system menus to be displayed. This is disabled by default, bu t is known to not work with Views menus because of a bug in <a href="http://api.drupal.org/api/function/hook_menu_link_alter/7">hook_menu_link_alter</a>'),
'#options' => array(
t('No'),
t('Yes'),
),
'#default_value' => variable_get('sys_menus', 0),
);
$form['footer_legacy'] = array(
'#type' => 'radios',
'#title' => t('Enable Legacy Footermap'),
'#description' => t('Enable footermap to be inserted in the $closure as well as in a block. You pr obably do not want to enable this unless you\'re upgrading from an older version.'),
'#options' => array(
t('No'),
t('Yes'),
),
'#default_value' => variable_get('footer_legacy', 0),
);
$form['footer_cache'] = array(
'#type' => 'radios',
'#title' => t('Enable Footermap Cache'),
'#description' => t('Enable caching of footermap. This is only recommended if you are using the legacy footeramp. This option will be removed in the future when the legacy footeramp is deprecated. Caching is done via the block system.'),
'#options' => array(
t('No'),
t('Yes'),
),
'#default_value' => variable_get('footer_cache', 0),
);
return system_settings_form($form);
}
function footermap_menu_link_alter(&$item, $menu) {
if (variable_get('footer_cache', 0) == 0) {
return;
}
$footercache = cache_get('footermap', 'cache');
$mlidregex = '/' . $item['mlid'] . '/';
if (preg_match($mlidregex, $footercache->data) == 0) {
return;
}
cache_clear_all('footermap', 'cache');
}
function footermap_footer() {
if (variable_get('footer_legacy', 0) == 0) {
return;
}
if (variable_get('footer_cache', 0) == 1) {
$vartime = cache_get('variables', 'cache')->created;
$cached = cache_get('footermap', 'cache');
}
if (isset($o->data) && $o->created >= $vartime) {
return $cached;
}
drupal_add_css(drupal_get_path('module', 'footermap') . '/footermap.css', 'module', 'all', TRUE);
$o = _footermap_render();
if (variable_get('footer_cache', 0) == 1) {
cache_set('footermap', $o, 'cache', CACHE_TEMPORARY);
}
return $o;
}
function footermap_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$blocks = array();
$blocks[] = array(
'info' => t('Footermap block'),
'weight' => 5,
'status' => 1,
'region' => 'footer',
);
return $blocks;
}
else {
if ($op == 'view') {
drupal_add_css(drupal_get_path('module', 'footermap') . '/footermap.css', 'module', 'all', TRUE);
$block = array(
'subject' => t(''),
'content' => _footermap_render(),
);
return $block;
}
}
}
function _footermap_render() {
$recurse = variable_get('recurse_limit', 0);
$base = variable_get('top_menu', 0);
$menus = menu_get_menus(TRUE);
$mapref = array();
$disp_heading = variable_get('footermap_heading', 0);
$o = '';
footermap_get_menu($base, $mapref, $recurse, 0);
$n = 0;
foreach ($mapref as $key => $block) {
$heading = $disp_heading == 1 ? $menus[$key] : '';
$o .= '<div class="footermap-col" id="footermap-col-' . $n . ' footermap-col-' . $key . '">';
if ($heading != '') {
$o .= '<h3>' . $heading . '</h3>';
}
$o .= theme('links', $block, array(
'class' => 'footermap-item links',
)) . '</div>';
$n++;
}
$o = '<div class="footermap">' . $o . '</div>';
return $o;
}
function footermap_get_menu($mlid, &$mapref, $recurse, $level) {
global $user;
if ($recurse != 0 && $level >= $recurse) {
return;
}
$avail_menus = variable_get('avail_menus', array());
if (variable_get('sys_menus', 0) == 0) {
$system_menu = " AND ml.module <> 'system' ";
}
else {
$system_menu = ' ';
}
$sql = 'SELECT * FROM {menu_links} ml LEFT OUTER JOIN {menu_router} mr ON (ml.router_path = mr.path) WHERE ml.plid = %d AND ml.hidden = 0' . $system_menu . 'ORDER BY ml.plid, ml.weight, ml.link_title, mr.title';
$res = db_query($sql, $mlid);
while ($h = db_fetch_object($res)) {
if (!_footermap_check_menu_item($avail_menus, $h)) {
continue;
}
if (isset($h->path)) {
if (empty($h->access_callback)) {
continue;
}
$map = array();
$args = array();
$map = explode('/', $h->link_path);
if (!empty($h->to_arg_functions)) {
_menu_link_map_translate($map, $h->to_arg_functions);
}
$args = menu_unserialize($h->access_arguments, $map);
if ($h->access_callback == 'user_access') {
if (!empty($args[0])) {
if (!user_access($args[0], $user)) {
continue;
}
}
}
else {
if ($h->access_callback == 'node_access') {
if (!node_access($args[0], node_load($args[1]))) {
continue;
}
}
}
}
$mapref[$h->menu_name]['menu-' . $h->mlid] = array(
'href' => $h->link_path,
'title' => $h->link_title,
);
if ($h->has_children == 1) {
footermap_get_menu($h->mlid, $mapref, $recurse, $level + 1);
}
}
}
function footermap_get_primary_menus($top_menu) {
$ret = array();
if (!is_numeric($top_menu)) {
return $ret;
}
$res = db_query("SELECT * FROM {menu_links} WHERE plid = %d AND hidden = 0", $top_menu);
while ($menu = db_fetch_object($res)) {
$ret[$menu->menu_name] = t($menu->menu_name);
}
return $ret;
}
function _footermap_check_menu_item($avail_menus, $item) {
foreach ($avail_menus as $key => $mn) {
if ($mn === $item->menu_name) {
return TRUE;
}
}
return FALSE;
}