Commit 1435e326 authored by Dave Reid's avatar Dave Reid

by Dave Reid: Changed generation to work by basic contexts instead of...

by Dave Reid: Changed generation to work by basic contexts instead of hard-coded language and added temporary context fallback.
parent f55df410
......@@ -44,6 +44,34 @@ function xmlsitemap_get_path_alias($path, $language) {
}
}
function xmlsitemap_get_url_options_from_context(array $context) {
$options = module_invoke_all('xmlsitemap_context_url_options', $context);
drupal_alter('xmlsitemap_context_url_options', $options, $context);
return $options;
}
/**
* @todo Replace with table of sitemap objects.
*/
function xmlsitemap_get_contexts() {
$contexts = array();
if (module_exists('xmlsitemap_i18n')) {
foreach (xmlsitemap_var('languages') as $langcode) {
$contexts[] = array('language' => $langcode);
}
}
else {
// Add an empty, default context.
$contexts[] = array();
}
$hashes = array_map('md5', array_map('serialize', $contexts));
$contexts = array_combine($hashes, $contexts);
return $contexts;
}
/**
* Delete and regenerate the sitemap files.
*/
......@@ -51,15 +79,15 @@ function xmlsitemap_regenerate() {
_xmlsitemap_regenerate_before();
// Generate the sitemap pages.
$contexts = xmlsitemap_get_contexts();
$chunk_count = xmlsitemap_get_chunk_count(TRUE);
foreach (xmlsitemap_var('languages') as $langcode) {
$language = xmlsitemap_language_load($langcode);
foreach ($contexts as $context) {
// Generate index.
if ($chunk_count > 1) {
xmlsitemap_generate('index', $language);
xmlsitemap_generate('index', $context);
}
for ($i = 1; $i <= $chunk_count; $i++) {
xmlsitemap_generate($i, $language);
xmlsitemap_generate($i, $context);
}
}
......@@ -160,21 +188,13 @@ function _xmlsitemap_regenerate_after() {
*
* @todo Revise/simplify or remove the function.
*/
function xmlsitemap_generate($chunk, $language = NULL) {
function xmlsitemap_generate($chunk, array $context) {
if (($chunk == 'index' && xmlsitemap_get_chunk_count() < 2) || ($chunk != 'index' && (!is_numeric($chunk) || $chunk > xmlsitemap_get_chunk_count()))) {
// Don't bother translating this string.
trigger_error('Improper condition hit in xmlsitemap_generate(). Chunk: ' . $chunk . ', Chunk Count: ' . xmlsitemap_get_chunk_count());
return FALSE;
}
if (!isset($language)) {
$language = language_default();
}
$context = array();
if (module_exists('xmlsitemap_i18n')) {
$context['language'] = $language->language;
}
$file = xmlsitemap_get_file_from_context($context, $chunk);
if (!$handle = fopen($file, 'wb')) {
......@@ -184,10 +204,10 @@ function xmlsitemap_generate($chunk, $language = NULL) {
$status = TRUE;
if ($chunk == 'index') {
xmlsitemap_generate_index($handle, $status, $language);
xmlsitemap_generate_index($handle, $status, $context);
}
else {
xmlsitemap_generate_chunk($handle, $status, $chunk, $language);
xmlsitemap_generate_chunk($handle, $status, $chunk, $context);
}
fclose($handle);
......@@ -208,10 +228,6 @@ function xmlsitemap_generate($chunk, $language = NULL) {
return $status;
}
//function xmlsitemap_fwrite($handle, &$status, $string) {
// $status &= (bool) fwrite($handle, $string);
//}
/**
* Write the proper XML sitemap header.
*
......@@ -221,12 +237,13 @@ function xmlsitemap_generate($chunk, $language = NULL) {
* @param $status
* @param $language
*/
function xmlsitemap_generate_chunk_header($type, $handle, &$status, $language) {
function xmlsitemap_generate_chunk_header($type, $handle, &$status, array $context) {
$output = '<?xml version="1.0" encoding="UTF-8"?>' . PHP_EOL;
$url_options = xmlsitemap_get_url_options_from_context($context);
// Add the stylesheet link.
if (xmlsitemap_var('xsl')) {
$xsl_url = url('sitemap.xsl', array('language' => $language, 'base_url' => xmlsitemap_var('base_url')));
$xsl_url = url('sitemap.xsl', $url_options);
$output .= '<?xml-stylesheet type="text/xsl" href="' . $xsl_url . '"?>' . PHP_EOL;
}
......@@ -256,9 +273,16 @@ function xmlsitemap_generate_chunk_header($type, $handle, &$status, $language) {
* @param $language
* A language object for the sitemap chunk.
*/
function xmlsitemap_generate_chunk($handle, &$status, $chunk, $language) {
function xmlsitemap_generate_chunk($handle, &$status, $chunk, array $context) {
$url_options = xmlsitemap_get_url_options_from_context($context);
$url_options += array(
'absolute' => TRUE,
'base_url' => xmlsitemap_var('base_url'),
'alias' => TRUE,
'language' => language_default(),
);
$last_url = '';
$url_options = xmlsitemap_get_url_options(array('alias' => TRUE));
$lastmod_format = variable_get('xmlsitemap_lastmod_format', 'Y-m-d\TH:i\Z');
$query = db_select('xmlsitemap', 'x');
......@@ -268,7 +292,7 @@ function xmlsitemap_generate_chunk($handle, &$status, $chunk, $language) {
$query->orderBy('language', 'DESC');
$query->orderBy('loc');
$query->addTag('xmlsitemap');
$query->addMetaData('language', $language);
$query->addMetaData('context', $context);
$offset = max($chunk - 1, 0) * xmlsitemap_get_chunk_size();
$limit = xmlsitemap_get_chunk_size();
......@@ -276,13 +300,12 @@ function xmlsitemap_generate_chunk($handle, &$status, $chunk, $language) {
$links = $query->execute();
// Add the XML header and XSL if desired.
xmlsitemap_generate_chunk_header('urlset', $handle, $status, $language);
xmlsitemap_generate_chunk_header('urlset', $handle, $status, $context);
while ($link = $links->fetchAssoc()) {
$url_options['language'] = ($link['language'] != LANGUAGE_NONE ? xmlsitemap_language_load($link['language']) : $language);
// @todo $url_options['langauge'] could be NULL if language was not found.
$link['alias'] = xmlsitemap_get_path_alias($link['loc'], $url_options['language']->language);
$link_url = url($link['alias'], $url_options);
$link['language'] = $link['language'] ? xmlsitemap_language_load($link['language']) : $url_options['language'];
$link['alias'] = xmlsitemap_get_path_alias($link['loc'], $link['language']->language);
$link_url = url($link['alias'], array('language' => $link['language']) + $url_options);
// Skip this link if it was a duplicate of the last one.
// @todo Figure out a way to do this before generation so we can report
......@@ -331,13 +354,20 @@ function xmlsitemap_generate_chunk($handle, &$status, $chunk, $language) {
* @param $language
* A language object, defaults to the default language.
*/
function xmlsitemap_generate_index($handle, &$status, $language) {
$url_options = xmlsitemap_get_url_options(array('language' => $language, 'alias' => TRUE));
function xmlsitemap_generate_index($handle, &$status, array $context) {
$url_options = xmlsitemap_get_url_options_from_context($context);
$url_options += array(
'absolute' => TRUE,
'base_url' => xmlsitemap_var('base_url'),
'alias' => TRUE,
'language' => language_default(),
);
$chunk_count = xmlsitemap_get_chunk_count(TRUE);
$lastmod_format = variable_get('xmlsitemap_lastmod_format', 'Y-m-d\TH:i\Z');
// Add the XML header and XSL if desired.
xmlsitemap_generate_chunk_header('sitemapindex', $handle, $status, $language);
xmlsitemap_generate_chunk_header('sitemapindex', $handle, $status, $context);
for ($i = 1; $i <= $chunk_count; $i++) {
$output = '<sitemap>';
......@@ -374,10 +404,11 @@ function xmlsitemap_rebuild_batch(array $entities, array $callbacks, $save_custo
$batch['operations'][] = array($callbacks[$entity], array($entity));
}
// Generate all the sitemap pages.
// Generate all the sitemap pages for each context.
$batch['operations'][] = array('_xmlsitemap_regenerate_before', array());
foreach (xmlsitemap_var('languages') as $language) {
$batch['operations'][] = array('xmlsitemap_rebuild_batch_generate', array(xmlsitemap_language_load($language)));
$contexts = xmlsitemap_get_contexts();
foreach ($contexts as $context) {
$batch['operations'][] = array('xmlsitemap_rebuild_batch_generate', array($context));
}
$batch['operations'][] = array('_xmlsitemap_regenerate_after', array());
......@@ -446,21 +477,21 @@ function xmlsitemap_rebuild_batch_fetch($entity, &$context) {
}
/**
* Batch callback; generate the sitemap chunks for a language.
* Batch callback; generate the sitemap chunks for a context.
*/
function xmlsitemap_rebuild_batch_generate($language, &$context) {
function xmlsitemap_rebuild_batch_generate(array $sitemap_context, array &$context) {
if (!isset($context['sandbox']['progress'])) {
$context['sandbox']['progress'] = 1;
$context['sandbox']['max'] = xmlsitemap_get_chunk_count(TRUE);
if ($context['sandbox']['max'] > 1) {
xmlsitemap_generate('index', $language);
xmlsitemap_generate('index', $sitemap_context);
}
// Bump the max number up by one since it gets incremented after generation.
$context['sandbox']['max']++;
}
xmlsitemap_generate($context['sandbox']['progress'], $language);
$context['message'] = t('Now generating @language sitemap page @chunk.', array('@language' => $language->name, '@chunk' => $context['sandbox']['progress']));
xmlsitemap_generate($context['sandbox']['progress'], $sitemap_context);
$context['message'] = t('Now generating sitemap page @chunk.', array('@chunk' => $context['sandbox']['progress']));
$context['sandbox']['progress']++;
if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
......
......@@ -9,35 +9,88 @@
*/
/**
* Output a sitemap page.
* Get the sitemap context of the current request.
*/
function xmlsitemap_get_current_context() {
static $context;
if (!isset($context)) {
$context = module_invoke_all('xmlsitemap_context');
drupal_alter('xmlsitemap_context', $context);
asort($context);
}
return $context;
}
/**
* Validate the context and use the default context if it fails validation.
*
* @see xmlsitemap_file_transfer()
* @todo Merge into xmlsitemap_get_current_context()?
* @todo Use real default context variable instead of hard-coded default.
*/
function xmlsitemap_output_chunk() {
$context = module_invoke_all('xmlsitemap_context');
drupal_alter('xmlsitemap_context', $context);
function xmlsitemap_context_check(array $context) {
$hash = md5(serialize($context));
$default = array();
if (module_exists('xmlsitemap_i18n')) {
$default['language'] = language_default('language');
}
$default_hash = md5(serialize($default));
module_load_include('inc', 'xmlsitemap', 'xmlsitemap.generate');
$valid_contexts = array_keys(xmlsitemap_get_contexts());
if (in_array($hash, $valid_contexts)) {
return $context;
}
elseif (in_array($default_hash, $valid_contexts)) {
return $default;
}
else {
trigger_error("Could not find fallback XML sitemap context. Context $hash: " . print_r($context, TRUE) . ". Default context $default_hash: " . print_r($default, TRUE), E_USER_ERROR);
return array();
}
}
/**
* Get the sitemap chunk/page of the current request.
*/
function xmlsitemap_get_current_chunk(array $context) {
// Check if we should be displaing the index.
if (!isset($_GET['page']) || !is_numeric($_GET['page'])) {
$index_file = xmlsitemap_get_file_from_context($context, 'index');
if (file_exists($index_file)) {
$chunk = 'index';
return 'index';
}
else {
$chunk = 1;
return 1;
}
}
else {
$chunk = (int) $_GET['page'];
return (int) $_GET['page'];
}
}
// Fallback to non-context sitemap?
/**
* Output a sitemap page.
*
* @see xmlsitemap_get_current_context()
* @see xmlsitemap_get_current_chunk()
* @see xmlsitemap_get_file_from_context()
* @see xmlsitemap_output_file()
*/
function xmlsitemap_output_chunk() {
$original_context = xmlsitemap_get_current_context();
$context = xmlsitemap_context_check($original_context);
$chunk = xmlsitemap_get_current_chunk($context);
$file = xmlsitemap_get_file_from_context($context, $chunk);
// Provide debugging information if enabled.
if (variable_get('xmlsitemap_developer_mode', 0) && isset($_GET['debug'])) {
$output = array();
$output[] = "Chunk: $chunk";
$output[] = "Original context: " . print_r($original_context, TRUE);
$output[] = "Context: " . print_r($context, TRUE);
$output[] = "Cache file location: $file";
$output[] = "Cache file exists: " . (file_exists($file) ? 'Yes' : 'No');
......
......@@ -11,6 +11,42 @@ function xmlsitemap_i18n_xmlsitemap_context() {
return $context;
}
function xmlsitemap_i18n_xmlsitemap_context_url_options(array $context) {
$options = array();
if (isset($context['language'])) {
$options['language'] = xmlsitemap_language_load($context['language']);
}
return $options;
}
/**
* Implements hook_xmlsitemap_context().
*/
function xmlsitemap_i18n_xmlsitemap_context_fallback() {
$context['language'] = language_default('language');
return $context;
}
function xmlsitemap_i18n_xmlsitemap_context_info() {
$context['language'] = array(
'label' => t('Language'),
'summary callback' => 'locale_language_name',
'settings callback' => 'xmlsitemap_i18n_xmlsitemap_language_context_settings',
);
return $context;
}
function xmlsitemap_i18n_xmlsitemap_language_context_settings(stdClass $sitemap) {
$form['language'] = array(
'#type' => 'select',
'#title' => t('Language'),
'#options' => locale_language_list(),
'#default_value' => issset($sitemap->context['language']) ? $sitemap->context['language'] : '',
'#description' => t("Each language's sitemap will respect the <a href=\"@i18n-settings\">multilingual content selection mode</a>.", array('@i18n-settings' => url('admin/settings/language/i18n'))),
);
return $form;
}
/**
* Implements hook_form_FORM_ID_alter().
*
......@@ -36,9 +72,15 @@ function xmlsitemap_i18n_form_xmlsitemap_settings_form_alter(&$form, $form_state
* @see i18n_db_rewrite_where()
*/
function xmlsitemap_i18n_query_xmlsitemap_alter(QueryAlterableInterface $query) {
// Get languages to simplify query building.
$mode = variable_get('i18n_selection_mode', 'simple');
$current = $query->getMetaData('language')->language;
$context = $query->getMetaData('context');
if (!isset($context['language']) || $mode == 'off') {
return;
}
// Get languages to simplify query building.
$current = $context['language'];
$default = i18n_default_language();
if ($mode == 'mixed' && $current == $default) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment