Commit 29d74c74 authored by gbyte.co's avatar gbyte.co

Issue #2763855 by temkin: Entity overrides are stored in configuration

parent dabe8752
......@@ -56,6 +56,7 @@ function simple_sitemap_schema() {
'type' => 'int',
'size' => 'small',
'not null' => TRUE,
'unsigned' => TRUE,
],
'sitemap_string' => [
'description' => 'XML sitemap chunk string.',
......@@ -68,6 +69,36 @@ function simple_sitemap_schema() {
'type' => 'int',
'default' => 0,
'not null' => TRUE,
'unsigned' => TRUE,
],
],
'primary key' => ['id'],
];
$schema['simple_sitemap_entity_overrides'] = [
'description' => 'Holds sitemap settings overridden by entities.',
'fields' => [
'id' => [
'description' => 'Override unique identifier.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'entity_type' => [
'description' => 'Entity type of the overriding entity.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
],
'entity_id' => [
'description' => 'ID of the overriding entity.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
],
'inclusion_settings' => [
'description' => 'Setting for the overriding entity.',
'type' => 'blob',
],
],
'primary key' => ['id'],
......@@ -106,3 +137,77 @@ function simple_sitemap_update_8201() {
\Drupal::service('config.factory')->getEditable('simple_sitemap.settings')
->set('entity_types', $entity_types)->save();
}
/**
* Moving entity overrides from configuration to database table.
*/
function simple_sitemap_update_8202() {
$database = \Drupal::database();
// Create database table.
if (!$database->schema()->tableExists('simple_sitemap_entity_overrides')) {
$database->schema()->createTable('simple_sitemap_entity_overrides', [
'description' => 'Holds sitemap settings overridden by entities.',
'fields' => [
'id' => [
'description' => 'Override unique identifier.',
'type' => 'serial',
'unsigned' => TRUE,
'not null' => TRUE,
],
'entity_type' => [
'description' => 'Entity type of the overriding entity.',
'type' => 'varchar',
'length' => 32,
'not null' => TRUE,
],
'entity_id' => [
'description' => 'ID of the overriding entity.',
'type' => 'int',
'unsigned' => TRUE,
'not null' => TRUE,
],
'inclusion_settings' => [
'description' => 'Setting for the overriding entity.',
'type' => 'blob',
],
],
'primary key' => ['id'],
]);
}
// Populate database table with config values.
$entity_types = \Drupal::config('simple_sitemap.settings')->get('entity_types');
$entity_types = is_array($entity_types) ? $entity_types : [];
foreach ($entity_types as $entity_type_name => &$entity_type) {
if (is_array($entity_type)) {
foreach($entity_type as $bundle_name => &$bundle) {
if (isset($bundle['entities'])) {
foreach($bundle['entities'] as $entity_id => $entity_settings) {
$database->insert('simple_sitemap_entity_overrides')
->fields([
'entity_type' => $entity_type_name,
'entity_id' => $entity_id,
'inclusion_settings' => serialize($entity_settings),
])
->execute();
}
// Remove entity overrides from configuration.
unset($bundle['entities']);
}
}
}
}
\Drupal::service('config.factory')->getEditable('simple_sitemap.settings')
->set('entity_types', $entity_types)->save();
}
/**
* Splitting simple_sitemap.settings configuration into simple_sitemap.settings,
* simple_sitemap.entity_types and simple_sitemap.custom.
*/
function simple_sitemap_update_8203() {
}
......@@ -7,12 +7,13 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help.
*/
function simple_sitemap_help($route_name, RouteMatchInterface $route_match) {
return $route_name === 'help.page.simple_sitemap' ?
check_markup(file_get_contents(dirname(__FILE__) . "/README.txt")) : NULL;
check_markup(file_get_contents(dirname(__FILE__) . "/README.md")) : NULL;
}
/**
......@@ -21,6 +22,7 @@ function simple_sitemap_help($route_name, RouteMatchInterface $route_match) {
* Adds sitemap settings to entity types that are supported via plugins.
*/
function simple_sitemap_form_alter(&$form, $form_state, $form_id) {
$f = \Drupal::service('simple_sitemap.form_helper')->processForm($form_state);
if (!$f->alteringForm) {
return;
......@@ -111,6 +113,7 @@ function simple_sitemap_cron() {
* Removes settings of the removed bundle.
*
* @todo Not working for menu bundles, as they are technically not bundles. Implement hook_menu_delete().
* @todo delete entity overrides
*/
function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) {
$generator = \Drupal::service('simple_sitemap.generator');
......@@ -132,14 +135,8 @@ function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) {
* Removes settings of the removed entity.
*/
function simple_sitemap_entity_delete(EntityInterface $entity) {
$generator = \Drupal::service('simple_sitemap.generator');
$entity_types = $generator->getConfig('entity_types');
$entity_type_id = $entity->getEntityTypeId();
$bundle_name = !empty($entity->bundle()) ? $entity->bundle() : $entity_type_id;
// Menu fix.
$bundle_name = $bundle_name == 'menu_link_content'&& method_exists($entity, 'getMenuName') ? $entity->getMenuName() : $bundle_name;
if (isset($entity_types[$entity_type_id][$bundle_name]['entities'][$entity->id()])) {
unset($entity_types[$entity_type_id][$bundle_name]['entities'][$entity->id()]);
$generator->saveConfig('entity_types', $entity_types);
}
\Drupal::database()->delete('simple_sitemap_entity_overrides')
->condition('entity_type', $entity->getEntityTypeId())
->condition('entity_id', $entity->id())
->execute();
}
......@@ -99,17 +99,11 @@ class BatchUrlGenerator {
foreach ($this->getBatchIterationEntities($entity_info) as $entity_id => $entity) {
$this->setCurrentId($entity_id);
$priority = NULL;
// Overriding entity settings if it has been overridden on entity edit page...
if (isset($this->batchInfo['entity_types'][$entity_info['entity_type_name']][$entity_info['bundle_name']]['entities'][$entity_id]['index'])) {
$entity_settings = $this->generator->getEntityInstanceSettings($entity_info['entity_type_name'], $entity_id);
// Skipping entity if it has been excluded on entity edit page.
if (!$this->batchInfo['entity_types'][$entity_info['entity_type_name']][$entity_info['bundle_name']]['entities'][$entity_id]['index']) {
continue;
}
// Otherwise overriding priority settings for this entity.
$priority = $this->batchInfo['entity_types'][$entity_info['entity_type_name']][$entity_info['bundle_name']]['entities'][$entity_id]['priority'];
if (empty($entity_settings['index'])) {
continue;
}
switch ($entity_info['entity_type_name']) {
......@@ -150,7 +144,7 @@ class BatchUrlGenerator {
'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($priority) ? $priority : (isset($entity_info['bundle_settings']['priority']) ? $entity_info['bundle_settings']['priority'] : NULL),
'priority' => $entity_settings['priority'],
];
$this->addUrlVariants($url_object, $path_data, $entity);
}
......
......@@ -189,7 +189,7 @@ class FormHelper {
'#options' => $this->getPrioritySelectValues(),
];
if ($this->entityCategory == 'instance' && isset($bundle_settings['priority'])) {
$form_fragment[$prefix . 'simple_sitemap_priority']['#options'][(string) $bundle_settings['priority']] .= ' (' . $this->t('Default') . ')';
$form_fragment[$prefix . 'simple_sitemap_priority']['#options'][$this->formatPriority($bundle_settings['priority'])] .= ' (' . $this->t('Default') . ')';
}
return $this;
}
......
......@@ -122,6 +122,10 @@ class Simplesitemap {
if (isset($entity_types[$entity_type_id])) {
unset($entity_types[$entity_type_id]);
$this->saveConfig('entity_types', $entity_types);
// todo: test
$this->db->delete('simple_sitemap_entity_overrides')
->condition('entity_type', $entity_type_id)
->execute();
}
return $this;
}
......@@ -141,13 +145,56 @@ class Simplesitemap {
* @return $this
*/
public function setBundleSettings($entity_type_id, $bundle_name = NULL, $settings) {
$bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
$entity_types = $this->getConfig('entity_types');
$this->addLinkSettings('entity', $settings, $entity_types[$entity_type_id][$bundle_name]);
$this->saveConfig('entity_types', $entity_types);
$results = $this->db->select('simple_sitemap_entity_overrides', 'o')
->fields('o', ['id', 'inclusion_settings'])
->condition('o.entity_type', $entity_type_id)
->execute()
->fetchAll();
// Delete entity overrides which are identical to new bundle setting.
foreach($results as $result) {
$delete = TRUE;
$instance_settings = unserialize($result->inclusion_settings);
foreach ($instance_settings as $key => $instance_setting) {
if ($instance_setting != $entity_types[$entity_type_id][$bundle_name][$key]) {
$delete = FALSE;
break;
}
}
if ($delete) {
$this->db->delete('simple_sitemap_entity_overrides')
->condition('id', $result->id)
->execute();
}
}
return $this;
}
/**
* Gets sitemap settings for an entity bundle or a non-bundle entity type.
*
* @param string $entity_type_id
* @param string|null $bundle_name
*
* @return array|false
*/
public function getBundleSettings($entity_type_id, $bundle_name = NULL) {
$bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
$entity_types = $this->getConfig('entity_types');
if (isset($entity_types[$entity_type_id][$bundle_name])) {
$settings = $entity_types[$entity_type_id][$bundle_name];
return $settings;
}
return FALSE;
}
/**
* Overrides entity bundle/entity type sitemap settings for a single entity.
*
......@@ -173,34 +220,56 @@ class Simplesitemap {
}
// Save overrides for this entity if something is different.
if ($override) {
$this->addLinkSettings('entity', $settings, $entity_types[$entity_type_id][$bundle_name]['entities'][$id]);
$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($settings),
])
->execute();
}
// Else unset override.
else {
unset($entity_types[$entity_type_id][$bundle_name]['entities'][$id]);
$this->db->delete('simple_sitemap_entity_overrides')
->condition('entity_type', $entity_type_id)
->condition('entity_id', $id)
->execute();
}
$this->saveConfig('entity_types', $entity_types);
}
else {
//todo: log error
}
return $this;
}
/**
* Gets sitemap settings for an entity bundle or a non-bundle entity type.
* Gets sitemap settings for an entity instance which overrides bundle
* settings.
*
* @param string $entity_type_id
* @param string|null $bundle_name
* @param int $id
*
* @return array|false
* @return array
*/
public function getBundleSettings($entity_type_id, $bundle_name = NULL) {
$bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
$entity_types = $this->getConfig('entity_types');
if (isset($entity_types[$entity_type_id][$bundle_name])) {
$settings = $entity_types[$entity_type_id][$bundle_name];
unset($settings['entities']);
return $settings;
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);
$bundle_name = $this->getEntityInstanceBundleName($entity);
return $this->getBundleSettings($entity_type_id, $bundle_name);
}
return FALSE;
}
/**
......@@ -229,27 +298,6 @@ class Simplesitemap {
return isset($entity_types[$entity_type_id]);
}
/**
* Gets sitemap settings for an entity instance which overrides bundle
* settings.
*
* @param string $entity_type_id
* @param int $id
*
* @return array
*/
public function getEntityInstanceSettings($entity_type_id, $id) {
$entity_types = $this->getConfig('entity_types');
$entity = $this->entityTypeManager->getStorage($entity_type_id)->load($id);
$bundle_name = $this->getEntityInstanceBundleName($entity);
if (isset($entity_types[$entity_type_id][$bundle_name]['entities'][$id])) {
return $entity_types[$entity_type_id][$bundle_name]['entities'][$id];
}
else {
return $this->getBundleSettings($entity_type_id, $bundle_name);
}
}
/**
* Adds a custom path to the sitemap settings.
*
......@@ -337,7 +385,7 @@ class Simplesitemap {
switch ($setting_key) {
case 'priority':
if (!FormHelper::isValidPriority($setting)) {
// todo: register error.
// todo: log error.
continue;
}
break;
......
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