You are here

site_map.module in Site map 5

Original author: Nic Ivy Now maintained by by Fredrik Jonsson fredrik at combonet dot se

File

site_map.module
View source
<?php

/**
 * @file
 * Original author: Nic Ivy
 * Now maintained by by Fredrik Jonsson fredrik at combonet dot se
 */

/**
 * Implementation of hook_help().
 */
function site_map_help($section) {
  switch ($section) {
    case 'sitemap':
      $output = _sitemap_get_message();
      return $output ? '<p>' . $output . '</p>' : '';
  }
}

/**
 * Implementation of hook_perm().
 */
function site_map_perm() {
  return array(
    'access site map',
  );
}

/**
 * Implementation of hook_settings().
 */
function site_map_admin_settings() {

  // Field to set site map message. Nifty language support from the catcha module,thanks.
  if (module_exists('locale')) {
    $langs = locale_supported_languages();
    $form['site_map_message'] = array(
      '#type' => 'fieldset',
      '#title' => t('Site map message'),
      '#description' => t('Define a message to be displayed above the site map.'),
    );
    foreach ($langs['name'] as $lang_code => $lang_name) {
      $form['site_map_message']["site_map_message_{$lang_code}"] = array(
        '#type' => 'textarea',
        '#title' => t('For language %lang_name (code %lang_code)', array(
          '%lang_name' => $lang_name,
          '%lang_code' => $lang_code,
        )),
        '#default_value' => _sitemap_get_message($lang_code),
        '#cols' => 60,
        '#rows' => 5,
      );
    }
  }
  else {
    $form['site_map_message'] = array(
      '#type' => 'textarea',
      '#title' => t('Site map message'),
      '#default_value' => _sitemap_get_message(),
      '#cols' => 60,
      '#rows' => 5,
      '#description' => t('Define a message to be displayed above the site map.'),
    );
  }
  $form['site_map_content'] = array(
    '#type' => 'fieldset',
    '#title' => t('Site map content'),
  );
  $form['site_map_content']['site_map_show_front'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show front page'),
    '#return_value' => 1,
    '#default_value' => variable_get('site_map_show_front', 1),
    '#description' => t('When enabled, this option will include the front page in the site map.'),
  );
  $form['site_map_content']['site_map_show_blogs'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show active blog authors'),
    '#return_value' => 1,
    '#default_value' => variable_get('site_map_show_blogs', 1),
    '#description' => t('When enabled, this option will show the 10 most active blog authors.'),
  );
  $book_options = array();
  if (module_exists('book')) {
    $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = 0 ORDER BY b.weight, n.title'));
    while ($row = db_fetch_object($result)) {
      $book_options[$row->nid] = $row->title;
    }
  }
  $form['site_map_content']['site_map_show_books'] = array(
    '#type' => 'select',
    '#title' => t('Books to include in the site map'),
    '#default_value' => variable_get('site_map_show_books', array()),
    '#options' => $book_options,
    '#multiple' => TRUE,
    '#description' => t('Ctrl-click (Windows) or Command-click (Mac) to select more than one value.'),
  );
  $menu_options = array();
  $menu_options = menu_get_root_menus();
  $form['site_map_content']['site_map_show_menus'] = array(
    '#type' => 'select',
    '#title' => t('Menus to include in the site map'),
    '#default_value' => variable_get('site_map_show_menus', array()),
    '#options' => $menu_options,
    '#multiple' => TRUE,
    '#description' => t('Ctrl-click (Windows) or Command-click (Mac) to select more than one value.'),
  );
  $form['site_map_content']['site_map_show_faq'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show FAQ content'),
    '#return_value' => 1,
    '#default_value' => variable_get('site_map_show_faq', 1),
    '#description' => t('When enabled, this option will include the content from the FAQ module in the site map.'),
  );
  $vocab_options = array();
  if (module_exists('taxonomy')) {
    foreach (taxonomy_get_vocabularies() as $vocabulary) {
      $vocab_options[$vocabulary->vid] = $vocabulary->name;
    }
  }
  $form['site_map_content']['site_map_show_vocabularies'] = array(
    '#type' => 'select',
    '#title' => t('Categories to include in the site map'),
    '#default_value' => variable_get('site_map_show_vocabularies', array()),
    '#options' => $vocab_options,
    '#multiple' => TRUE,
    '#description' => t('Ctrl-click (Windows) or Command-click (Mac) to select more than one value.'),
  );
  $form['site_map_content_options'] = array(
    '#type' => 'fieldset',
    '#title' => t('Categories settings'),
  );
  $form['site_map_content_options']['site_map_books_expanded'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show books expanded'),
    '#return_value' => 1,
    '#default_value' => variable_get('site_map_books_expanded', 1),
    '#description' => t('When enabled, this option will show all children pages for each book.'),
  );
  $form['site_map_content_options']['site_map_show_count'] = array(
    '#type' => 'checkbox',
    '#title' => t('Show node counts by categories'),
    '#return_value' => 1,
    '#default_value' => variable_get('site_map_show_count', 1),
    '#description' => t('When enabled, this option will show the number of nodes in each taxonomy term.'),
  );
  $form['site_map_content_options']['site_map_categories_depth'] = array(
    '#type' => 'textfield',
    '#title' => t('Categories depth'),
    '#default_value' => variable_get('site_map_categories_depth', 'all'),
    '#size' => 3,
    '#maxlength' => 10,
    '#description' => t('Specify how many subcategories should be included on the categorie page. Enter "all" to include all subcategories,"0" to include no subcategories, or "-1" not to append the depth at all.'),
  );
  $form['site_map_rss_options'] = array(
    '#type' => 'fieldset',
    '#title' => t('RSS settings'),
  );
  $form['site_map_rss_options']['site_map_show_rss_links'] = array(
    '#type' => 'checkbox',
    '#title' => t('Include RSS links'),
    '#return_value' => 1,
    '#default_value' => variable_get('site_map_show_rss_links', 1),
    '#description' => t('When enabled, this option will show links to the RSS feeds for each category and blog.'),
  );
  $form['site_map_rss_options']['site_map_rss_depth'] = array(
    '#type' => 'textfield',
    '#title' => t('RSS feed depth'),
    '#default_value' => variable_get('site_map_rss_depth', 'all'),
    '#size' => 3,
    '#maxlength' => 10,
    '#description' => t('Specify how many subcategories should be included in the RSS feed. Enter "all" to include all subcategories or "0" to include no subcategories.'),
  );
  return system_settings_form($form);
}

