$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.