web/drupal/modules/xmlsitemap/xmlsitemap.module
branchdrupal
changeset 74 0ff3ba646492
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/web/drupal/modules/xmlsitemap/xmlsitemap.module	Fri Aug 21 16:26:26 2009 +0000
@@ -0,0 +1,417 @@
+<?php
+// $Id: xmlsitemap.module,v 1.20.2.66 2009/06/23 11:54:41 earnie Exp $
+
+
+/**
+ * @file
+ * Creates a sitemap compatible with the sitemaps.org schema.
+ */
+
+/**
+ * @addtogroup xmlsitemap
+ * @{
+ */
+
+/*****************************************************************************
+ * Public constants.
+ ****************************************************************************/
+
+/**
+ * The date format used in the sitemap.
+ */
+if (!defined('DATE_W3C')) {
+  define('DATE_W3C', 'Y-m-d\TH:i:s+00:00');
+}
+
+/**
+ * The timestamp of server request to avoid repeatedly generating value.
+ */
+if (!defined('REQUEST_TIME')) {
+  if (isset($_SERVER['REQUEST_TIME'])) {
+    define('REQUEST_TIME', $_SERVER['REQUEST_TIME']);
+  }
+  else {
+    define('REQUEST_TIME', time());
+  }
+}
+
+/**
+ * The flag set when a sitemap link is not enabled.
+ */
+define('XMLSITEMAP_LINK_DISABLED', 1);
+
+/**
+ * The maximum number of links in one sitemap chunk file.
+ */
+define('XMLSITEMAP_MAX_SITEMAP_LINKS', 50000);
+
+/**
+ * The maximum filesize of a sitemap chunk file.
+ */
+define('XMLSITEMAP_MAX_SITEMAP_FILESIZE', 10485760);
+
+/**
+ * The maximum number of links in one sitemap index file.
+ */
+define('XMLSITEMAP_MAX_SITEMAP_INDEX_LINKS', 1000);
+
+/**
+ * The default number of links in one sitemap chunk file.
+ */
+define('XMLSITEMAP_DEFAULT_SITEMAP_LINKS', 1000);
+
+/*****************************************************************************
+ * Drupal hooks.
+ ****************************************************************************/
+
+/**
+ * Implementation of hook_form_alter().
+ */
+function xmlsitemap_form_alter(&$form, &$form_state, $form_id) {
+  switch ($form_id) {
+    case 'locale_languages_configure_form':
+    case 'path_admin_form':
+    case 'pathauto_admin_settings':
+    case 'system_clean_url_settings':
+      $form['#submit'][] = 'xmlsitemap_settings_submit';
+      break;
+  }
+}
+
+/**
+ * Implementation of hook_help().
+ */
+function xmlsitemap_help($path, $arg) {
+  switch ($path) {
+    case 'admin/settings/xmlsitemap':
+    case 'admin/settings/xmlsitemap/engines':
+      $output = t('The sitemap is located at <a href="@sitemap">@sitemap</a>.', array('@sitemap' => url('sitemap.xml', array('absolute' => TRUE))));
+      break;
+
+    case 'admin/help#xmlsitemap':
+      $output = '<p>'. t('XML sitemap automatically creates a sitemap that conforms to the <a href="@sitemaps.org">sitemaps.org specification</a>. This helps search engines keep their search results up to date.', array('@sitemaps.org' => 'http://www.sitemaps.org')) .'</p>';
+      $output .= '<h3>'. t('Supporting modules') .'</h3>';
+      $output .= '<p>'. t('By itself, the XML sitemap module adds only the front page of your site to the sitemap. Other types of links are handled by supporting modules.') .'</p>';
+      $optional = '';
+      foreach (module_implements('xmlsitemap_description', TRUE) as $module) {
+        $function = $module .'_xmlsitemap_description';
+        $optional .= $function();
+      }
+      if (!empty($optional)) {
+        $output .= "<dl>$optional</dl>";
+      }
+      $output .= '<p>'. t('Links may be assigned a priority between 0.0 and 1.0. The default priority is 0.5. A priority of <em>Not in sitemap</em> excludes a link from the sitemap.') .'</p>';
+      $output .= '<p>'. t('For more information, see the online handbook entry for <a href="@xmlsitemap">XML sitemap module</a>.', array('@xmlsitemap' => 'http://drupal.org/handbook/modules/gsitemap')) .'</p>';
+      break;
+
+    default:
+      $output = '';
+      break;
+  }
+  return $output;
+}
+
+/**
+ * Implementation of hook_menu().
+ */
+function xmlsitemap_menu() {
+  $items = array();
+  $access_config = array('administer site configuration');
+  $access_content = array('access content');
+  $items['admin/settings/xmlsitemap'] = array(
+    'title' => 'XML sitemap',
+    'description' => 'Configure the XML sitemap.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('xmlsitemap_settings'),
+    'access arguments' => $access_config,
+    'file' => 'xmlsitemap.admin.inc',
+  );
+  $items['admin/settings/xmlsitemap/sitemap'] = array(
+    'title' => 'Sitemap',
+    'description' => 'Configure the XML sitemap.',
+    'weight' => -1,
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'file' => 'xmlsitemap.admin.inc',
+  );
+  $items['admin/settings/xmlsitemap/tools'] = array(
+    'title' => 'Tools',
+    'description' => 'Sitemap tools.',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('xmlsitemap_tools'),
+    'access arguments' => $access_config,
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'xmlsitemap.admin.inc',
+  );
+  $items['sitemap.xml'] = array(
+    'title' => 'Sitemap index',
+    'page callback' => 'xmlsitemap_output',
+    'access arguments' => $access_content,
+    'type' => MENU_CALLBACK,
+    'file' => 'xmlsitemap.pages.inc',
+  );
+  $chunk_size = variable_get('xmlsitemap_chunk_size', XMLSITEMAP_DEFAULT_SITEMAP_LINKS);
+  $link_count = xmlsitemap_link_count();
+  if ($link_count > $chunk_size) {
+    for ($chunk = 0; $chunk < $link_count / $chunk_size; ++$chunk) {
+      $items["sitemap$chunk.xml"] = array(
+        'title' => 'Sitemap !number',
+        'title arguments' => array('!number' => $chunk),
+        'page callback' => 'xmlsitemap_output',
+        'page arguments' => array((string) $chunk),
+        'access arguments' => $access_content,
+        'type' => MENU_CALLBACK,
+        'file' => 'xmlsitemap.pages.inc',
+      );
+    }
+  }
+  return $items;
+}
+
+/**
+ * Implementation of hook_perm().
+ */
+function xmlsitemap_perm() {
+  return array('override node settings', 'override profile settings');
+}
+
+/**
+ * Implementation of hook_robotstxt().
+ */
+function xmlsitemap_robotstxt() {
+  return array("Sitemap: ". url('sitemap.xml', array('absolute' => TRUE)));
+}
+
+/**
+ * Implementation of hook_xmlsitemap_operations().
+ */
+function xmlsitemap_xmlsitemap_operations() {
+  return array(
+    'delete_cache_files' => array(
+      'label' => t('Delete the sitemap cache files'),
+      'callback' => 'xmlsitemap_delete_cache_files',
+    ),
+    'flag_sitemap' => array(
+      'label' => t('Flag the sitemap as requiring update'),
+      'callback' => 'xmlsitemap_flag_sitemap',
+    ),
+  );
+}
+
+/*****************************************************************************
+ * Public functions.
+ ****************************************************************************/
+
+/**
+ * Batch callback called when the batch operations are completed.
+ */
+function xmlsitemap_batch_operations_finished($success, $results, $operations) {
+  if ($success) {
+    drupal_set_message(t('The update has been performed.'));
+  }
+  else {
+    drupal_set_message(t('An error occurred and processing did not complete.'), 'error');
+    $message = format_plural($count = count($results), '1 item successfully processed.', '@count items successfully processed.');
+    if ($count) {
+      $message .= theme('item_list', $results, t('Last items successfully processed:'));
+    }
+    drupal_set_message($message);
+  }
+}
+
+/**
+ * Return the language string used to identify the cache file for the sitemap
+ * content.
+ */
+function xmlsitemap_language_id() {
+  global $language;
+  return isset($language->language) ? $language->language : language_default('language');
+}
+
+/**
+ * Return the array for the cron limit options.
+ */
+function xmlsitemap_cron_options() {
+  return array(
+    '2000' => t('2000 rows'),
+    '1500' => t('1500 rows'),
+    '1000' => t('1000 rows'),
+    '500' => t('500 rows'),
+    '250' => t('250 rows'),
+    '100' => t('100 rows'),
+    '50' => t('50 rows'),
+    '25' => t('25 rows'),
+    '20' => t('20 rows'),
+    '15' => t('15 rows'),
+    '10' => t('10 rows'),
+    '5' => t('5 rows'),
+    '-1' => t('Do not process via cron'),
+  );
+}
+
+/**
+ * Delete the cache file used for the sitemap content, and mark the sitemap as
+ * changed.
+ */
+function xmlsitemap_delete_cache_files() {
+  $parent_directory = variable_get('xmlsitemap_cache_directory', file_directory_path() .'/xmlsitemap');
+  if (!is_dir($parent_directory)) {
+    return;
+  }
+  file_scan_directory($parent_directory, 'xsm-.*\.xml', array('.', '..', 'CVS'), 'file_delete', FALSE);
+  xmlsitemap_flag_sitemap();
+  return;
+}
+
+/**
+ * Mark the sitemap as changed, and the cache as needing update.
+ */
+function xmlsitemap_flag_sitemap() {
+  if (!variable_get('xmlsitemap_sitemap_is_changed', FALSE)) {
+    variable_set('xmlsitemap_sitemap_is_changed', TRUE);
+  }
+  if (!variable_get('xmlsitemap_sitemap_needs_update', FALSE)) {
+    variable_set('xmlsitemap_sitemap_needs_update', TRUE);
+  }
+}
+
+/**
+ * Return the number of links present in xmlsitemap table.
+ */
+function xmlsitemap_link_count() {
+  static $link_count;
+  if (!isset($link_count)) {
+    $link_count = db_result(db_query("SELECT COUNT(xsm.loc)". xmlsitemap_sitemap_query()));
+  }
+  return $link_count;
+}
+
+/**
+ * Return the number of chunk files.
+ */
+function xmlsitemap_chunk_count() {
+  $link_count = xmlsitemap_link_count();
+  $chunk_size = variable_get('xmlsitemap_chunk_size', XMLSITEMAP_DEFAULT_SITEMAP_LINKS);
+  return ceil($link_count / $chunk_size);
+}
+
+/**
+ * Return an array of sitemap priority options.
+ *
+ * @param $option
+ *  If not given, the array will include priority values from 0.0 to 1.0.
+ * - exclude: Add option to exclude item from sitemap.
+ * - default: Add option to use default priority. Only for cases where a
+ *   default priority exists.
+ * - both: Add both the default and exclude options.
+ *
+ * @return
+ *  An array of priority options.
+ */
+function xmlsitemap_priority_options($option = '') {
+  $options = array(
+    '1' => t('1.0'),
+    '0.9' => t('0.9'),
+    '0.8' => t('0.8'),
+    '0.7' => t('0.7'),
+    '0.6' => t('0.6'),
+    '0.5' => t('0.5'),
+    '0.4' => t('0.4'),
+    '0.3' => t('0.3'),
+    '0.2' => t('0.2'),
+    '0.1' => t('0.1'),
+    '0' => t('0.0'),
+  );
+  if ($option == 'exclude' || $option == 'both') {
+    $options['-1'] = t('Not in sitemap');
+  }
+  if ($option == 'default' || $option == 'both') {
+    $options['-2'] = t('Default');
+  }
+  return $options;
+}
+
+/**
+ * Determine the frequency of updates to a link.
+ *
+ * @param $interval
+ *  The number of seconds since the last change, or the number of seconds
+ *  between the last change, and the previous change.
+ *
+ * @return
+ *  A string representing the update frequency according to the sitemaps.org
+ *  protocol.
+ */
+function xmlsitemap_sitemap_frequency($interval) {
+  $frequencies = array(
+    'always' => 3600,
+    'hourly' => 86400,
+    'daily' => 604800,
+    'weekly' => 2419200,
+    'monthly' => 29030400,
+    'yearly' => 100000000,
+  );
+  if ($interval < 0 || !is_numeric($interval)) {
+    return 'never';
+  }
+  foreach ($frequencies as $frequency => $value) {
+    if ($interval < $value) {
+      break;
+    }
+  }
+  return $frequency;
+}
+
+/**
+ * Complete the query used to select rows from the xmlsitemap table.
+ */
+function xmlsitemap_sitemap_query() {
+  global $language;
+  $default = language_default();
+  $language_query = "AND xsm.language IN ('". $language->language ."', '')";
+  switch (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE)) {
+    case LANGUAGE_NEGOTIATION_NONE:
+      $language_query = '';
+      break;
+
+    case LANGUAGE_NEGOTIATION_PATH_DEFAULT:
+    case LANGUAGE_NEGOTIATION_PATH:
+      if (variable_get('xmlsitemap_all_links_to_default_language', 0) && $language->language == $default->language) {
+        $language_query = '';
+      }
+      break;
+  }
+  return "
+    FROM {xmlsitemap} xsm
+    INNER JOIN {system} s ON s.name = xsm.module
+    WHERE s.type = 'module'
+      AND s.status = 1
+      AND xsm.changefreq <> 0
+      AND xsm.changed <> 0
+      $language_query
+      AND (xsm.priority >= 0 AND xsm.priority <= 1)
+    ";
+}
+
+/**
+ * Return an array used to add additional form fields in the user form.
+ */
+function xmlsitemap_user_form_fieldset() {
+  static $done = FALSE;
+  $form = array();
+  if (!$done) {
+    $form['xmlsitemap'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('XML sitemap'),
+      '#collapsible' => TRUE,
+      '#access' => user_access('override profile settings') || user_access('administer users'),
+      '#weight' => 7,
+    );
+    $done = TRUE;
+  }
+  return $form;
+}
+
+/**
+ * @} End of "addtogroup xmlsitemap".
+ */
+