Commit 169f2f9e authored by gbyte.co's avatar gbyte.co

Refactor generators into own classes

parent 97c92cbd
......@@ -14,7 +14,7 @@ services:
simple_sitemap.sitemap_generator:
class: Drupal\simple_sitemap\SitemapGenerator
public: false
public: true
arguments:
- '@simple_sitemap.batch'
- '@simple_sitemap.entity_helper'
......@@ -40,8 +40,20 @@ services:
class: Drupal\simple_sitemap\Batch\Batch
public: false
simple_sitemap.batch_url_generator:
class: Drupal\simple_sitemap\Batch\BatchUrlGenerator
simple_sitemap.entity_url_generator:
class: Drupal\simple_sitemap\Batch\EntityUrlGenerator
public: true
arguments:
- '@simple_sitemap.generator'
- '@simple_sitemap.sitemap_generator'
- '@language_manager'
- '@entity_type.manager'
- '@path.validator'
- '@entity.query'
- '@simple_sitemap.logger'
simple_sitemap.custom_url_generator:
class: Drupal\simple_sitemap\Batch\CustomUrlGenerator
public: true
arguments:
- '@simple_sitemap.generator'
......@@ -54,7 +66,7 @@ services:
simple_sitemap.logger:
class: Drupal\simple_sitemap\Logger
public: false
public: true
arguments:
- '@logger.channel.simple_sitemap'
- '@current_user'
......
......@@ -3,9 +3,14 @@
namespace Drupal\simple_sitemap\Batch;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\Cache\Cache;
/**
* Class Batch
* @package Drupal\simple_sitemap\Batch
*
* The services of this class are not injected, as this class looses its state
* on every method call because of how the batch APi works.
*/
class Batch {
......@@ -25,6 +30,8 @@ class Batch {
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 for all languages.";
const REGENERATION_FINISHED_ERROR_MESSAGE = 'The sitemap generation finished with an error.';
/**
* Batch constructor.
......@@ -113,10 +120,10 @@ class Batch {
* @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
*/
public static function generateBundleUrls(array $entity_info, array $batch_info, &$context) {
\Drupal::service('simple_sitemap.batch_url_generator')
\Drupal::service('simple_sitemap.entity_url_generator')
->setContext($context)
->setBatchInfo($batch_info)
->generateBundleUrls($entity_info);
->generate($entity_info);
}
/**
......@@ -129,10 +136,10 @@ class Batch {
* @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
*/
public static function generateCustomUrls(array $custom_paths, array $batch_info, &$context) {
\Drupal::service('simple_sitemap.batch_url_generator')
\Drupal::service('simple_sitemap.custom_url_generator')
->setContext($context)
->setBatchInfo($batch_info)
->generateCustomUrls($custom_paths);
->generate($custom_paths);
}
/**
......@@ -145,8 +152,24 @@ class Batch {
* @see https://api.drupal.org/api/drupal/core!includes!form.inc/group/batch/8
*/
public static function finishGeneration($success, $results, $operations) {
\Drupal::service('simple_sitemap.batch_url_generator')
->finishGeneration($success, $results, $operations);
if ($success) {
$remove_sitemap = empty($results['chunk_count']);
if (!empty($results['generate']) || $remove_sitemap) {
\Drupal::service('simple_sitemap.sitemap_generator')
->generateSitemap($results['generate'], $remove_sitemap);
}
Cache::invalidateTags(['simple_sitemap']);
\Drupal::service('simple_sitemap.logger')->m(self::REGENERATION_FINISHED_MESSAGE,
['@url' => $GLOBALS['base_url'] . '/sitemap.xml'])
// ['@url' => $this->sitemapGenerator->getCustomBaseUrl() . '/sitemap.xml']) //todo: Use actual base URL for message.
->display('status')
->log('info');
}
else {
\Drupal::service('simple_sitemap.logger')->m(self::REGENERATION_FINISHED_ERROR_MESSAGE)
->display('error', 'administer sitemap settings')
->log('error');
}
}
}
<?php
namespace Drupal\simple_sitemap\Batch;
use Drupal\Core\Url;
/**
* Class BatchUrlGenerator
* @package Drupal\simple_sitemap\Batch
*/
class CustomUrlGenerator extends UrlGeneratorBase implements UrlGeneratorInterface {
const PATH_DOES_NOT_EXIST_OR_NO_ACCESS_MESSAGE = "The custom path @path has been omitted from the XML sitemap as it either does not exist, or it is not accessible to anonymous users. You can review custom paths <a href='@custom_paths_url'>here</a>.";
/**
* Batch function which generates urls to custom paths.
*
* @param mixed $custom_paths
*/
public function generate($custom_paths) {
foreach ($this->getBatchIterationCustomPaths($custom_paths) as $i => $custom_path) {
$this->setCurrentId($i);
// todo: Change to different function, as this also checks if current user has access. The user however varies depending if process was started from the web interface or via cron/drush. Use getUrlIfValidWithoutAccessCheck()?
if (!$this->pathValidator->isValid($custom_path['path'])) {
// if (!(bool) $this->pathValidator->getUrlIfValidWithoutAccessCheck($custom_path['path'])) {
$this->logger->m(self::PATH_DOES_NOT_EXIST_OR_NO_ACCESS_MESSAGE,
['@path' => $custom_path['path'], '@custom_paths_url' => $GLOBALS['base_url'] . '/admin/config/search/simplesitemap/custom'])
->display('warning', 'administer sitemap settings')
->log('warning');
continue;
}
$url_object = Url::fromUserInput($custom_path['path'], ['absolute' => TRUE]);
$path = $url_object->getInternalPath();
if ($this->batchInfo['remove_duplicates'] && $this->pathProcessed($path)) {
continue;
}
$entity = $this->getEntityFromUrlObject($url_object);
$path_data = [
'path' => $path,
'lastmod' => method_exists($entity, 'getChangedTime') ? date_iso8601($entity->getChangedTime()) : NULL,
'priority' => isset($custom_path['priority']) ? $custom_path['priority'] : NULL,
];
if (NULL !== $entity) {
$path_data['entity_info'] = ['entity_type' => $entity->getEntityTypeId(), 'id' => $entity->id()];
}
$this->addUrlVariants($url_object, $path_data, $entity);
}
$this->processSegment();
}
/**
* @param array $custom_paths
* @return array
*/
protected function getBatchIterationCustomPaths(array $custom_paths) {
if ($this->needsInitialization()) {
$this->initializeBatch(count($custom_paths));
}
if ($this->isBatch()) {
$custom_paths = array_slice($custom_paths, $this->context['sandbox']['progress'], $this->batchInfo['batch_process_limit']);
}
return $custom_paths;
}
/**
* @param $url_object
* @return object|null
*/
protected function getEntityFromUrlObject(Url $url_object) {
$route_parameters = $url_object->getRouteParameters();
return !empty($route_parameters) && $this->entityTypeManager
->getDefinition($entity_type_id = key($route_parameters), FALSE)
? $this->entityTypeManager->getStorage($entity_type_id)
->load($route_parameters[$entity_type_id])
: NULL;
}
}
<?php
namespace Drupal\simple_sitemap\Batch;
/**
* Class BatchUrlGenerator
* @package Drupal\simple_sitemap\Batch
*/
class EntityUrlGenerator extends UrlGeneratorBase implements UrlGeneratorInterface {
/**
* Batch callback function which generates urls to entity paths.
*
* @param mixed $entity_info
*/
public function generate($entity_info) {
foreach ($this->getBatchIterationEntities($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' => $entity_settings['priority'],
];
$this->addUrlVariants($url_object, $path_data, $entity);
}
$this->processSegment();
}
/**
* @param array $entity_info
* @return \Drupal\Core\Entity\EntityInterface[]
*/
protected function getBatchIterationEntities(array $entity_info) {
$query = $this->entityQuery->get($entity_info['entity_type_name']);
if (!empty($entity_info['keys']['id'])) {
$query->sort($entity_info['keys']['id'], 'ASC');
}
if (!empty($entity_info['keys']['bundle'])) {
$query->condition($entity_info['keys']['bundle'], $entity_info['bundle_name']);
}
if (!empty($entity_info['keys']['status'])) {
$query->condition($entity_info['keys']['status'], 1);
}
if ($this->needsInitialization()) {
$count_query = clone $query;
$this->initializeBatch($count_query->count()->execute());
}
if ($this->isBatch()) {
$query->range($this->context['sandbox']['progress'], $this->batchInfo['batch_process_limit']);
}
return $this->entityTypeManager
->getStorage($entity_info['entity_type_name'])
->loadMultiple($query->execute());
}
}
<?php
namespace Drupal\simple_sitemap\Batch;
/**
* Interface UrlGeneratorInterface
* @package Drupal\simple_sitemap\Batch
*/
interface UrlGeneratorInterface {
/**
* @param mixed $data
*/
public function generate($data);
}
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