xmlsitemap_node.module 10.9 KB
Newer Older
Darren Oh's avatar
Darren Oh committed
1 2 3 4
<?php
// $Id$

/**
5 6 7
 * Implements hook_cron().
 *
 * Process old nodes not found in the {xmlsitemap} table.
Darren Oh's avatar
Darren Oh committed
8
 */
9
function xmlsitemap_node_cron() {
10 11 12 13 14 15 16 17
  xmlsitemap_node_xmlsitemap_index_links(xmlsitemap_var('batch_limit'));
}

/**
 * Implements hook_xmlsitemap_index_links().
 */
function xmlsitemap_node_xmlsitemap_index_links($limit) {
  if ($types = xmlsitemap_node_get_types()) {
18 19 20
    $nids = db_query_range("SELECT n.nid FROM {node} n LEFT JOIN {xmlsitemap} x ON x.type = 'node' AND n.nid = x.id WHERE x.id IS NULL AND n.type IN (:types) ORDER BY n.nid DESC", 0, $limit, array(':types' => $types))->fetchCol();
    $nodes = node_load_multiple($nids);
    foreach ($nodes as $node) {
21 22 23
      $link = xmlsitemap_node_create_link($node);
      xmlsitemap_save_link($link);
    }
24 25
  }
}
Darren Oh's avatar
Darren Oh committed
26 27

/**
28
 * Implements hook_node_insert().
Darren Oh's avatar
Darren Oh committed
29
 */
30 31
function xmlsitemap_node_node_insert($node) {
  xmlsitemap_node_node_update($node);
Darren Oh's avatar
Darren Oh committed
32 33 34
}

/**
35
 * Implements hook_node_update().
Darren Oh's avatar
Darren Oh committed
36
 */
37 38 39
function xmlsitemap_node_node_update($node) {
  $link = xmlsitemap_node_create_link($node);
  xmlsitemap_save_link($link);
Darren Oh's avatar
Darren Oh committed
40 41 42
}

/**
43
 * Implements hook_node_delete().
Darren Oh's avatar
Darren Oh committed
44
 */
45 46 47 48 49 50 51 52 53 54
function xmlsitemap_node_node_delete($node) {
  xmlsitemap_delete_link(array('type' => 'node', 'id' => $node->nid));
}

/**
 * Implements hook_comment_update().
 */
function xmlsitemap_node_comment_update(stdClass $comment) {
  if ($node = node_load($comment->nid, NULL, TRUE)) {
    xmlsitemap_node_node_update($node);
Darren Oh's avatar
Darren Oh committed
55 56 57
  }
}

58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
/**
 * Implements hook_comment_publish().
 */
function xmlsitemap_node_comment_publish(stdClass $comment) {
  xmlsitemap_node_comment_update($comment);
}

/**
 * Implements hook_comment_unpublish().
 */
function xmlsitemap_node_comment_unpublish(stdClass $comment) {
  xmlsitemap_node_comment_update($comment);
}

/**
 * Implements hook_comment_delete().
 */
function xmlsitemap_node_comment_delete(stdClass $comment) {
  xmlsitemap_node_comment_update($comment);
}

/**
 * Implements hook_node_type_delete().
 */
function xmlsitemap_node_node_type_delete($info) {
  variable_del('xmlsitemap_node_status_' . $info->type);
  variable_del('xmlsitemap_node_priority_' . $info->type);
  //xmlsitemap_delete_link(array('type' => 'node', 'subtype' => $info->type));
}

Darren Oh's avatar
Darren Oh committed
88
/**
89 90 91
 * Implements hook_form_FORM_ID_alter().
 *
 * Show a summary of content types on the XML sitemap settings page.
Darren Oh's avatar
Darren Oh committed
92
 */
93 94 95 96 97 98 99 100
function xmlsitemap_node_form_xmlsitemap_settings_form_alter(&$form, $form_state) {
  $type = array(
    'type' => 'node',
    'title' => t('Content types'),
    'item_title' => t('Content type'),
    'access' => user_access('administer content types'),
  );

101
  $node_types = node_type_get_names();
102 103 104
  foreach ($node_types as $node_type => $node_type_name) {
    $node_types[$node_type] = array(
      'name' => drupal_ucfirst($node_type_name),
105
      'link' => 'admin/structure/types/manage/' . str_replace('_', '-', $node_type),
106 107 108
      'status' => variable_get('xmlsitemap_node_status_' . $node_type, 0),
      'priority' => variable_get('xmlsitemap_node_priority_' . $node_type, 0.5),
    );
Darren Oh's avatar
Darren Oh committed
109
  }
110 111 112

  xmlsitemap_add_form_type_summary($form, $type, $node_types);
  $form['node']['#weight'] = 30;
Darren Oh's avatar
Darren Oh committed
113 114 115
}