/**
 * Implementation of hook_menu().
 */
function site_map_menu($may_cache) {
  $items = array();
  if ($may_cache) {
    $items[] = array(
      'path' => 'admin/settings/sitemap',
      'title' => t('Site map'),
      'description' => t('Control what should be displayed on the site map.'),
      'callback' => 'drupal_get_form',
      'callback arguments' => 'site_map_admin_settings',
      'access' => user_access('administer site configuration'),
      'type' => MENU_NORMAL_ITEM,
    );
    $items[] = array(
      'path' => 'sitemap',
      'title' => t('Site map'),
      'description' => t('Display a site map with RSS feeds.'),
      'callback' => 'site_map_page',
      'access' => user_access('access site map'),
      'type' => MENU_SUGGESTED_ITEM,
    );
  }
  return $items;
}

/**
 * Implementation of hook_block().
 */
function site_map_block($op = 'list', $delta = 0) {
  if ($op == 'list') {
    $blocks[0]['info'] = t('Syndicate (site map)');
    return $blocks;
  }
  else {
    if ($op == 'view') {
      if (user_access('access content')) {
        $block['subject'] = t('Syndicate');
        if (arg(0) == 'blog') {
          $uid = arg(1);
          $feedurl = is_numeric($uid) ? "blog/{$uid}/feed" : 'blog/feed';
        }
        else {
          $feedurl = 'rss.xml';
        }
        $block['content'] = theme('feed_icon', url($feedurl));
        $block['content'] .= '<div class="more-link">' . l(t('more'), 'sitemap', array(
          'title' => t('View the site map to see more RSS feeds.'),
        )) . "</div>\n";
        return $block;
      }
    }
  }
}

/**
 * Menu callback for the site map.
 */
