$t('XML sitemap'),
'value' => $t('Existing sitemap.xml file found.'),
'severity' => REQUIREMENT_ERROR,
'description' => $t('The XML sitemap module cannot display its XML output if there is an existing sitemap.xml file in your website root.'),
);
}
if ($phase == 'runtime') {
if (!user_access('access content', drupal_anonymous_user())) {
$requirements['xmlsitemap_access'] = array(
'title' => $t('XML sitemap anonymous content access'),
'value' => $t('Access denied'),
'description' => $t('In order to allow search engines to view the XML sitemap and content on your site, the anonymous user role must have the %permission permission.', array('@perm-link' => url('admin/config/people/permissions/' . DRUPAL_ANONYMOUS_RID, array('fragment' => 'module-node')), '%permission' => 'access content')),
'severity' => REQUIREMENT_ERROR,
);
}
if (!xmlsitemap_check_directory()) {
$requirements['xmlsitemap_directory'] = array(
'title' => $t('XML sitemap cache directory'),
'value' => $t('Not found or not writable'),
'severity' => REQUIREMENT_ERROR,
'description' => xmlsitemap_get_directory(),
);
}
$max_links = XMLSITEMAP_MAX_SITEMAP_LINKS * XMLSITEMAP_MAX_SITEMAP_CHUNKS;
if (xmlsitemap_get_link_count() > $max_links) {
$requirements['xmlsitemap_link_count'] = array(
'title' => $t('XML sitemap link count'),
'value' => xmlsitemap_get_link_count(),
'description' => $t('You have exceeded the number of links that your sitemap can contain (@num).', array('@num' => number_format($max_links))),
'severity' => REQUIREMENT_ERROR,
);
}
if (xmlsitemap_get_chunk_count() > XMLSITEMAP_MAX_SITEMAP_CHUNKS) {
$requirements['xmlsitemap_chunk_count'] = array(
'title' => $t('XML sitemap page count'),
'value' => xmlsitemap_get_chunk_count(),
'description' => $t('You have exceeded the number of sitemap pages (1,000).'),
'severity' => REQUIREMENT_ERROR,
);
if (!in_array(xmlsitemap_get_chunk_size(), array(50000, 'auto'))) {
$requirements['xmlsitemap_chunk_count']['description'] .= ' ' . t('Please increase the number of links per page.');
}
}
// Check when the cached files were last generated.
$generated_last = xmlsitemap_var('generated_last');
$generated_ago = REQUEST_TIME - $generated_last;
$requirements['xmlsitemap_generated'] = array(
'title' => $t('XML sitemap'),
'value' => $generated_last ? $t('Last generated on !date (!interval ago).', array('!date' => format_date($generated_last, 'small'), '!interval' => format_interval($generated_ago))) : $t('Cached files have not been generated yet.'),
'severity' => REQUIREMENT_OK,
);
if (xmlsitemap_var('rebuild_needed')) {
$requirements['xmlsitemap_generated']['severity'] = REQUIREMENT_ERROR;
$requirements['xmlsitemap_generated']['description'] = $t('The XML sitemap data is out of sync and needs to be completely rebuilt.', array('@link-rebuild' => url('admin/config/search/xmlsitemap/rebuild')));
}
elseif (xmlsitemap_var('regenerate_needed')) {
if ($generated_ago >= variable_get('cron_threshold_error', 1209600)) {
$requirements['xmlsitemap_generated']['severity'] = REQUIREMENT_ERROR;
}
elseif ($generated_ago >= variable_get('cron_threshold_warning', 172800)) {
$requirements['xmlsitemap_generated']['severity'] = REQUIREMENT_WARNING;
}
if ($requirements['xmlsitemap_generated']['severity']) {
$requirements['xmlsitemap_generated']['description'] = $t('The XML cached files are out of date and need to be regenerated. You can run cron manually to regenerate the sitemap files.', array('@link-cron' => url('admin/reports/status/run-cron', array('query' => drupal_get_destination()))));
}
}
}
return $requirements;
}
/**
* Check the status of all hook_requirements() from xmlsitemap modules.
*/
function xmlsitemap_check_status() {
$messages = &drupal_static(__FUNCTION__);
if (!isset($messages)) {
// Cache the list of modules that are checked.
if ($cache = cache_get('xmlsitemap:status:modules')) {
$modules = $cache->data;
}
else {
$modules = array();
foreach (module_implements('requirements') as $module) {
if (strpos($module, 'xmlsitemap') !== FALSE) {
$modules[] = $module;
}
}
cache_set('xmlsitemap:status:modules', $modules);
}
$messages = array();
foreach ($modules as $module) {
module_load_install($module);
$requirements = module_invoke($module, 'requirements', 'runtime');
foreach ($requirements as $requirement) {
if (isset($requirement['severity']) && max(REQUIREMENT_OK, $requirement['severity'])) {
$messages[] = $requirement['description'];
}
}
}
if ($messages) {
$message = t('One or more problems were detected with your XML sitemap configuration: !messages', array('!messages' => theme('item_list', array('items' => $messages))));
if (user_access('access site reports')) {
$message .= t('Check the status report for more information.', array('@status-report' => url('admin/reports/status')));
}
drupal_set_message($message, 'warning', FALSE);
}
}
return !empty($messages);
}
/**
* Implements hook_install().
*/
function xmlsitemap_install() {
// Set this module's weight to 1 so xmlsitemap_cron() runs after all other
// xmlsitemap_x_cron() runs.
db_update('system')
->fields(array('weight' => 1))
->condition('type', 'module')
->condition('name', 'xmlsitemap')
->execute();
// Load the module so we can use xmlsitemap_var().
drupal_load('module', 'xmlsitemap');
// Add files directory.
xmlsitemap_check_directory();
// Insert the homepage link into the {xmlsitemap} table so we do not show an
// empty sitemap after install.
db_query("INSERT INTO {xmlsitemap} (type, id, loc, priority, changefreq, language) VALUES ('frontpage', 0, '', :priority, :changefreq, :language)", array(':priority' => xmlsitemap_var('frontpage_priority'), 'changefreq' => xmlsitemap_var('frontpage_changefreq'), ':language' => LANGUAGE_NONE));
// @todo Does the sitemap show up on first install or is it a 404 page?
}
/**
* Implements hook_enable().
*/
function xmlsitemap_enable() {
variable_set('xmlsitemap_regenerate_needed', TRUE);
}
/**
* Implements hook_uninstall().
*/
function xmlsitemap_uninstall() {
// Remove variables.
drupal_load('module', 'xmlsitemap');
$variables = array_keys(xmlsitemap_variables());
foreach ($variables as $variable) {
variable_del($variable);
}
// Remove files directory.
xmlsitemap_clear_directory(TRUE);
}
/**
* Implements hook_schema().
*/
function xmlsitemap_schema() {
$schema['xmlsitemap'] = array(
'description' => 'The base table for xmlsitemap links.',
'fields' => array(
'id' => array(
'description' => 'Primary key with type; a unique id for the item.',
'type' => 'int',
'not null' => TRUE,
'unsigned' => TRUE,
'default' => 0,
),
'type' => array(
'description' => 'Primary key with id; the type of item (e.g. node, user, etc.).',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '',
),
'subtype' => array(
'description' => 'A sub-type identifier for the link (node type, menu name, term VID, etc.).',
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
),
'loc' => array(
'description' => 'The URL to the item relative to the Drupal path.',
'type' => 'varchar',
'length' => 255,
'not null' => TRUE,
'default' => '',
),
'language' => array(
'description' => 'The {languages}.language of this link or an empty string if it is language-neutral.',
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
),
'access' => array(
'description' => 'A boolean that represents if the item is viewable by the anonymous user. This field is useful to store the result of node_access() so we can retain changefreq and priority_override information.',
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 1,
),
'status' => array(
'description' => 'An integer that represents if the item is included in the sitemap.',
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 1,
),
'status_override' => array(
'description' => 'A boolean that if TRUE means that the status field has been overridden from its default value.',
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 0,
),
'lastmod' => array(
'description' => 'The UNIX timestamp of last modification of the item.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'priority' => array(
'description' => 'The priority of this URL relative to other URLs on your site. Valid values range from 0.0 to 1.0.',
'type' => 'float',
'default' => NULL,
// @todo Convert this field to non-nullable.
//'default' => 0.5,
//'not null' => NULL,
),
'priority_override' => array(
'description' => 'A boolean that if TRUE means that the priority field has been overridden from its default value.',
'type' => 'int',
'size' => 'tiny',
'not null' => TRUE,
'default' => 0,
),
'changefreq' => array(
'description' => 'The average time in seconds between changes of this item.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
'changecount' => array(
'description' => 'The number of times this item has been changed. Used to help calculate the next changefreq value.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
'default' => 0,
),
),
'primary key' => array('id', 'type'),
'indexes' => array(
'loc' => array('loc'),
'access_status_loc' => array('access', 'status', 'loc'),
'type_subtype' => array('type', 'subtype'),
'language' => array('language'),
),
);
return $schema;
}
// @todo Remove these update functions before alpha.
function xmlsitemap_update_1() {
db_drop_unique_key('xmlsitemap', 'loc');
}
function xmlsitemap_update_2() {
if (!variable_get('xmlsitemap_base_url', '')) {
variable_set('xmlsitemap_base_url', $GLOBALS['base_url']);
}
}
function xmlsitemap_update_3() {
db_add_index('xmlsitemap', 'loc', array('loc'));
}
function xmlsitemap_update_4() {
$field = array(
'type' => 'int',
'size' => 'tiny',
'default' => 1,
'unsigned' => TRUE,
);
db_change_field('xmlsitemap', 'status', 'status', $field);
db_add_index('xmlsitemap', 'status', array('status'));
}
function xmlsitemap_update_5() {
db_drop_primary_key('xmlsitemap');
db_add_primary_key('xmlsitemap', array('id', 'type'));
}
function xmlsitemap_update_6() {
if (db_column_exists('xmlsitemap', 'language')) {
db_drop_index('xmlsitemap', 'language');
db_drop_field('xmlsitemap', 'language');
}
variable_set('xmlsitemap_generated_last', variable_get('xmlsitemap_regenerate_last', 0));
variable_del('xmlsitemap_regenerate_last');
}
function xmlsitemap_update_7() {
if (xmlsitemap_load_link(array('type' => 'custom'))) {
drupal_install_modules(array('xmlsitemap_custom'));
}
variable_del('xmlsitemap_custom_links');
}
function xmlsitemap_update_8() {
$field = array(
'type' => 'float',
'default' => NULL,
);
db_add_field('xmlsitemap', 'priority_override', $field);
}
function xmlsitemap_update_9() {
$field = array(
'type' => 'int',
'default' => 0,
'unsigned' => TRUE,
'not null' => TRUE,
);
db_change_field('xmlsitemap', 'lastmod', 'lastmod', $field);
}
function xmlsitemap_update_10() {
db_update('system')
->fields(array('weight' => 1))
->condition('type', 'module')
->condition('name', 'xmlsitemap')
->execute();
}
function xmlsitemap_update_11() {
// Delete any items with NULL status and drop the status index.
db_delete('xmlsitemap')
->isNull('status')
->execute();
db_drop_index('xmlsitemap', 'status');
// Rename status to access.
$field = array(
'type' => 'int',
'size' => 'tiny',
'default' => 1,
'unsigned' => TRUE,
'not null' => TRUE,
);
db_change_field('xmlsitemap', 'status', 'access', $field);
// Add a status field.
$field = array(
'type' => 'int',
'size' => 'tiny',
'default' => 1,
);
db_add_field('xmlsitemap', 'status', $field);
db_add_index('xmlsitemap', 'access_status', array('access', 'status'));
}
function xmlsitemap_update_12() {
db_drop_index('xmlsitemap', 'access_status');
db_add_index('xmlsitemap', 'access_status_loc', array('access', 'status', 'loc'));
}
function xmlsitemap_update_13() {
db_change_field('xmlsitemap', 'priority_override', 'priority_override_value', array('type' => 'float', 'default' => NULL));
$override_field = array(
'type' => 'int',
'size' => 'tiny',
'default' => 0,
'not null' => TRUE,
);
db_add_field('xmlsitemap', 'status_override', $override_field);
db_add_field('xmlsitemap', 'priority_override', $override_field);
db_update('xmlsitemap')
->fields(array('priority_override' => 1))
->expression('priority', 'priority_override_value')
->isNotNull('priority_override_value')
->execute();
db_update('xmlsitemap')
->fields(array('priority' => 0.5))
->isNull('priority_override_value')
->execute();
db_drop_field('xmlsitemap', 'priority_override_value');
}
function xmlsitemap_update_14() {
db_add_field('xmlsitemap', 'subtype', array('type' => 'varchar', 'length' => 32, 'default' => NULL));
$fields = array('node' => 'node_type', 'menu' => 'menu_name', 'taxonomy' => 'term_vid');
foreach ($fields as $type => $field) {
if (db_column_exists('xmlsitemap', $field)) {
db_update('xmlsitemap')
->fields(array('subtype', $field))
->condition('type', $type)
->execute();
db_drop_index('xmlsitemap', $field);
db_drop_field('xmlsitemap', $field);
}
}
db_add_index('xmlsitemap', 'type_subtype', array('type', 'subtype'));
}
function xmlsitemap_update_15() {
$or = db_or();
$or->isNull('status');
$or->isNull('access');
db_delete('xmlsitemap')
->condition($or)
->execute();
$field = array(
'type' => 'int',
'size' => 'tiny',
'default' => 1,
'not null' => TRUE,
);
db_change_field('xmlsitemap', 'access', 'access', $field);
db_change_field('xmlsitemap', 'status', 'status', $field);
}
function xmlsitemap_update_16() {
$field = array(
'type' => 'varchar',
'length' => 12,
'not null' => TRUE,
'default' => '',
);
db_add_field('xmlsitemap', 'language', $field);
db_add_index('xmlsitemap', 'language', array('language'));
}
function xmlsitemap_update_17() {
db_update('xmlsitemap')
->fields(array('access' => 1))
->condition('access', 1, '>')
->execute();
db_update('xmlsitemap')
->fields(array('status' => 1))
->condition('status', 1, '>')
->execute();
}
function xmlsitemap_update_18() {
$field = array(
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
'default' => '',
);
db_change_field('xmlsitemap', 'type', 'type', $field);
$field['length'] = 128;
db_change_field('xmlsitemap', 'subtype', 'subtype', $field);
}
//@todo Update {xmlsitemap}.language from '' to LANGUAGE_NONE.