/**
116 117 118 119
 * Implements hook_form_FORM_ID_alter().
 *
 * @see node_type_form()
 * @see xmlsitemap_add_form_type_options()
Darren Oh's avatar
Darren Oh committed
120
 */
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
function xmlsitemap_node_form_node_type_form_alter(&$form, $form_state) {
  $node_type = isset($form['#node_type']->type) ? $form['#node_type']->type : '';

  module_load_include('inc', 'xmlsitemap', 'xmlsitemap.admin');
  $options = array(
    'status' => variable_get('xmlsitemap_node_status_' . $node_type, 0),
    'priority' => variable_get('xmlsitemap_node_priority_' . $node_type, 0.5),
  );
  xmlsitemap_add_form_type_options($form, 'node', $options);
  $form['xmlsitemap']['#attached']['js']['vertical-tabs'] = drupal_get_path('module', 'xmlsitemap_node') . '/xmlsitemap_node.js';

  // Add our submit handler before node_type_form_submit() so we can compare
  // the old and new values.
  array_unshift($form['#submit'], 'xmlsitemap_node_type_form_submit');
}

function xmlsitemap_node_type_form_submit($form, $form_state) {
  $node_type = $form_state['values']['old_type'];
  $new_status = $form_state['values']['xmlsitemap_node_status'];
  $new_priority = $form_state['values']['xmlsitemap_node_priority'];
  $new_type = $form_state['values']['type'];

  if ($new_status != variable_get('xmlsitemap_node_status_' . $node_type, 0)) {
    xmlsitemap_update_links(array('status' => $new_status), array('type' => 'node', 'subtype' => $node_type, 'status_override' => 0));
Darren Oh's avatar
Darren Oh committed
145
  }
146 147 148 149 150
  if ($new_priority != variable_get('xmlsitemap_node_priority_' . $node_type, 0.5)) {
    xmlsitemap_update_links(array('priority' => $new_priority), array('type' => 'node', 'subtype' => $node_type, 'priority_override' => 0));
  }
  if ($node_type != $new_type) {
    xmlsitemap_update_links(array('subtype' => $new_type), array('type' => 'node', 'subtype' => $node_type));
Darren Oh's avatar
Darren Oh committed
151
  }
Alberto Paderno's avatar
Alberto Paderno committed
152
}
Darren Oh's avatar
Darren Oh committed
153 154

/**
155 156 157 158 159
 * Implements hook_form_alter().
 *
 * Add the XML sitemap individual link options for a node.
 *
 * @see xmlsitemap_add_form_link_options()
Darren Oh's avatar
Darren Oh committed
160
 */
161
function xmlsitemap_node_form_alter(&$form, $form_state, $form_id) {
162 163
  if (!empty($form['#node_edit_form'])) {
    $node = clone $form['#node'];
164 165 166 167 168
    if (!isset($node->nid)) {
      // Handle new nodes that do not have a value for nid yet.
      $node->nid = NULL;
    }
    $link = xmlsitemap_node_create_link($node);
Darren Oh's avatar
Darren Oh committed
169

170 171 172
    // Add the link options.
    module_load_include('inc', 'xmlsitemap', 'xmlsitemap.admin');
    xmlsitemap_add_form_link_options($form, $link);
Darren Oh's avatar
Darren Oh committed
173

174 175 176
    $form['xmlsitemap']['#access'] |= user_access('administer nodes');
    $form['xmlsitemap']['#weight'] = 30;
    if (user_access('administer content types')) {
177
      $form['xmlsitemap']['#description'] = t('The default XML sitemap settings for this content type can be changed <a href="@link-type">here</a>.', array('@link-type' => url('admin/structure/types/manage/' . str_replace('_', '-', $node->type), array('query' => drupal_get_destination()))));
178
    }
Darren Oh's avatar
Darren Oh committed
179 180 181 182
  }
}

/**
183
 * Implements hook_xmlsitemap_links().
Darren Oh's avatar
Darren Oh committed
184
 */
185 186 187
function xmlsitemap_node_xmlsitemap_links($offset = 0, $limit = 0) {
  $links = array();

188
  if ($types = xmlsitemap_node_get_types()) {
189
    $sql = "SELECT n.nid FROM {node} n WHERE n.nid > :offset AND n.type IN (:types) ORDER BY n.nid";
190 191
    $args = array(':offset' => $offset, ':types' => $types);
    $nids = ($limit ? db_query_range($sql, 0, $limit, $args) : db_query($sql, $args));
192
    $nodes = node_load_multiple($nids);
193

194
    foreach ($nodes as $node) {
195 196
      $links[] = xmlsitemap_node_create_link($node);
    }
Darren Oh's avatar
Darren Oh committed
197
  }
198 199

  return $links;
Darren Oh's avatar
Darren Oh committed
200 201 202
}

/**
203
 * Implements hook_xmlsitemap_links_batch_info().
Darren Oh's avatar
Darren Oh committed
204
 */
205
function xmlsitemap_node_xmlsitemap_links_batch_info() {
206
  $types = xmlsitemap_node_get_types();
207
  return array(
208
    'max' => $types ? db_query("SELECT COUNT(n.nid) FROM {node} n WHERE n.type IN (:types)", array(':types' => $types))->fetchField() : 0,
209
  );
Darren Oh's avatar
Darren Oh committed
210 211 212
}

