Commit dff86b92 authored by gbyte.co's avatar gbyte.co

Issue #2959479: Make sitmemap structure pluggable

parent ce20a672
......@@ -66,7 +66,7 @@ basis. Just head over to a bundle instance edit form (e.g. node/1/edit) to
override its sitemap settings.
If you wish for the sitemap to reflect the new configuration instantly, check
'Regenerate sitemap after clicking save'. This setting only appears if a change
'Regenerate sitemaps after clicking save'. This setting only appears if a change
in the settings has been detected.
As the sitemap is accessible to anonymous users, bear in mind that only links
......@@ -77,7 +77,7 @@ To include custom links into the sitemap, visit
/admin/config/search/simplesitemap/custom.
The settings page can be found under admin/config/search/simplesitemap.
Here the module can be configured and the sitemap can be manually regenerated.
Here the module can be configured and the sitemaps can be manually regenerated.
USAGE
......@@ -85,7 +85,7 @@ USAGE
The sitemap is accessible to the whole world under /sitemap.xml.
If the cron generation is turned on, the sitemap will be regenerated according
If the cron generation is turned on, the sitemaps will be regenerated according
to the 'Sitemap generation interval' setting ranging from 'On every cron run' to
'Once a week'.
......
......@@ -10,7 +10,7 @@
*/
function simple_sitemap_drush_command() {
$items['simple_sitemap-generate'] = [
'description' => 'Regenerate the XML sitemap according to the module settings.',
'description' => 'Regenerate the XML sitemaps according to the module settings.',
'callback' => 'drush_simple_sitemap_generate',
'drupal dependencies' => ['simple_sitemap'],
];
......@@ -20,7 +20,7 @@ function simple_sitemap_drush_command() {
/**
* Callback function for hook_drush_command().
*
* Regenerate the XML sitemap.
* Regenerate the XML sitemaps.
*/
function drush_simple_sitemap_generate() {
\Drupal::service('simple_sitemap.generator')->generateSitemap('drush');
......
......@@ -28,7 +28,7 @@ function simple_sitemap_requirements($phase) {
case 'runtime':
$generator = \Drupal::service('simple_sitemap.generator');
$generated_ago = $generator->getGeneratedAgo();
$generated_ago = $generator->getGeneratedAgo('default'); //todo
$cron_generation = $generator->getSetting('cron_generate');
if (!$generated_ago) {
......@@ -42,12 +42,11 @@ function simple_sitemap_requirements($phase) {
$severity = REQUIREMENT_WARNING;
}
else {
$value = t('XML sitemap is available');
$description = t('The <a href="@sitemap">XML sitemap</a> was generated @ago ago.'
$value = t('XML sitemaps are available');
$description = t('The last generation finished @ago ago.'
. ' ' . ($cron_generation
? 'Run cron, or <a href="@generate">regenerate</a> the sitemap manually.'
: 'Generation on cron run is disabled. <a href="@generate">Regenerate</a> the sitemap manually.'), [
'@sitemap' => $GLOBALS['base_url'] . '/sitemap.xml',
? 'Run cron, or <a href="@generate">regenerate</a> the sitemaps manually.'
: 'Generation on cron run is disabled. <a href="@generate">Regenerate</a> the sitemaps manually.'), [
'@ago' => $generated_ago,
'@generate' => $GLOBALS['base_url'] . '/admin/config/search/simplesitemap'
]
......@@ -80,6 +79,20 @@ function simple_sitemap_schema() {
'not null' => TRUE,
'unsigned' => TRUE,
],
'type' => [
'description' => 'Type of sitemap this chunk belongs to.',
'type' => 'varchar',
'length' => 50,
'not null' => TRUE,
'default' => '',
],
'delta' => [
'description' => 'Delta of the chunk within the type scope.',
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'unsigned' => TRUE,
],
'sitemap_string' => [
'description' => 'XML sitemap chunk string.',
'type' => 'text',
......@@ -97,6 +110,26 @@ function simple_sitemap_schema() {
'primary key' => ['id'],
];
// $schema['simple_sitemap_index'] = [
// 'description' => 'Holds XML sitemaps indexes as strings for quick retrieval.',
// 'fields' => [
// 'id' => [
// 'description' => 'Sitemap index unique identifier.',
// 'type' => 'varchar',
// 'length' => 50,
// 'not null' => TRUE,
// 'default' => '',
// ],
// 'sitemap_string' => [
// 'description' => 'XML sitemap index string.',
// 'type' => 'text',
// 'size' => 'big',
// 'not null' => TRUE,
// ]
// ],
// 'primary key' => ['id'],
// ];
$schema['simple_sitemap_entity_overrides'] = [
'description' => 'Holds sitemap settings overridden by entities.',
'fields' => [
......@@ -398,3 +431,64 @@ function simple_sitemap_update_8209() {
return t('You may now want to configure your sitemap entities to include images.');
}
/**
* Adding simple_sitemap_index table and altering the simple_sitemap table.
*/
function simple_sitemap_update_8210() {
$database = \Drupal::database();
// Create simple_sitemap_index table.
// if (!$database->schema()->tableExists('simple_sitemap_index')) {
// $database->schema()->createTable('simple_sitemap_index', [
// 'description' => 'Holds XML sitemaps indexes as strings for quick retrieval.',
// 'fields' => [
// 'id' => [
// 'description' => 'Sitemap index unique identifier.',
// 'type' => 'varchar',
// 'length' => 50,
// 'not null' => TRUE,
// 'default' => '',
// ],
// 'sitemap_string' => [
// 'description' => 'XML sitemap index string.',
// 'type' => 'text',
// 'size' => 'big',
// 'not null' => TRUE,
// ]
// ],
// 'primary key' => ['id'],
// ]);
// }
// Alter simple_sitemap table.
$database->truncate('simple_sitemap')->execute();
if (!$database->schema()->fieldExists('simple_sitemap', 'type')) {
$database->schema()->addField(
'simple_sitemap',
'type', [
'description' => 'Type of sitemap this chunk belongs to.',
'type' => 'varchar',
'length' => 50,
'not null' => TRUE,
'default' => '',
]
);
}
if (!$database->schema()->fieldExists('simple_sitemap', 'delta')) {
$database->schema()->addField(
'simple_sitemap',
'delta', [
'description' => 'Delta of the chunk within the type scope.',
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'unsigned' => TRUE,
]
);
}
}
......@@ -240,9 +240,9 @@ function simple_sitemap_delete_bundle_config($entity_type_id, $bundle) {
// Delete bundle settings.
\Drupal::service('config.factory')->getEditable("simple_sitemap.bundle_settings.$entity_type_id.$bundle")->delete();
$message = 'You may want to <a href="@url">regenerate</a> your XML sitemap now.';
$message = 'You may want to <a href="@url">regenerate</a> your XML sitemaps now.';
if ($generator->getSetting('cron_generate')) {
$message .= ' Otherwise the sitemap will be regenerated during a future cron run.';
$message .= ' Otherwise the sitemaps will be regenerated during a future cron run.';
}
drupal_set_message(t($message, ['@url' => $GLOBALS['base_url'] . '/admin/config/search/simplesitemap']));
}
......@@ -250,10 +250,13 @@ function simple_sitemap_delete_bundle_config($entity_type_id, $bundle) {
/**
* Implements hook_robotstxt().
*
* @todo Use sitemap base URL setting?
* @todo include non-default sitemaps as well?
*/
function simple_sitemap_robotstxt() {
return [
'# XML sitemap',
'Sitemap: ' . $GLOBALS['base_url'] . '/sitemap.xml', //todo: Use base URL setting?
'# XML sitemaps',
'Sitemap: ' . $GLOBALS['base_url'] . '/sitemap.xml',
];
}
simple_sitemap.sitemap:
simple_sitemap.sitemap_default:
path: '/sitemap.xml'
defaults:
_controller: '\Drupal\simple_sitemap\Controller\SimplesitemapController::getSitemap'
requirements:
_access: 'TRUE'
simple_sitemap.sitemaps:
path: '/sitemaps'
simple_sitemap.sitemap_type:
path: '/sitemaps/{type}/sitemap.xml'
defaults:
_controller: '\Drupal\simple_sitemap\Controller\SimplesitemapController::getSitemap'
requirements:
_access: 'TRUE'
simple_sitemap.chunk_fallback:
path: '/sitemaps/{chunk_id}'
simple_sitemap.sitemap_type_fallback:
path: '/sitemaps/{type}'
defaults:
_controller: '\Drupal\simple_sitemap\Controller\SimplesitemapController::getSitemap'
requirements:
_access: 'TRUE'
simple_sitemap.chunk:
path: '/sitemaps/{chunk_id}/sitemap.xml'
simple_sitemap.sitemap_type_delta:
path: '/sitemaps/{type}/{delta}/sitemap.xml'
defaults:
_controller: '\Drupal\simple_sitemap\Controller\SimplesitemapController::getSitemap'
requirements:
_access: 'TRUE'
simple_sitemap.sitemap_type_delta_fallback:
path: '/sitemaps/{type}/{delta}'
defaults:
_controller: '\Drupal\simple_sitemap\Controller\SimplesitemapController::getSitemap'
requirements:
......
......@@ -3,7 +3,6 @@ services:
class: Drupal\simple_sitemap\Simplesitemap
public: true
arguments:
- '@simple_sitemap.sitemap_generator'
- '@simple_sitemap.entity_helper'
- '@config.factory'
- '@database'
......@@ -13,21 +12,11 @@ services:
- '@datetime.time'
- '@simple_sitemap.batch'
- '@plugin.manager.simple_sitemap.url_generator'
simple_sitemap.sitemap_generator:
class: Drupal\simple_sitemap\SitemapGenerator
public: true
arguments:
- '@simple_sitemap.entity_helper'
- '@database'
- '@module_handler'
- '@language_manager'
- '@datetime.time'
- '@simple_sitemap.sitemap_writer'
- '@plugin.manager.simple_sitemap.sitemap_generator'
simple_sitemap.sitemap_writer:
class: Drupal\simple_sitemap\SitemapWriter
public: false
class: Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapWriter
public: true
simple_sitemap.entity_helper:
class: Drupal\simple_sitemap\EntityHelper
......@@ -64,3 +53,7 @@ services:
plugin.manager.simple_sitemap.url_generator:
class: Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator\UrlGeneratorManager
parent: default_plugin_manager
plugin.manager.simple_sitemap.sitemap_generator:
class: Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapGeneratorManager
parent: default_plugin_manager
<?php
namespace Drupal\simple_sitemap\Annotation;
use Drupal\Component\Annotation\Plugin;
/**
* Defines a SitemapGenerator item annotation object.
*
* @package Drupal\simple_sitemap\Annotation
*
* @see \Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapGeneratorManager
* @see plugin_api
*
* @Annotation
*/
class SitemapGenerator extends Plugin {
/**
* The generator ID.
*
* @var string
*/
public $id;
/**
* The human-readable name of the generator.
*
* @ingroup plugin_translatable
*
* @var \Drupal\Core\Annotation\Translation
*/
public $title;
/**
* A short description of the generator.
*
* @ingroup plugin_translatable
*
* @var \Drupal\Core\Annotation\Translation
*/
public $description;
/**
* An integer to determine the weight of this generator relative to others.
*
* @var int
*/
public $weight = 0;
/**
* Whether the generator is enabled by default.
*
* @var bool
*/
public $enabled = TRUE;
/**
* Default generator settings.
*
* @var array
*/
public $settings = [
'list' => TRUE,
'default' => FALSE,
];
}
......@@ -61,6 +61,7 @@ class UrlGenerator extends Plugin {
* @var array
*/
public $settings = [
'default_sitemap_generator' => 'default',
'instantiate_for_each_data_set' => FALSE,
];
}
......@@ -26,11 +26,16 @@ class Batch {
*/
protected $batchSettings;
/**
* @var array
*/
protected $batchMeta;
const BATCH_TITLE = 'Generating XML sitemap';
const BATCH_INIT_MESSAGE = 'Initializing batch...';
const BATCH_ERROR_MESSAGE = 'An error has occurred. This may result in an incomplete XML sitemap.';
const BATCH_PROGRESS_MESSAGE = 'Processing @current out of @total link types.';
const REGENERATION_FINISHED_MESSAGE = 'The <a href="@url" target="_blank">XML sitemap</a> has been regenerated.';
const REGENERATION_FINISHED_MESSAGE = 'The XML sitemaps have been regenerated.';
const REGENERATION_FINISHED_ERROR_MESSAGE = 'The sitemap generation finished with an error.';
/**
......@@ -54,11 +59,24 @@ class Batch {
$this->batchSettings = $batch_settings;
}
/**
* @param array $batch_meta
*/
public function setBatchMeta(array $batch_meta) {
$this->batchMeta = $batch_meta;
}
/**
* Starts the batch process depending on where it was requested from.
*/
public function start() {
switch ($this->batchSettings['from']) {
// Update total operation count for each operation.
foreach ($this->batch['operations'] as $i => $operation) {
$this->batch['operations'][$i][1][3]['operations_count'] = count($this->batch['operations']);
}
switch ($this->batchMeta['from']) {
case 'form':
// Start batch process.
......@@ -98,8 +116,7 @@ class Batch {
$operation[1][] = &$context;
call_user_func_array($operation[0], $operation[1]);
}
$this->finishGeneration(TRUE, !empty($context['results']) ? $context['results'] : [], []);
return TRUE;
return $this->finishGeneration(TRUE, !empty($context['results']) ? $context['results'] : [], []);
}
return FALSE;
}
......@@ -107,29 +124,32 @@ class Batch {
/**
* Adds an operation to the batch.
*
* @param $plugin_id
* @param string $url_generator_id$data_sets
* @param array|null $data_sets
*/
public function addOperation($plugin_id, $data_sets = NULL) {
$this->batch['operations'][] = [
__CLASS__ . '::generate', [$plugin_id, $data_sets, $this->batchSettings],
public function addOperation($url_generator_id, $data_sets = NULL) {
$operation_no = count($this->batch['operations']) + 1;
$this->batch['operations'][$operation_no] = [
__CLASS__ . '::generate', [$url_generator_id, $data_sets, $this->batchSettings, $this->batchMeta + ['current_operation_no' => $operation_no]],
];
}
/**
* Batch callback function which generates URLs.
*
* @param $plugin_id
* @param string $url_generator_id
* @param array|null $data_sets
* @param array $batch_settings
* @param array $batch_meta
* @param $context
*
* @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
*/
public static function generate($plugin_id, $data_sets, array $batch_settings, &$context) {
public static function generate($url_generator_id, $data_sets, array $batch_settings, array $batch_meta, &$context) {
\Drupal::service('plugin.manager.simple_sitemap.url_generator')
->createInstance($plugin_id)
->createInstance($url_generator_id)
->setContext($context)
->setBatchMeta($batch_meta)
->setBatchSettings($batch_settings)
->generate($data_sets);
}
......@@ -141,19 +161,14 @@ class Batch {
* @param $results
* @param $operations
*
* @return bool
*
* @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
*/
public static function finishGeneration($success, $results, $operations) {
if ($success) {
$remove_sitemap = empty($results['chunk_count']);
if (!empty($results['generate']) || $remove_sitemap) {
\Drupal::service('simple_sitemap.sitemap_generator')
->setSettings(['excluded_languages' => \Drupal::service('simple_sitemap.generator')->getSetting('excluded_languages', [])])
->generateSitemap(!empty($results['generate']) ? $results['generate'] : [], $remove_sitemap);
}
Cache::invalidateTags(['simple_sitemap']);
\Drupal::service('simple_sitemap.logger')->m(self::REGENERATION_FINISHED_MESSAGE,
['@url' => $GLOBALS['base_url'] . '/sitemap.xml'])
\Drupal::service('simple_sitemap.logger')->m(self::REGENERATION_FINISHED_MESSAGE)
// ['@url' => $this->sitemapGenerator->getCustomBaseUrl() . '/sitemap.xml']) //todo: Use actual base URL for message.
->display('status')
->log('info');
......@@ -163,6 +178,8 @@ class Batch {
->display('error', 'administer sitemap settings')
->log('error');
}
return $success;
}
}
......@@ -25,7 +25,7 @@ class SimplesitemapCommands extends DrushCommands {
}
/**
* Regenerate the XML sitemap according to the module settings.
* Regenerate the XML sitemaps according to the module settings.
*
* @command simple-sitemap:generate
* @validate-module-enabled simple_sitemap
......
......@@ -8,6 +8,7 @@ use Symfony\Component\HttpFoundation\Response;
use Drupal\Core\Cache\CacheableResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Drupal\simple_sitemap\Simplesitemap;
use Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapGeneratorBase;
use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
/**
......@@ -47,11 +48,16 @@ class SimplesitemapController extends ControllerBase {
}
/**
* Returns the whole sitemap, a requested sitemap chunk, or the sitemap index file.
* Returns the whole sitemap of a certain type, its requested sitemap chunk,
* or its sitemap index file.
* Caches the response in case of expected output, prevents caching otherwise.
*
* @param int $chunk_id
* Optional ID of the sitemap chunk. If none provided, the first chunk or
* @param string $type
* Optional name of sitemap type. This corresponds to the plugin ID
* of the sitemap generator plugin to be responsible for the generation.
*
* @param int $delta
* Optional delta of the sitemap chunk. If none provided, the first chunk or
* the sitemap index is fetched.
*
* @throws NotFoundHttpException
......@@ -59,14 +65,13 @@ class SimplesitemapController extends ControllerBase {
* @return object
* Returns an XML response.
*/
public function getSitemap($chunk_id = NULL) {
$output = $this->generator->getSitemap($chunk_id);
public function getSitemap($type = SitemapGeneratorBase::DEFAULT_SITEMAP_TYPE, $delta = NULL) {
$output = $this->generator->getSitemap($type, $delta);
if (!$output) {
$this->cacheKillSwitch->trigger();
throw new NotFoundHttpException();
}
// Display sitemap with correct XML header.
$response = new CacheableResponse($output, Response::HTTP_OK, [
'content-type' => 'application/xml',
'X-Robots-Tag' => 'noindex', // Do not index the sitemap itself.
......
......@@ -27,13 +27,13 @@ class SimplesitemapSettingsForm extends SimplesitemapFormBase {
$form['simple_sitemap_settings']['regenerate'] = [
'#type' => 'fieldset',
'#title' => $this->t('Regenerate sitemap'),
'#markup' => '<p>' . $this->t('This will regenerate the XML sitemap immediately.') . '</p>',
'#title' => $this->t('Regenerate sitemaps'),
'#markup' => '<p>' . $this->t('This will regenerate the XML sitemaps immediately.') . '</p>',
];
$form['simple_sitemap_settings']['regenerate']['regenerate_submit'] = [
'#type' => 'submit',
'#value' => $this->t('Regenerate sitemap'),
'#value' => $this->t('Regenerate sitemaps'),
'#submit' => ['::generateSitemap'],
// Skip form-level validator.
'#validate' => [],
......@@ -46,8 +46,8 @@ class SimplesitemapSettingsForm extends SimplesitemapFormBase {
$form['simple_sitemap_settings']['settings']['cron_generate'] = [
'#type' => 'checkbox',
'#title' => $this->t('Regenerate the sitemap during cron runs'),
'#description' => $this->t('Uncheck this if you intend to only regenerate the sitemap manually or via drush.'),
'#title' => $this->t('Regenerate the sitemaps during cron runs'),
'#description' => $this->t('Uncheck this if you intend to only regenerate the sitemaps manually or via drush.'),
'#default_value' => $this->generator->getSetting('cron_generate', TRUE),
];
......
<?php
namespace Drupal\simple_sitemap;
namespace Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Database\Connection;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Component\Datetime\Time;
/**
* Class SitemapGenerator
* @package Drupal\simple_sitemap
*/
class SitemapGenerator {
* Class DefaultSitemapGenerator
* @package Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator
*
* @SitemapGenerator(
* id = "default",
* title = @Translation("Default sitemap generator"),
* description = @Translation("Generates a standard conform hreflang sitemap of your content."),
* weight = 0,
* settings = {
* "default" = true,
* },
* )
*/
class DefaultSitemapGenerator extends SitemapGeneratorBase {
const XML_VERSION = '1.0';
const ENCODING = 'UTF-8';
const XMLNS = 'http://www.sitemaps.org/schemas/sitemap/0.9';
const XMLNS_XHTML = 'http://www.w3.org/1999/xhtml';
const GENERATED_BY = 'Generated by the Simple XML sitemap Drupal module: https://drupal.org/project/simple_sitemap.';
const FIRST_CHUNK_INDEX = 1;
const XMLNS_IMAGE = 'http://www.google.com/schemas/sitemap-image/1.1';
/**
* @var \Drupal\simple_sitemap\EntityHelper
*/
protected $entityHelper;
/**
* @var \Drupal\Core\Database\Connection
*/
protected $db;
/**
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* @var \Drupal\Core\Extension\ModuleHandler
*/
protected $moduleHandler;
/**
* @var bool
*/
protected $isHreflangSitemap;
/**
* @var \Drupal\Component\Datetime\Time
*/
protected $time;
/**
* @var array
*/
protected $settings;
/**
* @var \XMLWriter
*/
protected $writer;
/**
* @var array
*/
......@@ -71,120 +37,53 @@ class SitemapGenerator {
];
/**
* @var array
*/
protected static $indexAttributes = [
'xmlns' => self::XMLNS,
];
/**
* SitemapGenerator constructor.
* @param \Drupal\simple_sitemap\EntityHelper $entityHelper
* DefaultSitemapGenerator constructor.
* @param array $configuration
* @param string $plugin_id
* @param mixed $plugin_definition
* @param \Drupal\Core\Database\Connection $database
* @param \Drupal\Core\Extension\ModuleHandler $module_handler
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* @param \Drupal\Component\Datetime\Time $time
* @param \Drupal\simple_sitemap\SitemapWriter $sitemapWriter
* @param \Drupal\simple_sitemap\Plugin\simple_sitemap\SitemapGenerator\SitemapWriter $sitemapWriter
*/
public function __construct(
EntityHelper $entityHelper,
array $configuration,
$plugin_id,
$plugin_definition,
Connection $database,
ModuleHandler $module_handler,
LanguageManagerInterface $language_manager,
Time $time,
SitemapWriter $sitemapWriter
) {
$this->entityHelper = $entityHelper;
$this->db = $database;
$this->moduleHandler = $module_handler;
$this->languageManager = $language_manager;
$this->time = $time;
$this->writer = $sitemapWriter;
}
/**
* @return bool
*/
protected function isHreflangSitemap() {
if (NULL === $this->isHreflangSitemap) {
$this->isHreflangSitemap = count(array_diff_key($this->languageManager->getLanguages(), $this->settings['excluded_languages'])) > 1;
}
return $this->isHreflangSitemap;
}
/**
* @param array $settings
* @return $this
*/
public function setSettings(array $settings) {
$this->settings = $settings;
return $this;
}
/**
* Wrapper method which takes links along with their options and then
* generates and saves the sitemap.
*
* @param array $links
* All links with their multilingual versions and settings.
* @param bool $remove_sitemap
* Remove old sitemap from database before inserting the new one.
*/
public function generateSitemap(array $links, $remove_sitemap = FALSE) {
$values = [
'id' => $remove_sitemap ? self::FIRST_CHUNK_INDEX
: $this->db->query('SELECT MAX(id) FROM {simple_sitemap}')
->fetchField() + 1,
'sitemap_string' => $this->generateSitemapChunk($links),
'sitemap_created' => $this->time->getRequestTime(),
];
if ($remove_sitemap) {
$this->db->truncate('simple_sitemap')->execute();
}
$this->db->insert('simple_sitemap')->fields($values)->execute();
}
/**
* Generates and returns the sitemap index for all sitemap chunks.