function site_map_page() {

  // Set breadcrumbs
  $breadcrumb = array(
    array(
      'path' => 'sitemap',
    ),
  );
  menu_set_location($breadcrumb);
  return theme('site_map_display');
}
function theme_site_map_display() {
  $output = '';
  if (variable_get('site_map_show_rss_links', 1)) {
    $output .= '<p><span class="rss">' . theme('site_map_feed_icon', NULL) . '</span> ' . t('This is a link to a content RSS feed');
    if (module_exists('commentrss')) {
      $output .= '<br /><span class="rss">' . theme('site_map_feed_icon', NULL, 'comment') . '</span> ' . t('This is a link to a comment RSS feed');
    }
    $output .= '</p>';
  }
  if (variable_get('site_map_show_front', 1)) {
    $output .= _site_map_front_page();
  }
  if (variable_get('site_map_show_blogs', 1)) {
    $output .= _site_map_blogs();
  }

  /*   $output .= _site_map_audio(); */

  /*   $output .= _site_map_video(); */

  // Compile the books trees.
  $output .= _site_map_books();

  // Compile the menu trees.
  $output .= _site_map_menus();
  if (variable_get('site_map_show_faq', 1)) {
    $output .= _site_map_faq();
  }

  // Compile the vocabulary trees.
  $output .= _site_map_taxonomys();

  // Invoke all custom modules and get themed HTML to be integrated into the site map.
  $additional = module_invoke_all('site_map');
  foreach ($additional as $themed_site_map_code) {
    $output .= $themed_site_map_code;
  }
  $output = '<div class="site-map">' . $output . '</div>';
  return $output;
}
function theme_site_map_feed_icon($url, $type = 'node') {
  switch ($type) {
    case 'node':
      $output = theme('image', drupal_get_path('module', 'site_map') . '/feed-small.png', t('Syndicate content'), t('Syndicate content'));
      if ($url) {
        $output = '<a href="' . check_url($url) . '" class="feed-link">' . $output . '</a>';
      }
      break;
    case 'comment':
      $output = theme('image', drupal_get_path('module', 'site_map') . '/feed-small-comment.png', t('Syndicate comments'), t('Syndicate comments'));
      if ($url) {
        $output = '<a href="' . check_url($url) . '" class="feed-link">' . $output . '</a>';
      }
      break;
  }
  return $output;
}
function _site_map_front_page() {
  $title = t('Front page');
  $output = l(t("Front page of %sn", array(
    "%sn" => variable_get('site_name', 'Drupal'),
  )), '<front>', NULL, NULL, NULL, FALSE, TRUE) . (variable_get('site_map_show_rss_links', 1) ? ' ' . theme('site_map_feed_icon', url('rss.xml')) . (module_exists('commentrss') ? ' ' . theme('site_map_feed_icon', url('crss'), 'comment') : '') : '');
  $output = theme('box', $title, $output);
  return $output;
}

/**
 * Render the latest blog authors
 */
function _site_map_blogs() {
  if (module_exists('blog')) {
    $title = t('Blogs');
    $output = '<div class="description">' . t("Community blog and recent blog authors at %sn.", array(
      "%sn" => variable_get('site_name', 'Drupal'),
    )) . '</div>';
    $blogs = array();
    $blogs[] .= l(t('All blogs'), 'blog') . (variable_get('site_map_show_rss_links', 1) ? ' ' . theme('site_map_feed_icon', url('blog/feed')) : '');
    $sql = "SELECT DISTINCT u.uid, u.name, count(u.uid) AS numitems\n      FROM {node} n\n      INNER JOIN {users} u ON u.uid = n.uid\n      WHERE n.type = 'blog' AND n.status = 1\n      GROUP BY u.uid\n      ORDER BY numitems DESC, u.name";
    $result = db_query_range($sql, 0, 10);
    while ($blog = db_fetch_object($result)) {
      $blogs[] = l(t("!s's blog", array(
        "!s" => $blog->name,
      )), "blog/{$blog->uid}") . ' (' . $blog->numitems . ')' . (variable_get('site_map_show_rss_links', 1) ? ' ' . theme('site_map_feed_icon', url("blog/{$blog->uid}/feed")) : '');
    }
    $output .= theme('item_list', $blogs);
    $output = theme('box', $title, $output);
  }
  return $output;
}
function _site_map_audio() {
  if (module_exists('audio')) {
    $title = t('Audio');
    $output = l(t('Audio content'), 'audio') . (variable_get('site_map_show_rss_links', 1) ? ' ' . theme('site_map_feed_icon', url('audio/feed')) : '');
    $output = theme('box', $title, $output);
  }
  return $output;
}
function _site_map_video() {
  if (module_exists('video')) {
    $title = t('Video');
    $output = l(t('Video content'), 'video') . (variable_get('site_map_show_rss_links', 1) ? ' ' . theme('site_map_feed_icon', url('video/feed')) : '');
    $output = theme('box', $title, $output);
  }
  return $output;
}