/**
213
 * Implements hook_xmlsitemap_link_info().
Darren Oh's avatar
Darren Oh committed
214
 */
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
function xmlsitemap_node_xmlsitemap_link_info() {
  return array(
    'node' => array(
      'purge' => TRUE,
      'table' => 'node',
      'id' => 'nid',
      'subtype' => 'type',
      'subtypes' => xmlsitemap_node_get_types(),
    ),
  );
}

/**
 * Fetch an array of node types to be included in the sitemap.
 */
function xmlsitemap_node_get_types() {
231
  $node_types = array_keys(node_type_get_names());
232 233 234 235
  foreach ($node_types as $index => $node_type) {
    if (!variable_get('xmlsitemap_node_status_' . $node_type, 0)) {
      unset($node_types[$index]);
    }
Darren Oh's avatar
Darren Oh committed
236
  }
237
  return $node_types;
Darren Oh's avatar
Darren Oh committed
238 239
}

240
/**
241
 * Implements hook_field_extra_fields().
242
 */
243 244 245 246 247 248 249 250 251
function xmlsitemap_node_field_extra_fields() {
  $extras = array();
  foreach (xmlsitemap_node_get_types() as $type) {
    $extras['node'][$type]['xmlsitemap'] = array(
      'label' => t('XML sitemap'),
      'description' => t('XML sitemap module element'),
      'weight' => 30,
    );
  }
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
  return $extras;
}

/**
 * Fetch all the timestamps for when a node was changed.
 *
 * @param $node
 *   A node object.
 * @return
 *   An array of UNIX timestamp integers.
 */
function xmlsitemap_node_get_timestamps($node) {
  static $timestamps = array();

  if (!isset($timestamps[$node->nid])) {
267
    $timestamps[$node->nid] = db_query("SELECT c.created FROM {comment} c WHERE c.nid = :nid AND c.status = :status UNION ALL SELECT nr.timestamp FROM {node_revision} nr WHERE nr.nid = :nid2", array(':nid' => $node->nid, ':status' => COMMENT_PUBLISHED, ':nid2' => $node->nid))->fetchCol();
268
  }
269 270

  return $timestamps[$node->nid];
271
}
272 273 274 275 276 277 278 279 280 281

/**
 * Create a sitemap link from a node.
 *
 * The link will be saved as $node->xmlsitemap.
 *
 * @param $node
 *   A node object.
 */
function xmlsitemap_node_create_link(&$node) {
282
  if (!isset($node->xmlsitemap) || !is_array($node->xmlsitemap)) {
283
    $node->xmlsitemap = array();
284 285 286
    if ($node->nid && $link = xmlsitemap_load_link(array('type' => 'node', 'id' => $node->nid))) {
      $node->xmlsitemap = $link;
    }
287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
  }

  $node->xmlsitemap += array(
    'type' => 'node',
    'id' => $node->nid,
    'subtype' => $node->type,
    'loc' => 'node/'. $node->nid,
    'status' => variable_get('xmlsitemap_node_status_' . $node->type, 0),
    'status_default' => variable_get('xmlsitemap_node_status_' . $node->type, 0),
    'status_override' => 0,
    'priority' => variable_get('xmlsitemap_node_priority_' . $node->type, 0.5),
    'priority_default' => variable_get('xmlsitemap_node_priority_' . $node->type, 0.5),
    'priority_override' => 0,
  );

302 303 304 305 306
  // Always recalculate changefreq and changecount.
  $timestamps = xmlsitemap_node_get_timestamps($node);
  $node->xmlsitemap['changefreq'] = $node->nid ? xmlsitemap_calculate_changefreq($timestamps) : 0;
  $node->xmlsitemap['changecount'] = $node->nid ? count($timestamps) - 1 : 0;

307 308 309
  // The following values must always be checked because they are volatile.
  $node->xmlsitemap['lastmod'] = isset($node->changed) ? $node->changed : REQUEST_TIME;
  $node->xmlsitemap['access'] = $node->nid ? (bool) node_access('view', $node, drupal_anonymous_user()) : 1;
310
  $node->xmlsitemap['language'] = isset($node->language) ? $node->language : LANGUAGE_NONE;
311 312 313 314 315 316 317 318 319

  return $node->xmlsitemap;
}

/**
 * Internal default variables for xmlsitemap_node_var().
 */
function xmlsitemap_node_variables() {
  $defaults = array();
320
  $node_types = array_keys(node_type_get_names());
321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347
  foreach ($node_types as $node_type) {
    $defaults['xmlsitemap_node_priority_' . $node_type] = 0.5;
    $defaults['xmlsitemap_node_status_' . $node_type] = 0;
    // @todo Remove the variable.
    $defaults['xmlsitemap_node_update_' . $node_type] = NULL;
  }
  return $defaults;
}

///**
// * Internal implementation of variable_get().
// */
//function xmlsitemap_node_var($name, $default = NULL) {
//  static $defaults;
//  if (!isset($defaults)) {
//    $defaults = xmlsitemap_node_variables();
//  }
//
//  $name = 'xmlsitemap_node_'. $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]);
//}