View source
<?php
namespace Drupal\simple_sitemap;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Path\PathValidator;
use Drupal\Core\Config\ConfigFactory;
use Drupal\Core\Datetime\DateFormatter;
use Drupal\Component\Datetime\Time;
use Drupal\simple_sitemap\Plugin\simple_sitemap\UrlGenerator\UrlGeneratorManager;
class Simplesitemap {
protected $sitemapGenerator;
protected $entityHelper;
protected $configFactory;
protected $db;
protected $entityTypeManager;
protected $pathValidator;
protected $dateFormatter;
protected $time;
protected $batch;
protected $moduleHandler;
protected $urlGeneratorManager;
protected static $allowedLinkSettings = [
'entity' => [
'index',
'priority',
'changefreq',
'include_images',
],
'custom' => [
'priority',
'changefreq',
],
];
protected static $linkSettingDefaults = [
'index' => 1,
'priority' => 0.5,
'changefreq' => '',
'include_images' => 0,
];
public function __construct(SitemapGenerator $sitemapGenerator, EntityHelper $entityHelper, ConfigFactory $configFactory, Connection $database, EntityTypeManagerInterface $entityTypeManager, PathValidator $pathValidator, DateFormatter $dateFormatter, Time $time, Batch $batch, UrlGeneratorManager $urlGeneratorManager) {
$this->sitemapGenerator = $sitemapGenerator;
$this->entityHelper = $entityHelper;
$this->configFactory = $configFactory;
$this->db = $database;
$this->entityTypeManager = $entityTypeManager;
$this->pathValidator = $pathValidator;
$this->dateFormatter = $dateFormatter;
$this->time = $time;
$this->batch = $batch;
$this->urlGeneratorManager = $urlGeneratorManager;
}
public function getSetting($name, $default = FALSE) {
$setting = $this->configFactory
->get('simple_sitemap.settings')
->get($name);
return NULL !== $setting ? $setting : $default;
}
public function saveSetting($name, $setting) {
$this->configFactory
->getEditable('simple_sitemap.settings')
->set($name, $setting)
->save();
return $this;
}
public function getSitemap($chunk_id = NULL) {
$chunk_info = $this
->fetchSitemapChunkInfo();
if (NULL === $chunk_id || !isset($chunk_info[$chunk_id])) {
if (count($chunk_info) > 1) {
return $this
->getSitemapIndex($chunk_info);
}
else {
return count($chunk_info) === 1 && isset($chunk_info[SitemapGenerator::FIRST_CHUNK_INDEX]) ? $this
->fetchSitemapChunk(SitemapGenerator::FIRST_CHUNK_INDEX)->sitemap_string : FALSE;
}
}
else {
return $this
->fetchSitemapChunk($chunk_id)->sitemap_string;
}
}
protected function fetchSitemapChunkInfo() {
return $this->db
->query('SELECT id, sitemap_created FROM {simple_sitemap}')
->fetchAllAssoc('id');
}
protected function fetchSitemapChunk($id) {
return $this->db
->query('SELECT * FROM {simple_sitemap} WHERE id = :id', [
':id' => $id,
])
->fetchObject();
}
public function generateSitemap($from = 'form') {
$this->batch
->setBatchSettings([
'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,
]);
$plugins = $this->urlGeneratorManager
->getDefinitions();
usort($plugins, function ($a, $b) {
return $a['weight'] - $b['weight'];
});
foreach ($plugins as $plugin) {
if ($plugin['enabled']) {
if (!empty($plugin['settings']['instantiate_for_each_data_set'])) {
foreach ($this->urlGeneratorManager
->createInstance($plugin['id'])
->getDataSets() as $data_sets) {
$this->batch
->addOperation($plugin['id'], $data_sets);
}
}
else {
$this->batch
->addOperation($plugin['id']);
}
}
}
$success = $this->batch
->start();
return $from === 'nobatch' ? $this : $success;
}
protected function getSitemapIndex($chunk_info) {
return $this->sitemapGenerator
->setSettings([
'base_url' => $this
->getSetting('base_url', ''),
])
->generateSitemapIndex($chunk_info);
}
public function getGeneratedAgo() {
$chunks = $this
->fetchSitemapChunkInfo();
if (isset($chunks[SitemapGenerator::FIRST_CHUNK_INDEX]->sitemap_created)) {
return $this->dateFormatter
->formatInterval($this->time
->getRequestTime() - $chunks[SitemapGenerator::FIRST_CHUNK_INDEX]->sitemap_created);
}
return FALSE;
}
public function enableEntityType($entity_type_id) {
$enabled_entity_types = $this
->getSetting('enabled_entity_types');
if (!in_array($entity_type_id, $enabled_entity_types)) {
$enabled_entity_types[] = $entity_type_id;
$this
->saveSetting('enabled_entity_types', $enabled_entity_types);
}
return $this;
}
public function disableEntityType($entity_type_id) {
$enabled_entity_types = $this
->getSetting('enabled_entity_types');
if (FALSE !== ($key = array_search($entity_type_id, $enabled_entity_types))) {
unset($enabled_entity_types[$key]);
$this
->saveSetting('enabled_entity_types', array_values($enabled_entity_types));
}
$config_names = $this->configFactory
->listAll("simple_sitemap.bundle_settings.{$entity_type_id}.");
foreach ($config_names as $config_name) {
$this->configFactory
->getEditable($config_name)
->delete();
}
$this
->removeEntityInstanceSettings($entity_type_id);
return $this;
}
public function setBundleSettings($entity_type_id, $bundle_name = NULL, $settings = []) {
$bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
if (!empty($old_settings = $this
->getBundleSettings($entity_type_id, $bundle_name))) {
$settings = array_merge($old_settings, $settings);
}
else {
self::supplementDefaultSettings('entity', $settings);
}
$bundle_settings = $this->configFactory
->getEditable("simple_sitemap.bundle_settings.{$entity_type_id}.{$bundle_name}");
foreach ($settings as $setting_key => $setting) {
if ($setting_key === 'index') {
$setting = intval($setting);
}
$bundle_settings
->set($setting_key, $setting);
}
$bundle_settings
->save();
$sitemap_entity_types = $this->entityHelper
->getSupportedEntityTypes();
if (isset($sitemap_entity_types[$entity_type_id])) {
$entity_type = $sitemap_entity_types[$entity_type_id];
$keys = $entity_type
->getKeys();
$keys['bundle'] = $entity_type_id === 'menu_link_content' ? 'menu_name' : $keys['bundle'];
$query = $this->entityTypeManager
->getStorage($entity_type_id)
->getQuery();
if (!$this->entityHelper
->entityTypeIsAtomic($entity_type_id)) {
$query
->condition($keys['bundle'], $bundle_name);
}
$entity_ids = $query
->execute();
$query = $this->db
->select('simple_sitemap_entity_overrides', 'o')
->fields('o', [
'id',
'inclusion_settings',
])
->condition('o.entity_type', $entity_type_id);
if (!empty($entity_ids)) {
$query
->condition('o.entity_id', $entity_ids, 'IN');
}
$delete_instances = [];
foreach ($query
->execute()
->fetchAll() as $result) {
$delete = TRUE;
$instance_settings = unserialize($result->inclusion_settings);
foreach ($instance_settings as $setting_key => $instance_setting) {
if ($instance_setting != $settings[$setting_key]) {
$delete = FALSE;
break;
}
}
if ($delete) {
$delete_instances[] = $result->id;
}
}
if (!empty($delete_instances)) {
$this->db
->delete('simple_sitemap_entity_overrides')
->condition('id', $delete_instances, 'IN')
->execute();
}
}
else {
}
return $this;
}
public function getBundleSettings($entity_type_id = NULL, $bundle_name = NULL) {
if (NULL !== $entity_type_id) {
$bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
$bundle_settings = $this->configFactory
->get("simple_sitemap.bundle_settings.{$entity_type_id}.{$bundle_name}")
->get();
return !empty($bundle_settings) ? $bundle_settings : FALSE;
}
else {
$config_names = $this->configFactory
->listAll('simple_sitemap.bundle_settings.');
$all_settings = [];
foreach ($config_names as $config_name) {
$config_name_parts = explode('.', $config_name);
$all_settings[$config_name_parts[2]][$config_name_parts[3]] = $this->configFactory
->get($config_name)
->get();
}
return $all_settings;
}
}
public static function supplementDefaultSettings($type, &$settings, $overrides = []) {
foreach (self::$allowedLinkSettings[$type] as $allowed_link_setting) {
if (!isset($settings[$allowed_link_setting]) && isset(self::$linkSettingDefaults[$allowed_link_setting])) {
$settings[$allowed_link_setting] = isset($overrides[$allowed_link_setting]) ? $overrides[$allowed_link_setting] : self::$linkSettingDefaults[$allowed_link_setting];
}
}
}
public function setEntityInstanceSettings($entity_type_id, $id, $settings) {
$entity = $this->entityTypeManager
->getStorage($entity_type_id)
->load($id);
$bundle_settings = $this
->getBundleSettings($entity_type_id, $this->entityHelper
->getEntityInstanceBundleName($entity));
if (!empty($bundle_settings)) {
$override = FALSE;
foreach ($settings as $key => $setting) {
if (!isset($bundle_settings[$key]) || $setting != $bundle_settings[$key]) {
$override = TRUE;
break;
}
}
if ($override) {
$this->db
->merge('simple_sitemap_entity_overrides')
->key([
'entity_type' => $entity_type_id,
'entity_id' => $id,
])
->fields([
'entity_type' => $entity_type_id,
'entity_id' => $id,
'inclusion_settings' => serialize(array_merge($bundle_settings, $settings)),
])
->execute();
}
else {
$this
->removeEntityInstanceSettings($entity_type_id, $id);
}
}
else {
}
return $this;
}
public function getEntityInstanceSettings($entity_type_id, $id) {
$results = $this->db
->select('simple_sitemap_entity_overrides', 'o')
->fields('o', [
'inclusion_settings',
])
->condition('o.entity_type', $entity_type_id)
->condition('o.entity_id', $id)
->execute()
->fetchField();
if (!empty($results)) {
return unserialize($results);
}
else {
$entity = $this->entityTypeManager
->getStorage($entity_type_id)
->load($id);
return $this
->getBundleSettings($entity_type_id, $this->entityHelper
->getEntityInstanceBundleName($entity));
}
}
public function removeEntityInstanceSettings($entity_type_id, $entity_ids = NULL) {
$query = $this->db
->delete('simple_sitemap_entity_overrides')
->condition('entity_type', $entity_type_id);
if (NULL !== $entity_ids) {
$entity_ids = !is_array($entity_ids) ? [
$entity_ids,
] : $entity_ids;
$query
->condition('entity_id', $entity_ids, 'IN');
}
$query
->execute();
return $this;
}
public function bundleIsIndexed($entity_type_id, $bundle_name = NULL) {
$settings = $this
->getBundleSettings($entity_type_id, $bundle_name);
return !empty($settings['index']);
}
public function entityTypeIsEnabled($entity_type_id) {
return in_array($entity_type_id, $this
->getSetting('enabled_entity_types', []));
}
public function addCustomLink($path, $settings = []) {
if (!$this->pathValidator
->isValid($path)) {
return $this;
}
if ($path[0] !== '/') {
return $this;
}
$custom_links = $this
->getCustomLinks(FALSE);
foreach ($custom_links as $key => $link) {
if ($link['path'] === $path) {
$link_key = $key;
break;
}
}
$link_key = isset($link_key) ? $link_key : count($custom_links);
$custom_links[$link_key] = [
'path' => $path,
] + $settings;
$this->configFactory
->getEditable('simple_sitemap.custom')
->set('links', $custom_links)
->save();
return $this;
}
public function getCustomLinks($supplement_default_settings = TRUE) {
$custom_links = $this->configFactory
->get('simple_sitemap.custom')
->get('links');
if ($supplement_default_settings) {
foreach ($custom_links as $i => $link_settings) {
self::supplementDefaultSettings('custom', $link_settings);
$custom_links[$i] = $link_settings;
}
}
return $custom_links !== NULL ? $custom_links : [];
}
public function getCustomLink($path) {
foreach ($this
->getCustomLinks() as $key => $link) {
if ($link['path'] === $path) {
return $link;
}
}
return FALSE;
}
public function removeCustomLink($path) {
$custom_links = $this
->getCustomLinks(FALSE);
foreach ($custom_links as $key => $link) {
if ($link['path'] === $path) {
unset($custom_links[$key]);
$custom_links = array_values($custom_links);
$this->configFactory
->getEditable('simple_sitemap.custom')
->set('links', $custom_links)
->save();
break;
}
}
return $this;
}
public function removeCustomLinks() {
$this->configFactory
->getEditable('simple_sitemap.custom')
->set('links', [])
->save();
return $this;
}
}