From a4e5fedff5d79c776d35432b35da74d6e15f1856 Mon Sep 17 00:00:00 2001
From: Dave Reid <dave@davereid.net>
Date: Sun, 31 Jan 2010 06:39:13 +0000
Subject: [PATCH] by Dave Reid: Fixed most of xmlsitemap_taxonomy and entity
 code. Rebuilding is still broken.

---
 xmlsitemap.admin.inc                          |  44 +++---
 xmlsitemap.inc                                |  28 ++--
 xmlsitemap.module                             |   3 +-
 xmlsitemap_menu/xmlsitemap_menu.module        |  31 ++++-
 xmlsitemap_node/xmlsitemap_node.module        |   2 +
 .../xmlsitemap_taxonomy.module                | 125 ++++++++----------
 6 files changed, 118 insertions(+), 115 deletions(-)

diff --git a/xmlsitemap.admin.inc b/xmlsitemap.admin.inc
index 29342dde..efc3c65a 100644
--- a/xmlsitemap.admin.inc
+++ b/xmlsitemap.admin.inc
@@ -24,7 +24,7 @@ function xmlsitemap_settings_form() {
   $form['xmlsitemap']['xmlsitemap_minimum_lifetime'] = array(
     '#type' => 'select',
     '#title' => t('Minimum sitemap lifetime'),
-    '#options' => array(0 => t('No minimum')) + drupal_map_assoc(array(300, 900, 1800, 3600, 10800, 21600, 32400, 43200, 86400, 172800, 259200, 604800), 'format_interval'),
+    '#options' => array(0 => t('No minimum')) + drupal_map_assoc(array(300, 900, 1800, 3600, 10800, 21600, 43200, 86400, 172800, 259200, 604800), 'format_interval'),
     '#default_value' => xmlsitemap_var('minimum_lifetime')
   );
   $form['xmlsitemap']['xmlsitemap_xsl'] = array(
@@ -191,8 +191,8 @@ function xmlsitemap_settings_form_submit($form, $form_state) {
  * @see xmlsitemap_rebuild_form_submit()
  */
 function xmlsitemap_rebuild_form() {
-  if (!$_POST && !xmlsitemap_var('rebuild_needed')) {
-    if (!xmlsitemap_var('regenerate_needed')) {
+  if (!$_POST && !variable_get('xmlsitemap_rebuild_needed', FALSE)) {
+    if (!variable_get('xmlsitemap_regenerate_needed', FALSE)) {
       drupal_set_message(t('Your sitemap is up to date and does not need to be rebuilt.'), 'error');
     }
     else {
@@ -201,16 +201,20 @@ function xmlsitemap_rebuild_form() {
     }
   }
 
-  // Show only the modules that implement the 6.x-2.x hooks.
-  $modules = module_implements('xmlsitemap_link_info', TRUE);
-
-  $form['modules'] = array(
+  $entities = xmlsitemap_get_link_info();
+  foreach ($entities as $entity => $info) {
+    if (empty($info['base table'])) {
+      // Only show entities which can be rebuilt.
+      unset($entities[$entity]);
+    }
+  }
+  $form['entities'] = array(
     '#type' => 'select',
-    '#title' => t("Select which modules' links you would like to rebuild"),
-    '#description' => t('If no modules are selected, the sitemap files will just be regenerated.'),
+    '#title' => t("Select which link types you would like to rebuild"),
+    '#description' => t('If no link types are selected, the sitemap files will just be regenerated.'),
     '#multiple' => TRUE,
-    '#options' => drupal_map_assoc($modules),
-    '#default_value' => xmlsitemap_var('rebuild_needed') || !xmlsitemap_var('developer_mode') ? $modules : array(),
+    '#options' => drupal_map_assoc(array_keys($entities)),
+    '#default_value' => xmlsitemap_var('rebuild_needed') || !xmlsitemap_var('developer_mode') ? array_keys($entities) : array(),
     '#access' => xmlsitemap_var('developer_mode'),
   );
   $form['save_custom'] = array(
@@ -240,7 +244,7 @@ function xmlsitemap_rebuild_form_submit($form, &$form_state) {
   variable_set('xmlsitemap_rebuild_needed', TRUE);
 
   module_load_include('inc', 'xmlsitemap');
-  $batch = xmlsitemap_rebuild_batch($form_state['values']['modules'], $form_state['values']['save_custom']);
+  $batch = xmlsitemap_rebuild_batch($form_state['values']['entities'], $form_state['values']['save_custom']);
   batch_set($batch);
   $form_state['redirect'] = 'admin/config/search/xmlsitemap';
 }
@@ -249,14 +253,6 @@ function xmlsitemap_rebuild_form_submit($form, &$form_state) {
  * Add a table summary for an entity and its bundles.
  */
 function xmlsitemap_add_form_entity_summary(&$form, $entity, array $entity_info) {
-  $header = array(
-    t('Type'),
-    t('Inclusion'),
-    t('Priority'),
-    t('Total'),
-    t('Indexed'),
-    t('Visible'),
-  );
   $priorities = xmlsitemap_get_priority_options(NULL, FALSE);
   $statuses = xmlsitemap_get_status_options(NULL);
 
@@ -296,6 +292,14 @@ function xmlsitemap_add_form_entity_summary(&$form, $entity, array $entity_info)
   }
 
   if ($rows) {
+    $header = array(
+      $entity_info['bundle label'],
+      t('Inclusion'),
+      t('Priority'),
+      t('Available'),
+      t('Indexed'),
+      t('Visible'),
+    );
     $rows[] = array(
       array(
         'data' => t('Totals'),
diff --git a/xmlsitemap.inc b/xmlsitemap.inc
index 31a82542..abac8532 100644
--- a/xmlsitemap.inc
+++ b/xmlsitemap.inc
@@ -344,7 +344,7 @@ function xmlsitemap_generate_index($handle, &$status, $language) {
 /**
  * Batch information callback.
  */
-function xmlsitemap_rebuild_batch($modules = array(), $save_custom = FALSE) {
+function xmlsitemap_rebuild_batch($entities = array(), $save_custom = FALSE) {
   $batch = array(
     'operations' => array(),
     'finished' => 'xmlsitemap_rebuild_batch_finished',
@@ -353,13 +353,11 @@ function xmlsitemap_rebuild_batch($modules = array(), $save_custom = FALSE) {
   );
 
   // Purge any links first.
-  $batch['operations'][] = array('xmlsitemap_rebuild_batch_clear', array($modules, $save_custom));
+  $batch['operations'][] = array('xmlsitemap_rebuild_batch_clear', array($entities, $save_custom));
 
   // Fetch all the sitemap links and save them to the {xmlsitemap} table.
-  foreach ($modules as $module) {
-    if (module_hook($module, 'xmlsitemap_links')) {
-      $batch['operations'][] = array('xmlsitemap_rebuild_batch_fetch', array($module));
-    }
+  foreach ($entities as $entity) {
+    $batch['operations'][] = array('xmlsitemap_rebuild_batch_fetch', array($entity));
   }
 
   // Generate all the sitemap pages.
@@ -373,22 +371,12 @@ function xmlsitemap_rebuild_batch($modules = array(), $save_custom = FALSE) {
 }
 
 /**
- * Batch callback; clear sitemap links for modules.
+ * Batch callback; clear sitemap links for entites.
  */
-function xmlsitemap_rebuild_batch_clear($modules, $save_custom, &$context) {
-  $purge = array();
-  foreach ($modules as $module) {
-    $types = module_invoke($module, 'xmlsitemap_link_info');
-    foreach ($types as $type => $info) {
-      if ($info['purge']) {
-        $purge[] = $type;
-      }
-    }
-  }
-
-  if ($purge) {
+function xmlsitemap_rebuild_batch_clear(array $entities, $save_custom, &$context) {
+  if (!empty($entities)) {
     $query = db_delete('xmlsitemap');
-    $query->condition('type', $purge);
+    $query->condition('type', $entities);
     // If we want to save the custom data, make sure to exclude any links
     // that are not using default inclusion or priority.
     if ($save_custom) {
diff --git a/xmlsitemap.module b/xmlsitemap.module
index 35f7048a..6f6af25d 100644
--- a/xmlsitemap.module
+++ b/xmlsitemap.module
@@ -777,6 +777,7 @@ function xmlsitemap_get_link_info($type = NULL, $reset = FALSE) {
 
   if ($reset) {
     $link_info = NULL;
+    entity_info_cache_clear();
   }
   elseif ($cached = cache_get('xmlsitemap:link_info:' . $language->language)) {
     $link_info = $cached->data;
@@ -802,8 +803,6 @@ function xmlsitemap_get_link_info($type = NULL, $reset = FALSE) {
         'type' => $key,
         'base table' => FALSE,
         'bundles' => array(),
-        'object keys' => array(),
-        'admin' => array(),
       );
     }
     drupal_alter('xmlsitemap_link_info', $link_info);
diff --git a/xmlsitemap_menu/xmlsitemap_menu.module b/xmlsitemap_menu/xmlsitemap_menu.module
index 4a711708..ce5d812a 100644
--- a/xmlsitemap_menu/xmlsitemap_menu.module
+++ b/xmlsitemap_menu/xmlsitemap_menu.module
@@ -5,15 +5,34 @@
  * Implements hook_xmlsitemap_link_info().
  */
 function xmlsitemap_menu_xmlsitemap_link_info() {
-  return array(
-    'menu' => array(
-      'purge' => TRUE,
-      'table' => 'menu_links',
+  $types['menu'] = array(
+    'label' => t('Menu'),
+    'bundle label' => t('Menu title'),
+    'base table' => 'menu_links',
+    'object keys' => array(
       'id' => 'mlid',
-      'subtype' => 'menu_name',
-      'subtypes' => xmlsitemap_menu_get_menus(),
+      'bundle' => 'menu_name',
     ),
+    'path callback' => 'xmlsitemap_menu_path',
   );
+  foreach (menu_get_menus() as $menu => $name) {
+    $types['menu']['bundles'][$menu] = array(
+      'label' => $name,
+      'admin' => array(
+        'real path' => 'admin/structure/menu/manage/' . $menu . '/edit',
+        'access arguments' => array('administer menu'),
+      ),
+      'xmlsitemap' => array(
+        'priority' => variable_get('xmlsitemap_menu_priority_' . $menu, 0.5),
+        'status' => variable_get('xmlsitemap_menu_status_' . $menu, 0),
+      ),
+    );
+  }
+  return $types;
+}
+
+function xmlsitemap_menu_path($menu_item) {
+  return $menu_item['link_path'];
 }
 
 /**
diff --git a/xmlsitemap_node/xmlsitemap_node.module b/xmlsitemap_node/xmlsitemap_node.module
index 310a65b6..fdf21d06 100644
--- a/xmlsitemap_node/xmlsitemap_node.module
+++ b/xmlsitemap_node/xmlsitemap_node.module
@@ -5,6 +5,8 @@
  * Implements hook_entity_info_alter().
  */
 function xmlsitemap_node_entity_info_alter(&$entity_info) {
+  $entity_info['node']['label'] = t('Content');
+  $entity_info['node']['bundle label'] = t('Content type');
   $entity_info['node']['xmlsitemap'] = array();
   foreach (node_type_get_names() as $type => $name) {
     $entity_info['node']['bundles'][$type]['xmlsitemap'] = array(
diff --git a/xmlsitemap_taxonomy/xmlsitemap_taxonomy.module b/xmlsitemap_taxonomy/xmlsitemap_taxonomy.module
index fcf48e45..bf4aa228 100644
--- a/xmlsitemap_taxonomy/xmlsitemap_taxonomy.module
+++ b/xmlsitemap_taxonomy/xmlsitemap_taxonomy.module
@@ -5,6 +5,7 @@
  * Implements hook_entity_info_alter().
  */
 function xmlsitemap_taxonomy_entity_info_alter(&$entity_info) {
+  $entity_info['taxonomy_term']['bundle label'] = t('Vocabulary name');
   $entity_info['taxonomy_term']['xmlsitemap'] = array();
   foreach (taxonomy_vocabulary_get_names() as $machine_name => $vocabulary) {
     $entity_info['taxonomy_term']['bundles'][$machine_name]['xmlsitemap'] = array(
@@ -14,6 +15,21 @@ function xmlsitemap_taxonomy_entity_info_alter(&$entity_info) {
   }
 }
 
+/**
+ * Implements hook_xmlsitemap_link_info_alter().
+ */
+function xmlsitemap_taxonomy_xmlsitemap_link_info_alter(&$link_info) {
+  // Change taxonomy term bundle type from machine name to vid.
+  $link_info['taxonomy_term']['object keys']['bundle'] = 'vid';
+  foreach (taxonomy_vocabulary_get_names() as $machine_name => $vocabulary) {
+    // Adjust the edit path to the *real* edit path.
+    $link_info['taxonomy_term']['bundles'][$machine_name]['admin']['path'] .= '/edit';
+    $link_info['taxonomy_term']['bundles'][$machine_name]['admin']['real path'] .= '/edit';
+    $link_info['taxonomy_term']['bundles'][$vocabulary->vid] = $link_info['taxonomy_term']['bundles'][$machine_name];
+    unset($link_info['taxonomy_term']['bundles'][$machine_name]);
+  }
+}
+
 /**
  * Implements hook_cron().
  *
@@ -28,7 +44,7 @@ function xmlsitemap_taxonomy_cron() {
  */
 function xmlsitemap_taxonomy_xmlsitemap_index_links($limit) {
   if ($vids = xmlsitemap_taxonomy_get_vids()) {
-    $tids = db_query_range("SELECT t.tid FROM {term_data} t LEFT JOIN {xmlsitemap} x ON x.type = 'taxonomy_term' AND t.tid = x.id WHERE x.id IS NULL AND t.vid IN (:vids) ORDER BY t.tid DESC", 0, $limit, array(':vids' => $vids))->fetchCol();
+    $tids = db_query_range("SELECT t.tid FROM {taxonomy_term_data} t LEFT JOIN {xmlsitemap} x ON x.type = 'taxonomy_term' AND t.tid = x.id WHERE x.id IS NULL AND t.vid IN (:vids) ORDER BY t.tid DESC", 0, $limit, array(':vids' => $vids))->fetchCol();
     $terms = taxonomy_term_load_multiple($tids);
     foreach ($terms as $term) {
       $link = xmlsitemap_taxonomy_create_link($term);
@@ -44,7 +60,7 @@ function xmlsitemap_taxonomy_xmlsitemap_links($offset = 0, $limit = 0) {
   $links = array();
 
   if ($vids = xmlsitemap_taxonomy_get_vids()) {
-    $sql = "SELECT t.tid FROM {term_data} t WHERE t.tid > :tid AND t.vid IN (:vids) ORDER BY t.tid";
+    $sql = "SELECT t.tid FROM {taxonomy_term_data} t WHERE t.tid > :tid AND t.vid IN (:vids) ORDER BY t.tid";
     $args = array(':tid' => $offset, ':vids' => $vids);
     $tids = ($limit ? db_query_range($sql, 0, $limit, $args)->fetchCol() : db_query($sql, $args)->fetchCol());
     $terms = taxonomy_term_load_multiple($tids);
@@ -63,7 +79,7 @@ function xmlsitemap_taxonomy_xmlsitemap_links($offset = 0, $limit = 0) {
 function xmlsitemap_taxonomy_xmlsitemap_links_batch_info() {
   $vids = xmlsitemap_taxonomy_get_vids();
   return array(
-    'max' => $vids ? db_query("SELECT COUNT(t.tid) FROM {term_data} t WHERE t.vid IN (:vids)", array(':vids' => $vids))->fetchField() : 0,
+    'max' => $vids ? db_query("SELECT COUNT(t.tid) FROM {taxonomy_term_data} t WHERE t.vid IN (:vids)", array(':vids' => $vids))->fetchField() : 0,
   );
 }
 
@@ -83,18 +99,6 @@ function xmlsitemap_taxonomy_form_taxonomy_form_vocabulary_alter(&$form, $form_s
   );
   xmlsitemap_add_form_type_options($form, 'taxonomy', $options);
 
-  // @todo Enable these features:
-  //$form['xmlsitemap']['xmlsitemap_taxonomy_calculate_priority'] = array(
-  //  '#type' => 'checkbox',
-  //  '#title' => t('Calculate priority based on term depth and weight.'),
-  //  '#default_value' => xmlsitemap_taxonomy_var('calculate_priority_' . $vid),
-  //);
-  //$form['xmlsitemap']['xmlsitemap_taxonomy_include_empty_terms'] = array(
-  //  '#type' => 'checkbox',
-  //  '#title' => t('Include terms that do not have any associated content.'),
-  //  '#default_value' => xmlsitemap_taxonomy_var('include_empty_terms_' . $vid),
-  //);
-
   // The submit and delete buttons need to be weighted down.
   $form['submit'] += array('#weight' => 50);
   if (isset($form['delete'])) {
@@ -158,28 +162,35 @@ function xmlsitemap_taxonomy_form_taxonomy_form_term_alter(&$form, $form_state)
 }
 
 /**
- * Implements hook_taxonomy().
+ * Implements hook_taxonomy_vocabulary_delete().
  */
-function xmlsitemap_taxonomy_taxonomy($op, $type, $array = NULL) {
-  if ($type == 'vocabulary') {
-    $vid = $array['vid'];
-    // Insert and update actions handled by xmlsitemap_taxonomy_taxonomy_form_vocabulary_submit().
-    if ($op == 'delete') {
-      xmlsitemap_link_delete_multiple(array('type' => 'taxonomy_term', 'subtype' => $vid));
-      variable_del('xmlsitemap_taxonomy_status_' . $vid);
-      variable_del('xmlsitemap_taxonomy_priority_' . $vid);
-    }
-  }
-  if ($type == 'term') {
-    $tid = $array['tid'];
-    if ($op == 'insert' || $op == 'update') {
-      $link = xmlsitemap_taxonomy_create_link((object) $array);
-      xmlsitemap_save_link($link);
-    }
-    elseif ($op == 'delete') {
-      xmlsitemap_link_delete('taxonomy_term', $tid);
-    }
-  }
+function xmlsitemap_taxonomy_vocabulary_delete(stdClass $vocabulary) {
+  xmlsitemap_link_delete_multiple(array('type' => 'taxonomy_term', 'subtype' => $vocabulary->vid));
+  variable_del('xmlsitemap_taxonomy_status_' . $vocabulary->vid);
+  variable_del('xmlsitemap_taxonomy_priority_' . $vocabulary->vid);
+}
+
+/**
+ * Implements hook_taxonomy_term_insert() {
+ */
+function xmlsitemap_taxonomy_term_insert(stdClass $term) {
+  $link = xmlsitemap_taxonomy_create_link($term);
+  xmlsitemap_save_link($link);
+}
+
+/**
+ * Implements hook_taxonomy_term_update() {
+ */
+function xmlsitemap_taxonomy_term_update(stdClass $term) {
+  $link = xmlsitemap_taxonomy_create_link($term);
+  xmlsitemap_save_link($link);
+}
+
+/**
+ * Implements hook_taxonomy_term_delete() {
+ */
+function xmlsitemap_taxonomy_term_delete(stdClass $term) {
+  xmlsitemap_link_delete('taxonomy_term', $term->tid);
 }
 
 /**
@@ -222,43 +233,42 @@ function xmlsitemap_taxonomy_create_link(stdClass $term) {
 /**
  * Calculate the priority of a taxonomy term based on depth and weight.
  */
-function xmlsitemap_taxonomy_calculate_term_priority($term) {
+/*function xmlsitemap_taxonomy_calculate_term_priority(stdClass $term) {
   // Calculate priority.
   // Min weight = -128
   // Max weight = 127
   // Max depth = ?
-  return NULL;
-}
+}*/
 
 /**
  * Find the tree depth of a taxonomy term.
  *
- * @param $tid
- *   A term ID.
+ * @param $term
+ *   A taxonomy term object.
  * @return
  *   The tree depth of the term.
  */
-function xmlsitemap_taxonomy_get_term_depth($tid) {
+function xmlsitemap_taxonomy_get_term_depth(stdClass $term) {
   static $depths = array();
 
-  if (!isset($depths[$tid])) {
-    if ($parent = db_query("SELECT parent FROM {term_hierarchy} WHERE tid = %d", $tid)->fetchField()) {
+  if (!isset($depths[$term->tid])) {
+    if ($parent = db_query("SELECT parent FROM {term_hierarchy} WHERE tid = %d", $term->tid)->fetchField()) {
       // If the term has a parent, the term's depth is the parent's depth + 1.
       if (!isset($depths[$parent])) {
         $depths[$parent] = xmlsitemap_taxonomy_get_term_depth($parent);
       }
-      $depths[$tid] = $depths[$parent] + 1;
+      $depths[$term->tid] = $depths[$parent] + 1;
     }
     else {
       // Term has no parents, so depth is 0.
-      $depths[$tid] = 0;
+      $depths[$term->tid] = 0;
     }
   }
 
-  return $depths[$tid];
+  return $depths[$term->tid];
 }
 
-function xmlsitemap_taxonomy_get_node_count($term) {
+function xmlsitemap_taxonomy_get_node_count(stdClass $term) {
   // @todo Use db_rewrite_sql() w/ switch user.
   return db_query_range("SELECT COUNT(tn.nid) FROM {term_node} tn LEFT JOIN {node n} USING (nid) WHERE tn.tid = :tid AND n.status = 1", 0, 1, array(':tid' => $term->tid))->fetchField();
 }
@@ -304,22 +314,3 @@ function xmlsitemap_taxonomy_variables() {
 //  $defaults['xmlsitemap_taxonomy_include_empty_terms_' . $vid] = TRUE;
 //  return $defaults;
 //}
-
-/**
- * Internal implementation of variable_get().
- */
-function xmlsitemap_taxonomy_var($name, $default = NULL) {
-  static $defaults = NULL;
-  if (!isset($defaults)) {
-    $defaults = xmlsitemap_taxonomy_variables();
-  }
-
-  $name = 'xmlsitemap_taxonomy_' . $name;
-
-  // @todo Remove when stable.
-  if (!isset($defaults[$name])) {
-    trigger_error(t('Default variable for %variable not found.', array('%variable' => $name)));
-  }
-
-  return variable_get($name, isset($default) || !isset($defaults[$name]) ? $default : $defaults[$name]);
-}
-- 
GitLab