$vids)); foreach ($tids as $tid) { $term = xmlsitemap_taxonomy_taxonomy_term_load($tid); $link = xmlsitemap_taxonomy_create_link($term); xmlsitemap_save_link($link); } } } /** * Implements hook_xmlsitemap_links(). */ 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"; $args = array(':tid' => $offset, ':vids' => $vids); $tids = ($limit ? db_query_range($sql, 0, $limit, $args) : db_query($sql, $args)); foreach ($tids as $tid) { $term = xmlsitemap_taxonomy_taxonomy_term_load($tid); $links[] = xmlsitemap_taxonomy_create_link($term); } } return $links; } /** * Implements hook_xmlsitemap_links_batch_info(). */ 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, ); } /** * Implements hook_xmlsitemap_link_info(). */ function xmlsitemap_taxonomy_xmlsitemap_link_info() { return array( 'taxononomy' => array( 'purge' => TRUE, 'table' => 'term_data', 'id' => 'tid', 'subtype' => 'vid', 'subtypes' => xmlsitemap_taxonomy_get_vids(), ), ); } /** * Load a taxonomy term and its associated sitemap link data. * * Use this instead of taxonomy_get_term(). * * @todo Convert this to hook_taxonomy_term_load() in Drupal 7. */ function xmlsitemap_taxonomy_taxonomy_term_load($tid) { $term = taxonomy_get_term($tid); if ($data = xmlsitemap_load_link(array('type' => 'taxonomy_term', 'id' => $tid))) { $term->xmlsitemap = $data; } return $term; } /** * Implements hook_form_FORM_ID_alter(). * * Show a summary of vocabularies on the XML sitemap settings page. */ function xmlsitemap_taxonomy_form_xmlsitemap_settings_form_alter(&$form, $form_state) { $type = array( 'type' => 'taxonomy_term', 'title' => t('Taxonomy'), 'item_title' => t('Vocabulary'), 'access' => user_access('administer taxonomy'), ); $vocabularies = taxonomy_get_vocabularies(); foreach ($vocabularies as $vid => $vocabulary) { $vocabularies[$vid] = array( 'name' => $vocabulary->name, 'link' => 'admin/content/taxonomy/edit/vocabulary/' . $vid, 'status' => xmlsitemap_taxonomy_var('status_' . $vid), 'priority' => xmlsitemap_taxonomy_var('priority_' . $vid), ); } xmlsitemap_add_form_type_summary($form, $type, $vocabularies); $form['taxonomy_term']['#weight'] = 40; } /** * Implements hook_form_FORM_ID_alter(). * * @see taxonomy_form_vocabulary() * @see xmlsitemap_add_form_type_options() */ function xmlsitemap_taxonomy_form_taxonomy_form_vocabulary_alter(&$form, $form_state) { $vid = isset($form['vid']['#value']) ? $form['vid']['#value'] : 0; module_load_include('inc', 'xmlsitemap', 'xmlsitemap.admin'); $options = array( 'status' => variable_get('xmlsitemap_taxonomy_status_' . $vid, 0), 'priority' => variable_get('xmlsitemap_taxonomy_priority_' . $vid, 0.5), ); 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'])) { $form['delete'] += array('#weight' => 51); } $form['#submit'][] = 'xmlsitemap_taxonomy_taxonomy_form_vocabulary_submit'; } /** * Form submit handler; update settings when a taxonomy vocabulary is saved. */ function xmlsitemap_taxonomy_taxonomy_form_vocabulary_submit($form, $form_state) { $vid = $form_state['values']['vid']; $new_status = $form_state['values']['xmlsitemap_taxonomy_status']; $new_priority = $form_state['values']['xmlsitemap_taxonomy_priority']; if ($new_status != variable_get('xmlsitemap_taxonomy_status_' . $vid, 0)) { xmlsitemap_update_links(array('status' => $new_status), array('type' => 'taxonomy_term', 'subtype' => $vid, 'status_override' => 0)); } if ($new_priority != variable_get('xmlsitemap_taxonomy_priority_' . $vid, 0.5)) { xmlsitemap_update_links(array('priority' => $new_priority), array('type' => 'taxonomy_term', 'subtype' => $vid, 'priority_override' => 0)); } variable_set('xmlsitemap_taxonomy_status_' . $vid, $new_status); variable_set('xmlsitemap_taxonomy_priority_' . $vid, $new_priority); } /** * Implements hook_form_FORM_ID_alter(). */ function xmlsitemap_taxonomy_form_taxonomy_form_term_alter(&$form, $form_state) { // Because the same form is used for deletion in confirm_form, we must check // if the normal editing form elements are present. Hopefully this is fixed // in Drupal 7. if (isset($form['identification'])) { if ($form['#term']['tid']) { $term = xmlsitemap_taxonomy_taxonomy_term_load($form['#term']['tid']); } else { $term = (object) $form['#term']; } $term->vid = $form['vid']['#value']; $link = xmlsitemap_taxonomy_create_link($term); // Add the link options. module_load_include('inc', 'xmlsitemap', 'xmlsitemap.admin'); xmlsitemap_add_form_link_options($form, $link); $form['xmlsitemap']['#access'] |= user_access('administer taxonomy'); if (user_access('administer taxonomy')) { $form['xmlsitemap']['#description'] = t('The default priority for this vocabulary can be changed here.', array('@link-type' => url('admin/content/taxonomy/edit/vocabulary/' . $term->vid, array('query' => drupal_get_destination())))); } // The submit and delete buttons need to be weighted down. $form['submit'] += array('#weight' => 50); if (isset($form['delete'])) { $form['delete'] += array('#weight' => 51); } } } /** * Implements hook_taxonomy(). */ 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_delete_link(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_delete_link(array('type' => 'taxonomy_term', 'id' => $tid)); } } } /** * Create a sitemap link from a taxonomy term. * * @param $term * A taxonomy term object. * @return * An array representing a sitemap link. */ function xmlsitemap_taxonomy_create_link(stdClass $term) { if (!isset($term->xmlsitemap)) { $term->xmlsitemap = array(); } $term->xmlsitemap += array( 'id' => $term->tid, 'type' => 'taxonomy_term', 'subtype' => $term->vid, 'loc' => taxonomy_term_path($term), 'status' => variable_get('xmlsitemap_taxonomy_status_' . $term->vid, 0), 'status_default' => variable_get('xmlsitemap_taxonomy_status_' . $term->vid, 0), 'status_override' => 0, 'priority' => variable_get('xmlsitemap_taxonomy_priority_' . $term->vid, 0.5), 'priority_default' => variable_get('xmlsitemap_taxonomy_priority_' . $term->vid, 0.5), 'priority_override' => 0, ); // The following values must always be checked because they are volatile. // @todo How can/should we check taxonomy term access? $term->xmlsitemap['access'] = 1; $term->xmlsitemap['language'] = isset($term->language) ? $term->language : LANGUAGE_NONE; return $term->xmlsitemap; } /** * Calculate the priority of a taxonomy term based on depth and weight. */ function xmlsitemap_taxonomy_calculate_term_priority($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. * @return * The tree depth of the term. */ function xmlsitemap_taxonomy_get_term_depth($tid) { static $depths = array(); if (!isset($depths[$tid])) { if ($parent = db_query("SELECT parent FROM {term_hierarchy} WHERE tid = %d", $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; } else { // Term has no parents, so depth is 0. $depths[$tid] = 0; } } return $depths[$tid]; } function xmlsitemap_taxonomy_get_node_count($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(); } /** * Fetch an array of vocabulary IDs to be included in the sitemap. */ function xmlsitemap_taxonomy_get_vids() { $vids = array_keys(taxonomy_get_vocabularies()); foreach ($vids as $index => $vid) { if (!variable_get('xmlsitemap_taxonomy_status_' . $vid, 0)) { unset($vids[$index]); } } return $vids; } /** * Internal default variables for template_var(). */ function xmlsitemap_taxonomy_variables() { $defaults = array( // Removed variables set to NULL. 'xmlsitemap_taxonomy_include_empty_terms' => NULL, 'xmlsitemap_taxonomy_calculate_priority' => NULL, ); $vids = array_keys(taxonomy_get_vocabularies()); foreach ($vids as $vid) { $defaults['xmlsitemap_taxonomy_status_' . $vid] = 0; $defaults['xmlsitemap_taxonomy_priority_' . $vid] = '0.5'; $defaults['xmlsitemap_taxonomy_calculate_priority_' . $vid] = FALSE; $defaults['xmlsitemap_taxonomy_include_empty_terms_' . $vid] = FALSE; //$defaults += _xmlsitemap_taxonomy_variables_vid($vid); } return $defaults; } //function _xmlsitemap_taxonomy_variables_vid($vid) { // $defaults = array(); // $defaults['xmlsitemap_taxonomy_status_' . $vid] = 0; // $defaults['xmlsitemap_taxonomy_priority_' . $vid] = 0.5; // $defaults['xmlsitemap_taxonomy_calculate_priority_' . $vid] = FALSE; // $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]); }