Commit 74b81873 authored by gbyte.co's avatar gbyte.co

Refactor generators to make them pluggable through hook

parent 4a159db7
......@@ -11,12 +11,13 @@ services:
- '@path.validator'
- '@date.formatter'
- '@datetime.time'
- '@simple_sitemap.batch'
- '@module_handler'
simple_sitemap.sitemap_generator:
class: Drupal\simple_sitemap\SitemapGenerator
public: true
arguments:
- '@simple_sitemap.batch'
- '@simple_sitemap.entity_helper'
- '@database'
- '@module_handler'
......@@ -75,6 +76,7 @@ services:
- '@entity_type.manager'
- '@simple_sitemap.logger'
- '@simple_sitemap.entity_helper'
- '@module_handler'
simple_sitemap.logger:
class: Drupal\simple_sitemap\Logger
......
......@@ -107,11 +107,10 @@ class Batch {
* Adds an operation to the batch.
*
* @param string $processing_service
* @param array $data
*/
public function addOperation($processing_service, array $data) {
public function addOperation($processing_service) {
$this->batch['operations'][] = [
__CLASS__ . '::generate', [$processing_service, $data, $this->batchInfo],
__CLASS__ . '::generate', [$processing_service, $this->batchInfo],
];
}
......@@ -119,17 +118,16 @@ class Batch {
* Batch callback function which generates URLs.
*
* @param $processing_service
* @param array $data
* @param array $batch_info
* @param $context
*
* @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
*/
public static function generate($processing_service, array $data, array $batch_info, &$context) {
public static function generate($processing_service, array $batch_info, &$context) {
\Drupal::service($processing_service)
->setContext($context)
->setBatchInfo($batch_info)
->generate($data);
->generate();
}
/**
......
......@@ -2,21 +2,66 @@
namespace Drupal\simple_sitemap\Batch\Generator;
use Drupal\simple_sitemap\EntityHelper;
use Drupal\simple_sitemap\Logger;
use Drupal\simple_sitemap\Simplesitemap;
use Drupal\simple_sitemap\SitemapGenerator;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
/**
* Class ArbitraryUrlGenerator
* @package Drupal\simple_sitemap\Batch\Generator
*/
class ArbitraryUrlGenerator extends UrlGeneratorBase implements UrlGeneratorInterface {
protected $moduleHandler;
/**
* ArbitraryUrlGenerator constructor.
* @param \Drupal\simple_sitemap\Simplesitemap $generator
* @param \Drupal\simple_sitemap\SitemapGenerator $sitemap_generator
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* @param \Drupal\simple_sitemap\Logger $logger
* @param \Drupal\simple_sitemap\EntityHelper $entityHelper
* @param \Drupal\Core\Extension\ModuleHandler $module_handler
*/
public function __construct(
Simplesitemap $generator,
SitemapGenerator $sitemap_generator,
LanguageManagerInterface $language_manager,
EntityTypeManagerInterface $entity_type_manager,
Logger $logger,
EntityHelper $entityHelper,
ModuleHandler $module_handler
) {
parent::__construct(
$generator,
$sitemap_generator,
$language_manager,
$entity_type_manager,
$logger,
$entityHelper
);
$this->moduleHandler = $module_handler;
}
/**
* @return array
*/
protected function getData() {
$arbitrary_links = [];
$this->moduleHandler->alter('simple_sitemap_arbitrary_links', $arbitrary_links);
return $arbitrary_links;
}
/**
* Batch function that adds arbitrary URLs to the sitemap.
*
* @param mixed $arbitrary_paths
*
* @see \hook_simple_sitemap_arbitrary_links_alter()
*/
public function generate($arbitrary_paths) {
foreach ($this->getBatchIterationElements(array_values($arbitrary_paths)) as $i => $path_data) {
public function generate() {
foreach ($this->getBatchIterationElements(array_values($this->getData())) as $i => $path_data) {
$this->setCurrentId($i);
$this->addUrl($path_data);
}
......
......@@ -2,10 +2,6 @@
namespace Drupal\simple_sitemap\Batch\Generator;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\Entity;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\simple_sitemap\EntityHelper;
use Drupal\simple_sitemap\Logger;
......@@ -53,7 +49,6 @@ class CustomUrlGenerator extends UrlGeneratorBase implements UrlGeneratorInterfa
EntityHelper $entityHelper,
PathValidator $path_validator
) {
$this->pathValidator = $path_validator;
parent::__construct(
$generator,
$sitemap_generator,
......@@ -62,18 +57,25 @@ class CustomUrlGenerator extends UrlGeneratorBase implements UrlGeneratorInterfa
$logger,
$entityHelper
);
$this->pathValidator = $path_validator;
}
/**
* @return array
*/
protected function getData() {
return $this->generator->getCustomLinks();
}
/**
* Batch function which generates urls to custom paths.
*
* @param mixed $custom_paths
*/
public function generate($custom_paths) {
public function generate() {
$this->includeImages = $this->generator->getSetting('custom_links_include_images', FALSE);
foreach ($this->getBatchIterationElements($custom_paths) as $i => $custom_path) {
foreach ($this->getBatchIterationElements($this->getData()) as $i => $custom_path) {
$this->setCurrentId($i);
......
......@@ -9,68 +9,96 @@ namespace Drupal\simple_sitemap\Batch\Generator;
class EntityUrlGenerator extends UrlGeneratorBase implements UrlGeneratorInterface {
/**
* Batch callback function which generates urls to entity paths.
*
* @param mixed $entity_info
* @return array
*/
public function generate($entity_info) {
foreach ($this->getBatchIterationElements($entity_info) as $entity_id => $entity) {
$this->setCurrentId($entity_id);
$entity_settings = $this->generator->getEntityInstanceSettings($entity_info['entity_type_name'], $entity_id);
if (empty($entity_settings['index'])) {
continue;
}
switch ($entity_info['entity_type_name']) {
// Loading url object for menu links.
case 'menu_link_content':
if (!$entity->isEnabled()) {
continue 2;
protected function getData() {
$data_sets = [];
$sitemap_entity_types = $this->entityHelper->getSupportedEntityTypes();
foreach ($this->generator->getBundleSettings() as $entity_type_name => $bundles) {
if (isset($sitemap_entity_types[$entity_type_name])) {
$keys = $sitemap_entity_types[$entity_type_name]->getKeys();
// Menu fix.
$keys['bundle'] = $entity_type_name == 'menu_link_content' ? 'menu_name' : $keys['bundle'];
foreach ($bundles as $bundle_name => $bundle_settings) {
if ($bundle_settings['index']) {
$data_sets[] = [
'bundle_settings' => $bundle_settings,
'bundle_name' => $bundle_name,
'entity_type_name' => $entity_type_name,
'keys' => $keys,
];
}
$url_object = $entity->getUrlObject();
break;
// Loading url object for other entities.
default:
$url_object = $entity->toUrl();
}
}
}
return $data_sets;
}
// Do not include external paths.
if (!$url_object->isRouted()) {
continue;
}
$path = $url_object->getInternalPath();
// Do not include paths that have been already indexed.
if ($this->batchInfo['remove_duplicates'] && $this->pathProcessed($path)) {
continue;
/**
* Batch callback function which generates urls to entity paths.
*/
public function generate() {
foreach ($this->getData() as $entity_info) {
foreach ($this->getBatchIterationElements($entity_info) as $entity_id => $entity) {
$this->setCurrentId($entity_id);
$entity_settings = $this->generator->getEntityInstanceSettings($entity_info['entity_type_name'], $entity_id);
if (empty($entity_settings['index'])) {
continue;
}
switch ($entity_info['entity_type_name']) {
// Loading url object for menu links.
case 'menu_link_content':
if (!$entity->isEnabled()) {
continue 2;
}
$url_object = $entity->getUrlObject();
break;
// Loading url object for other entities.
default:
$url_object = $entity->toUrl();
}
// Do not include external paths.
if (!$url_object->isRouted()) {
continue;
}
$path = $url_object->getInternalPath();
// Do not include paths that have been already indexed.
if ($this->batchInfo['remove_duplicates'] && $this->pathProcessed($path)) {
continue;
}
$url_object->setOption('absolute', TRUE);
$path_data = [
'path' => $path,
'entity_info' => [
'entity_type' => $entity_info['entity_type_name'],
'id' => $entity_id
],
'lastmod' => method_exists($entity, 'getChangedTime')
? date_iso8601($entity->getChangedTime()) : NULL,
'priority' => isset($entity_settings['priority']) ? $entity_settings['priority'] : NULL,
'changefreq' => !empty($entity_settings['changefreq']) ? $entity_settings['changefreq'] : NULL,
'images' => !empty($entity_settings['include_images'])
? $this->getImages($entity_info['entity_type_name'], $entity_id)
: []
];
$this->addUrl($path_data, $url_object);
}
$url_object->setOption('absolute', TRUE);
$path_data = [
'path' => $path,
'entity_info' => [
'entity_type' => $entity_info['entity_type_name'],
'id' => $entity_id
],
'lastmod' => method_exists($entity, 'getChangedTime')
? date_iso8601($entity->getChangedTime()) : NULL,
'priority' => isset($entity_settings['priority']) ? $entity_settings['priority'] : NULL,
'changefreq' => !empty($entity_settings['changefreq']) ? $entity_settings['changefreq'] : NULL,
'images' => !empty($entity_settings['include_images'])
? $this->getImages($entity_info['entity_type_name'], $entity_id)
: []
];
$this->addUrl($path_data, $url_object);
$this->processSegment();
}
$this->processSegment();
}
/**
......
......@@ -4,7 +4,6 @@ namespace Drupal\simple_sitemap\Batch\Generator;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\ContentEntityBase;
use Drupal\Core\Entity\Entity;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Url;
use Drupal\simple_sitemap\EntityHelper;
......
......@@ -8,9 +8,6 @@ namespace Drupal\simple_sitemap\Batch\Generator;
*/
interface UrlGeneratorInterface {
/**
* @param mixed $data
*/
public function generate($data);
public function generate();
}
......@@ -8,6 +8,8 @@ use Drupal\Core\Path\PathValidator;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Component\Datetime\Time;
use Drupal\simple_sitemap\Batch\Batch;
use Drupal\Core\Extension\ModuleHandler;
/**
* Class Simplesitemap
......@@ -55,6 +57,16 @@ class Simplesitemap {
*/
protected $time;
/**
* @var \Drupal\simple_sitemap\Batch\Batch
*/
protected $batch;
/**
* @var \Drupal\Core\Extension\ModuleHandler
*/
protected $moduleHandler;
/**
* @var array
*/
......@@ -73,6 +85,12 @@ class Simplesitemap {
'include_images' => 0,
];
protected static $generatorServices = [
'simple_sitemap.custom_url_generator',
'simple_sitemap.entity_url_generator',
'simple_sitemap.arbitrary_url_generator',
];
/**
* Simplesitemap constructor.
* @param \Drupal\simple_sitemap\SitemapGenerator $sitemapGenerator
......@@ -83,6 +101,8 @@ class Simplesitemap {
* @param \Drupal\Core\Path\PathValidator $pathValidator
* @param \Drupal\Core\Datetime\DateFormatter $dateFormatter
* @param \Drupal\Component\Datetime\Time $time
* @param \Drupal\simple_sitemap\Batch\Batch $batch
* @param \Drupal\Core\Extension\ModuleHandler $module_handler
*/
public function __construct(
SitemapGenerator $sitemapGenerator,
......@@ -92,7 +112,9 @@ class Simplesitemap {
EntityTypeManagerInterface $entityTypeManager,
PathValidator $pathValidator,
DateFormatter $dateFormatter,
Time $time
Time $time,
Batch $batch,
ModuleHandler $module_handler
) {
$this->sitemapGenerator = $sitemapGenerator;
$this->entityHelper = $entityHelper;
......@@ -102,6 +124,8 @@ class Simplesitemap {
$this->pathValidator = $pathValidator;
$this->dateFormatter = $dateFormatter;
$this->time = $time;
$this->batch = $batch;
$this->moduleHandler = $module_handler;
}
/**
......@@ -210,19 +234,24 @@ class Simplesitemap {
* This decides how the batch process is to be run.
*/
public function generateSitemap($from = 'form') {
$this->sitemapGenerator
->setBundleSettings($this->getBundleSettings())
->setCustomLinks($this->getCustomLinks())
->setSettings([
'base_url' => $this->getSetting('base_url', ''),
'batch_process_limit' => $this->getSetting('batch_process_limit', NULL),
'max_links' => $this->getSetting('max_links', 2000),
'skip_untranslated' => $this->getSetting('skip_untranslated', FALSE),
'remove_duplicates' => $this->getSetting('remove_duplicates', TRUE),
'excluded_languages' => $this->getSetting('excluded_languages', []),
'from' => $from,
])
->startGeneration();
$this->batch->setBatchInfo([
'base_url' => $this->getSetting('base_url', ''),
'batch_process_limit' => $this->getSetting('batch_process_limit', NULL),
'max_links' => $this->getSetting('max_links', 2000),
'skip_untranslated' => $this->getSetting('skip_untranslated', FALSE),
'remove_duplicates' => $this->getSetting('remove_duplicates', TRUE),
'excluded_languages' => $this->getSetting('excluded_languages', []),
'from' => $from,
]);
$this->moduleHandler->alter('simple_sitemap_generator_services', self::$generatorServices);
foreach (self::$generatorServices as $service) {
$this->batch->addOperation($service);
}
$this->batch->start();
}
/**
......@@ -233,6 +262,8 @@ class Simplesitemap {
*
* @return string
* The sitemap index.
*
* @todo Need to make sure response is cached.
*/
protected function getSitemapIndex($chunk_info) {
return $this->sitemapGenerator
......
......@@ -3,7 +3,6 @@
namespace Drupal\simple_sitemap;
use XMLWriter;
use Drupal\simple_sitemap\Batch\Batch;
use Drupal\Core\Database\Connection;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\Language\LanguageManagerInterface;
......@@ -23,11 +22,6 @@ class SitemapGenerator {
const FIRST_CHUNK_INDEX = 1;
const XMLNS_IMAGE = 'http://www.google.com/schemas/sitemap-image/1.1';
/**
* @var \Drupal\simple_sitemap\Batch\Batch
*/
protected $batch;
/**
* @var \Drupal\simple_sitemap\EntityHelper
*/
......@@ -58,16 +52,6 @@ class SitemapGenerator {
*/
protected $time;
/**
* @var array
*/
protected $bundleSettings;
/**
* @var array
*/
protected $customLinks;
/**
* @var array
*/
......@@ -91,7 +75,6 @@ class SitemapGenerator {
/**
* SitemapGenerator constructor.
* @param \Drupal\simple_sitemap\Batch\Batch $batch
* @param \Drupal\simple_sitemap\EntityHelper $entityHelper
* @param \Drupal\Core\Database\Connection $database
* @param \Drupal\Core\Extension\ModuleHandler $module_handler
......@@ -99,14 +82,12 @@ class SitemapGenerator {
* @param \Drupal\Component\Datetime\Time $time
*/
public function __construct(
Batch $batch,
EntityHelper $entityHelper,
Connection $database,
ModuleHandler $module_handler,
LanguageManagerInterface $language_manager,
Time $time
) {
$this->batch = $batch;
$this->entityHelper = $entityHelper;
$this->db = $database;
$this->moduleHandler = $module_handler;
......@@ -126,24 +107,6 @@ class SitemapGenerator {
return $this->isHreflangSitemap;
}
/**
* @param array $bundle_settings
* @return $this
*/
public function setBundleSettings(array $bundle_settings) {
$this->bundleSettings = $bundle_settings;
return $this;
}
/**
* @param array $custom_links
* @return $this
*/
public function setCustomLinks(array $custom_links) {
$this->customLinks = $custom_links;
return $this;
}
/**
* @param array $settings
* @return $this
......@@ -153,77 +116,6 @@ class SitemapGenerator {
return $this;
}
/**
* Adds all operations to the batch and starts it.
*/
public function startGeneration() {
$this->batch->setBatchInfo($this->settings + ['entity_types' => $this->bundleSettings]);
// Add custom link generating operation.
$this->batch->addOperation('simple_sitemap.custom_url_generator', $this->getCustomUrlsData());
// Add entity link generating operations.
foreach ($this->getEntityTypeData() as $data) {
$this->batch->addOperation('simple_sitemap.entity_url_generator', $data);
}
// Add arbitrary links generating operation.
$arbitrary_links = [];
$this->moduleHandler->alter('simple_sitemap_arbitrary_links', $arbitrary_links);
if (!empty($arbitrary_links)) {
$this->batch->addOperation('simple_sitemap.arbitrary_url_generator', $arbitrary_links);
}
$this->batch->start();
}
/**
* Returns a batch-ready data array for custom link generation.
*
* @return array
* Data to be processed.
*/
protected function getCustomUrlsData() {
$paths = [];
foreach ($this->customLinks as $i => $custom_path) {
$paths[$i]['path'] = $custom_path['path'];
$paths[$i]['priority'] = isset($custom_path['priority']) ? $custom_path['priority'] : NULL;
$paths[$i]['changefreq'] = isset($custom_path['changefreq']) ? $custom_path['changefreq'] : NULL;
}
return $paths;
}
/**
* Collects entity metadata for entities that are set to be indexed
* and returns an array of batch-ready data sets for entity link generation.
*
* @return array
*/
protected function getEntityTypeData() {
$data_sets = [];
$sitemap_entity_types = $this->entityHelper->getSupportedEntityTypes();
foreach ($this->bundleSettings as $entity_type_name => $bundles) {
if (isset($sitemap_entity_types[$entity_type_name])) {
$keys = $sitemap_entity_types[$entity_type_name]->getKeys();
// Menu fix.
$keys['bundle'] = $entity_type_name == 'menu_link_content' ? 'menu_name' : $keys['bundle'];
foreach ($bundles as $bundle_name => $bundle_settings) {
if ($bundle_settings['index']) {
$data_sets[] = [
'bundle_settings' => $bundle_settings,
'bundle_name' => $bundle_name,
'entity_type_name' => $entity_type_name,
'keys' => $keys,
];
}
}
}
}
return $data_sets;
}
/**
* Wrapper method which takes links along with their options and then
* generates and saves the sitemap.
......
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