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() { ...@@ -56,6 +56,7 @@ function simple_sitemap_schema() {
'type' => 'int', 'type' => 'int',
'size' => 'small', 'size' => 'small',
'not null' => TRUE, 'not null' => TRUE,
'unsigned' => TRUE,
], ],
'sitemap_string' => [ 'sitemap_string' => [
'description' => 'XML sitemap chunk string.', 'description' => 'XML sitemap chunk string.',
...@@ -68,6 +69,36 @@ function simple_sitemap_schema() { ...@@ -68,6 +69,36 @@ function simple_sitemap_schema() {
'type' => 'int', 'type' => 'int',
'default' => 0, 'default' => 0,
'not null' => TRUE, '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'], 'primary key' => ['id'],
...@@ -106,3 +137,77 @@ function simple_sitemap_update_8201() { ...@@ -106,3 +137,77 @@ function simple_sitemap_update_8201() {
\Drupal::service('config.factory')->getEditable('simple_sitemap.settings') \Drupal::service('config.factory')->getEditable('simple_sitemap.settings')
->set('entity_types', $entity_types)->save(); ->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 @@ ...@@ -7,12 +7,13 @@
use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Routing\RouteMatchInterface;
/** /**
* Implements hook_help. * Implements hook_help.
*/ */
function simple_sitemap_help($route_name, RouteMatchInterface $route_match) { function simple_sitemap_help($route_name, RouteMatchInterface $route_match) {
return $route_name === 'help.page.simple_sitemap' ? 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) { ...@@ -21,6 +22,7 @@ function simple_sitemap_help($route_name, RouteMatchInterface $route_match) {
* Adds sitemap settings to entity types that are supported via plugins. * Adds sitemap settings to entity types that are supported via plugins.
*/ */
function simple_sitemap_form_alter(&$form, $form_state, $form_id) { function simple_sitemap_form_alter(&$form, $form_state, $form_id) {
$f = \Drupal::service('simple_sitemap.form_helper')->processForm($form_state); $f = \Drupal::service('simple_sitemap.form_helper')->processForm($form_state);
if (!$f->alteringForm) { if (!$f->alteringForm) {
return; return;
...@@ -111,6 +113,7 @@ function simple_sitemap_cron() { ...@@ -111,6 +113,7 @@ function simple_sitemap_cron() {
* Removes settings of the removed bundle. * Removes settings of the removed bundle.
* *
* @todo Not working for menu bundles, as they are technically not bundles. Implement hook_menu_delete(). * @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) { function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) {
$generator = \Drupal::service('simple_sitemap.generator'); $generator = \Drupal::service('simple_sitemap.generator');
...@@ -132,14 +135,8 @@ function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) { ...@@ -132,14 +135,8 @@ function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) {
* Removes settings of the removed entity. * Removes settings of the removed entity.
*/ */
function simple_sitemap_entity_delete(EntityInterface $entity) { function simple_sitemap_entity_delete(EntityInterface $entity) {
$generator = \Drupal::service('simple_sitemap.generator'); \Drupal::database()->delete('simple_sitemap_entity_overrides')
$entity_types = $generator->getConfig('entity_types'); ->condition('entity_type', $entity->getEntityTypeId())
$entity_type_id = $entity->getEntityTypeId(); ->condition('entity_id', $entity->id())
$bundle_name = !empty($entity->bundle()) ? $entity->bundle() : $entity_type_id; ->execute();
// 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);
}
} }
...@@ -99,17 +99,11 @@ class BatchUrlGenerator { ...@@ -99,17 +99,11 @@ class BatchUrlGenerator {
foreach ($this->getBatchIterationEntities($entity_info) as $entity_id => $entity) { foreach ($this->getBatchIterationEntities($entity_info) as $entity_id => $entity) {
$this->setCurrentId($entity_id); $this->setCurrentId($entity_id);
$priority = NULL;
// Overriding entity settings if it has been overridden on entity edit page... $entity_settings = $this->generator->getEntityInstanceSettings($entity_info['entity_type_name'], $entity_id);
if (isset($this->batchInfo['entity_types'][$entity_info['entity_type_name']][$entity_info['bundle_name']]['entities'][$entity_id]['index'])) {
// Skipping entity if it has been excluded on entity edit page. if (empty($entity_settings['index'])) {
if (!$this->batchInfo['entity_types'][$entity_info['entity_type_name']][$entity_info['bundle_name']]['entities'][$entity_id]['index']) { continue;
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'];
} }
switch ($entity_info['entity_type_name']) { switch ($entity_info['entity_type_name']) {
...@@ -150,7 +144,7 @@ class BatchUrlGenerator { ...@@ -150,7 +144,7 @@ class BatchUrlGenerator {
'path' => $path, 'path' => $path,
'entity_info' => ['entity_type' => $entity_info['entity_type_name'], 'id' => $entity_id], 'entity_info' => ['entity_type' => $entity_info['entity_type_name'], 'id' => $entity_id],
'lastmod' => method_exists($entity, 'getChangedTime') ? date_iso8601($entity->getChangedTime()) : NULL, '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); $this->addUrlVariants($url_object, $path_data, $entity);
} }
......
...@@ -189,7 +189,7 @@ class FormHelper { ...@@ -189,7 +189,7 @@ class FormHelper {
'#options' => $this->getPrioritySelectValues(), '#options' => $this->getPrioritySelectValues(),
]; ];
if ($this->entityCategory == 'instance' && isset($bundle_settings['priority'])) { 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; return $this;
} }
......
...@@ -122,6 +122,10 @@ class Simplesitemap { ...@@ -122,6 +122,10 @@ class Simplesitemap {
if (isset($entity_types[$entity_type_id])) { if (isset($entity_types[$entity_type_id])) {
unset($entity_types[$entity_type_id]); unset($entity_types[$entity_type_id]);
$this->saveConfig('entity_types', $entity_types); $this->saveConfig('entity_types', $entity_types);
// todo: test
$this->db->delete('simple_sitemap_entity_overrides')
->condition('entity_type', $entity_type_id)
->execute();
} }
return $this; return $this;
} }
...@@ -141,13 +145,56 @@ class Simplesitemap { ...@@ -141,13 +145,56 @@ class Simplesitemap {
* @return $this * @return $this
*/ */
public function setBundleSettings($entity_type_id, $bundle_name = NULL, $settings) { public function setBundleSettings($entity_type_id, $bundle_name = NULL, $settings) {
$bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name; $bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name;
$entity_types = $this->getConfig('entity_types'); $entity_types = $this->getConfig('entity_types');
$this->addLinkSettings('entity', $settings, $entity_types[$entity_type_id][$bundle_name]); $this->addLinkSettings('entity', $settings, $entity_types[$entity_type_id][$bundle_name]);
$this->saveConfig('entity_types', $entity_types); $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; 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. * Overrides entity bundle/entity type sitemap settings for a single entity.
* *
...@@ -173,34 +220,56 @@ class Simplesitemap { ...@@ -173,34 +220,56 @@ class Simplesitemap {
} }
// Save overrides for this entity if something is different. // Save overrides for this entity if something is different.
if ($override) { 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 override.
else { 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; 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 $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) { public function getEntityInstanceSettings($entity_type_id, $id) {
$bundle_name = empty($bundle_name) ? $entity_type_id : $bundle_name; $results = $this->db->select('simple_sitemap_entity_overrides', 'o')
$entity_types = $this->getConfig('entity_types'); ->fields('o', ['inclusion_settings'])
if (isset($entity_types[$entity_type_id][$bundle_name])) { ->condition('o.entity_type', $entity_type_id)
$settings = $entity_types[$entity_type_id][$bundle_name]; ->condition('o.entity_id', $id)
unset($settings['entities']); ->execute()
return $settings; ->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 { ...@@ -229,27 +298,6 @@ class Simplesitemap {
return isset($entity_types[$entity_type_id]); 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. * Adds a custom path to the sitemap settings.
* *
...@@ -337,7 +385,7 @@ class Simplesitemap { ...@@ -337,7 +385,7 @@ class Simplesitemap {
switch ($setting_key) { switch ($setting_key) {
case 'priority': case 'priority':
if (!FormHelper::isValidPriority($setting)) { if (!FormHelper::isValidPriority($setting)) {
// todo: register error. // todo: log error.
continue; continue;
} }
break; 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