/**
 * Render books
 */
function _site_map_books() {
  if (module_exists('book') && ($nids = variable_get('site_map_show_books', array()))) {
    $title = t('Books');
    $description = '<div class="description">' . t("Books at %sn.", array(
      "%sn" => variable_get('site_name', 'Drupal'),
    )) . '</div>';
    $result = db_query(db_rewrite_sql('SELECT n.nid, n.title FROM {node} n INNER JOIN {book} b ON n.vid = b.vid WHERE b.parent = 0 AND n.status = 1 AND n.moderate = 0 AND n.nid IN (%s) ORDER BY b.weight, n.title'), implode(',', $nids));
    while ($node = db_fetch_object($result)) {
      $book_display .= '<h3>' . l($node->title, 'node/' . $node->nid) . '</h3>';
      $book_display .= book_tree($node->nid, 5, array(
        variable_get('site_map_books_expanded', 1) ? TRUE : '',
      ));
    }
    if ($book_display) {
      $output = theme('box', $title, $description . $book_display);
    }
  }
  return $output;
}

/**
 * Render menus
 */
function _site_map_menus() {
  $output = '';
  if ($mids = variable_get('site_map_show_menus', array())) {
    $menu = menu_get_menu();
    foreach ($mids as $mid) {
      $menu_display = _site_map_menu_tree($mid, $menu);
      if (!empty($menu_display)) {
        $title = $menu['visible'][$mid]['title'];
        $output .= theme('box', $title, $menu_display);
      }
    }
  }
  return $output;
}
function _site_map_faq() {
  if (module_exists('faq')) {
    $title = variable_get('faq_title', t('Frequently Asked Questions'));
    $output = faq_get_faq_list();
    $output = theme('box', $title, $output);
  }
  return $output;
}
function _site_map_menu_tree($pid = 1, $menu = NULL) {

  // based on functions theme_menu_tree and menu_tree
  if (isset($menu['visible'][$pid]) && $menu['visible'][$pid]['children']) {
    foreach ($menu['visible'][$pid]['children'] as $mid) {
      $children = isset($menu['visible'][$mid]['children']) ? $menu['visible'][$mid]['children'] : NULL;
      $menu_tree .= theme('menu_item', $mid, _site_map_menu_tree($mid, $menu), count($children) == 0);
    }
  }
  if ($menu_tree) {
    $output = '<ul class="tree">' . $menu_tree . '</ul>';
  }
  return $output;
}

/**
 * This function can be called from blocks or pages as desired.
 */
function _site_map_taxonomys() {
  if (module_exists('taxonomy') && ($vids = variable_get('site_map_show_vocabularies', array()))) {
    $result = db_query('SELECT vid, name, description
      FROM {vocabulary} WHERE vid IN (%s) ORDER BY weight ASC, name', implode(',', $vids));
    while ($t = db_fetch_object($result)) {
      $output .= _site_map_taxonomy_tree($t->vid, $t->name, $t->description);
    }
  }
  return $output;
}

/**
 * Render taxonomy tree
 *
 * @param $tree The results of taxonomy_get_tree() with optional 'count' fields.
 * @param $name An optional name for the tree. (Default: NULL)
 * @param $description An optional description of the tree. (Default: NULL)
 * @return A string representing a rendered tree.
 */
function _site_map_taxonomy_tree($vid, $name = NULL, $description = NULL) {
  if ($vid == variable_get('forum_nav_vocabulary', '')) {
    $title = l($name, 'forum');
  }
  else {
    $title = $name ? check_plain(t($name)) : '';
  }
  $title .= module_exists('commentrss') ? ' ' . theme('site_map_feed_icon', url("crss/vocab/{$vid}"), 'comment') : '';
  $last_depth = -1;
  $rss_depth = variable_get('site_map_rss_depth', 'all');
  if (!is_numeric($rss_depth) || $rss_depth < 0) {
    $rss_depth = 'all';
  }
  $cat_depth = variable_get('site_map_categories_depth', 'all');
  if (!is_numeric($cat_depth)) {
    $cat_depth = 'all';
  }
  $output = $description ? '<div class="description">' . check_plain($description) . '</div>' : '';
  $output .= '<div class="tree">';

  // taxonomy_get_tree() honors access controls
  $tree = taxonomy_get_tree($vid);
  foreach ($tree as $term) {

    // Adjust the depth of the <ul> based on the change
    // in $term->depth since the $last_depth.
    if ($term->depth > $last_depth) {
      for ($i = 0; $i < $term->depth - $last_depth; $i++) {
        $output .= '<ul>';
      }
    }
    else {
      if ($term->depth < $last_depth) {
        for ($i = 0; $i < $last_depth - $term->depth; $i++) {
          $output .= '</ul>';
        }
      }
    }

    // Display the $term.
    $output .= '<li>';
    $term->count = taxonomy_term_count_nodes($term->tid);
    if ($term->count) {
      if ($cat_depth < 0) {
        $output .= l($term->name, taxonomy_term_path($term), array(
          'title' => $term->description,
        ));
      }
      else {
        $output .= l($term->name, "taxonomy/term/{$term->tid}/{$cat_depth}", array(
          'title' => $term->description,
        ));
      }
    }
    else {
      $output .= check_plain($term->name);
    }
    if (variable_get('site_map_show_count', 1)) {
      $output .= " ({$term->count})";
    }
    if (variable_get('site_map_show_rss_links', 1)) {
      $output .= ' ' . theme('site_map_feed_icon', url("taxonomy/term/{$term->tid}/{$rss_depth}/feed"));
      $output .= module_exists('commentrss') ? ' ' . theme('site_map_feed_icon', url("crss/term/{$term->tid}"), 'comment') : '';
    }
    $output .= "</li>\n";

    // Reset $last_depth in preparation for the next $term.
    $last_depth = $term->depth;
  }

  // Bring the depth back to where it began, -1.
  if ($last_depth > -1) {
    for ($i = 0; $i < $last_depth + 1; $i++) {
      $output .= '</ul>';
    }
  }
  $output .= "</div>\n";
  $output = theme('box', $title, $output);
  return $output;
}

/**
 * Get the message which appears above the site map.
 * If the locale module is enabled, an optional language code can be given
 */
function _sitemap_get_message($lang_code = NULL) {
  if (module_exists('locale')) {
    if ($lang_code == NULL) {
      global $locale;
      $lang_code = $locale;
    }
    $message = filter_xss_admin(variable_get("site_map_message_{$lang_code}", ''));
  }
  else {
    $message = filter_xss_admin(variable_get('site_map_message', ''));
  }
  return $message;
}

Functions

Namesort descending Description
site_map_admin_settings Implementation of hook_settings().
site_map_block Implementation of hook_block().
site_map_help Implementation of hook_help().
site_map_menu Implementation of hook_menu().
site_map_page Menu callback for the site map.
site_map_perm Implementation of hook_perm().
theme_site_map_display
theme_site_map_feed_icon
_sitemap_get_message Get the message which appears above the site map. If the locale module is enabled, an optional language code can be given
_site_map_audio
_site_map_blogs Render the latest blog authors
_site_map_books Render books
_site_map_faq
_site_map_front_page
_site_map_menus Render menus
_site_map_menu_tree
_site_map_taxonomys This function can be called from blocks or pages as desired.
_site_map_taxonomy_tree Render taxonomy tree
_site_map_video