Commit 6cb333e4 authored by gbyte.co's avatar gbyte.co

Add some API for altering simple_sitemap settings programmatically instead of...

Add some API for altering simple_sitemap settings programmatically instead of fiddling with the configuration object
parent fd938414
......@@ -72,36 +72,19 @@ function simple_sitemap_entity_form_submit($form, &$form_state) {
$sitemap = \Drupal::service('simple_sitemap.generator');
$f = $form['simple_sitemap']['#simple_sitemap'];
// Get current entity type sitemap settings.
$entity_types = $sitemap->getConfig('entity_types');
switch ($f->entityCategory) {
case 'custom':
case 'bundle':
$f->bundleName = !empty($f->bundleName) ? $f->bundleName : Form::getNewEntityId($form_state);
$entity_types[$f->entityTypeId][$f->bundleName]['index'] = $values['simple_sitemap_index_content'];
$entity_types[$f->entityTypeId][$f->bundleName]['priority'] = $values['simple_sitemap_priority'];
$sitemap->setBundleSettings($f->entityTypeId, $f->bundleName, ['index' => $values['simple_sitemap_index_content'], 'priority' => $values['simple_sitemap_priority']]);
break;
case 'instance':
$f->instanceId = !empty($f->instanceId) ? $f->instanceId : Form::getNewEntityId($form_state);
// Delete overrides if they are identical to bundle settings.
if ($values['simple_sitemap_index_content'] == $entity_types[$f->entityTypeId][$f->bundleName]['index']
&& $values['simple_sitemap_priority'] == $entity_types[$f->entityTypeId][$f->bundleName]['priority']) {
unset($entity_types[$f->entityTypeId][$f->bundleName]['entities'][$f->instanceId]);
}
else { // Else save overrides for this entity.
$entity_types[$f->entityTypeId][$f->bundleName]['entities'][$f->instanceId]['index'] = $values['simple_sitemap_index_content'];
$entity_types[$f->entityTypeId][$f->bundleName]['entities'][$f->instanceId]['priority'] = $values['simple_sitemap_priority'];
}
$sitemap->setEntityInstanceSettings($f->entityTypeId, $f->instanceId, ['index' => $values['simple_sitemap_index_content'], 'priority' => $values['simple_sitemap_priority']]);
break;
}
// Save new entity type settings.
$sitemap->saveConfig('entity_types', $entity_types);
// Regenerate sitemaps according to user setting.
if ($values['simple_sitemap_regenerate_now']) {
$sitemap->generateSitemap();
......
......@@ -47,18 +47,17 @@ class Form {
if (!is_null($this->formState))
$this->getEntityDataFromFormEntity();
$entity_types = $this->sitemap->getConfig('entity_types');
// Do not alter the form if it is irrelevant to sitemap generation.
if (empty($this->entityCategory))
$this->alteringForm = FALSE;
// Do not alter the form if entity is not enabled in sitemap settings.
elseif (!isset($entity_types[$this->entityTypeId]))
$this->alteringForm = FALSE;
elseif (!$this->sitemap->entityTypeIsEnabled($this->entityTypeId))
$this->alteringForm = FALSE;
// Do not alter the form, if sitemap is disabled for the entity type of this entity instance.
elseif ($this->entityCategory == 'instance' && empty($entity_types[$this->entityTypeId][$this->bundleName]['index']))
elseif ($this->entityCategory == 'instance'
&& !$this->sitemap->bundleIsIndexed($this->entityTypeId, $this->bundleName))
$this->alteringForm = FALSE;
}
......@@ -93,24 +92,15 @@ class Form {
public function displayEntitySitemapSettings(&$form_fragment, $multiple = FALSE) {
$prefix = $multiple ? $this->entityTypeId . '_' : '';
// Setting default form values.
$index = 0;
$priority = self::PRIORITY_DEFAULT;
$entity_types = $this->sitemap->getConfig('entity_types');
// Overwriting defaults if settings found for bundle.
if (isset($entity_types[$this->entityTypeId][$this->bundleName]['index']))
$bundle_index = $index = $entity_types[$this->entityTypeId][$this->bundleName]['index'];
if (isset($entity_types[$this->entityTypeId][$this->bundleName]['priority']))
$bundle_priority = $priority = $entity_types[$this->entityTypeId][$this->bundleName]['priority'];
// Overwriting defaults if settings found for this entity instance.
if ($this->entityCategory == 'instance') {
if (isset($entity_types[$this->entityTypeId][$this->bundleName]['entities'][$this->instanceId]['index']))
$index = $entity_types[$this->entityTypeId][$this->bundleName]['entities'][$this->instanceId]['index'];
if (isset($entity_types[$this->entityTypeId][$this->bundleName]['entities'][$this->instanceId]['priority']))
$priority = $entity_types[$this->entityTypeId][$this->bundleName]['entities'][$this->instanceId]['priority'];
$settings = $this->sitemap->getEntityInstanceSettings($this->entityTypeId, $this->instanceId);
$bundle_settings = $this->sitemap->getBundleSettings($this->entityTypeId, $this->bundleName);
}
else {
$settings = $this->sitemap->getBundleSettings($this->entityTypeId, $this->bundleName);
}
$index = isset($settings['index']) ? $settings['index'] : 0;
$priority = isset($settings['priority']) ? $settings['priority'] : self::PRIORITY_DEFAULT;
if (!$multiple) {
$form_fragment[$prefix . 'simple_sitemap_index_content'] = [
......@@ -121,8 +111,8 @@ class Form {
1 => $this->entityCategory == 'instance' ? t('Index this entity') : t('Index entities of this type'),
]
];
if ($this->entityCategory == 'instance' && isset($bundle_index)) {
$form_fragment[$prefix . 'simple_sitemap_index_content']['#options'][$bundle_index] .= ' <em>(' . t('Default') . ')</em>';
if ($this->entityCategory == 'instance' && isset($bundle_settings['index'])) {
$form_fragment[$prefix . 'simple_sitemap_index_content']['#options'][$bundle_settings['index']] .= ' <em>(' . t('Default') . ')</em>';
}
}
......@@ -142,8 +132,8 @@ class Form {
'#default_value' => $priority,
'#options' => self::getPrioritySelectValues(),
];
if ($this->entityCategory == 'instance' && isset($bundle_priority)) {
$form_fragment[$prefix . 'simple_sitemap_priority']['#options'][(string)$bundle_priority] .= ' (' . t('Default') . ')';
if ($this->entityCategory == 'instance' && isset($bundle_settings['priority'])) {
$form_fragment[$prefix . 'simple_sitemap_priority']['#options'][(string)$bundle_settings['priority']] .= ' (' . t('Default') . ')';
}
}
......@@ -159,7 +149,6 @@ class Form {
if ($form_entity !== FALSE) {
$entity_type_id = $form_entity->getEntityTypeId();
$sitemap_entity_types = Simplesitemap::getSitemapEntityTypes();
$entity_bundle = $form_entity->bundle();
if (isset($sitemap_entity_types[$entity_type_id])) {
$this->entityCategory = 'instance';
}
......@@ -173,21 +162,18 @@ class Form {
}
// Menu fix.
if (is_null($this->entityCategory) && $entity_type_id == 'menu') {
$this->entityCategory = 'bundle';
$entity_type_id = 'menu_link_content';
}
$this->entityCategory = is_null($this->entityCategory) && $entity_type_id == 'menu' ? 'bundle' : $this->entityCategory;
switch ($this->entityCategory) {
case 'bundle':
$this->entityTypeId = $entity_type_id == 'menu_link_content' ? $entity_type_id : $form_entity->getEntityType()->getBundleOf(); // Menu fix.
$this->entityTypeId = Simplesitemap::getBundleEntityTypeId($form_entity);
$this->bundleName = $form_entity->id();
$this->instanceId = NULL;
break;
case 'instance':
$this->entityTypeId = $entity_type_id;
$this->bundleName = $entity_bundle == 'menu_link_content' && method_exists($form_entity, 'getMenuName') ? $form_entity->getMenuName() : $entity_bundle; // Menu fix.
$this->bundleName = Simplesitemap::getEntityInstanceBundleName($form_entity);
$this->instanceId = $form_entity->id();
break;
......
......@@ -41,11 +41,11 @@ class SimplesitemapEntitiesForm extends ConfigFormBase {
$form['simple_sitemap_entities']['entities'] = array(
'#title' => t('Sitemap entities'),
'#type' => 'fieldset',
'#markup' => '<p>' . t("Simple XML sitemap settings will be added only to entity forms of entity types enabled here. For all entity types featuring bundles (e.g. <em>node</em>) inclusion settings have to be set on their bundle pages (e.g. <em>page</em>). Disabling an entity type on this page will delete its sitemap settings including per-entity overrides.") . '</p>',
'#markup' => '<p>' . t("Simple XML sitemap settings will be added only to entity forms of entity types enabled here. For all entity types featuring bundles (e.g. <em>node</em>) sitemap settings have to be set on their bundle pages (e.g. <em>page</em>).") . '</p>',
);
$form['#attached']['library'][] = 'simple_sitemap/sitemapEntities';
$form['#attached']['drupalSettings']['simple_sitemap'] = ['entities' => [], 'atomic_entities' => []];
$form['#attached']['drupalSettings']['simple_sitemap'] = ['all_entities' => [], 'atomic_entities' => []];
$entity_type_labels = [];
foreach (Simplesitemap::getSitemapEntityTypes() as $entity_type_id => $entity_type) {
......@@ -53,21 +53,19 @@ class SimplesitemapEntitiesForm extends ConfigFormBase {
}
asort($entity_type_labels);
$entity_types = $sitemap->getConfig('entity_types');
$f = new Form();
foreach ($entity_type_labels as $entity_type_id => $entity_type_label) {
$entity_type_enabled = isset($entity_types[$entity_type_id]);
$form['simple_sitemap_entities']['entities'][$entity_type_id] = [
'#type' => 'details',
'#title' => $entity_type_label,
'#open' => $entity_type_enabled,
'#open' => $sitemap->entityTypeIsEnabled($entity_type_id),
];
$form['simple_sitemap_entities']['entities'][$entity_type_id][$entity_type_id . '_enabled'] = [
'#type' => 'checkbox',
'#title' => t('Enable @entity_type_label <em>(@entity_type_id)</em> support', array('@entity_type_label' => strtolower($entity_type_label), '@entity_type_id' => $entity_type_id)),
'#description' => t('Sitemap settings for this entity type can be set on its bundle pages and overridden on its entity pages.'),
'#default_value' => $entity_type_enabled,
'#default_value' => $sitemap->entityTypeIsEnabled($entity_type_id),
];
$form['#attached']['drupalSettings']['simple_sitemap']['all_entities'][] = str_replace('_', '-', $entity_type_id);
if (Simplesitemap::entityTypeIsAtomic($entity_type_id)) {
......@@ -88,26 +86,23 @@ class SimplesitemapEntitiesForm extends ConfigFormBase {
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$sitemap = \Drupal::service('simple_sitemap.generator');
$entity_types = $sitemap->getConfig('entity_types');
$values = $form_state->getValues();
foreach($values as $field_name => $value) {
if (substr($field_name, -strlen('_enabled')) == '_enabled') {
$entity_type_id = substr($field_name, 0, -8);
if ($value) {
if (empty($entity_types[$entity_type_id])) {
if (Simplesitemap::entityTypeIsAtomic($entity_type_id))
// As entity type has no bundles, making it index by default with set priority.
$entity_types[$entity_type_id][$entity_type_id] = ['index' => 1, 'priority' => $values[$entity_type_id . '_simple_sitemap_priority']];
else // As entity has bundles, enabling settings on its bundle pages.
$entity_types[$entity_type_id] = [];
$sitemap->enableEntityType($entity_type_id);
if (Simplesitemap::entityTypeIsAtomic($entity_type_id)) {
$sitemap->setBundleSettings($entity_type_id, $entity_type_id, [
'index' => TRUE,
'priority' => $values[$entity_type_id . '_simple_sitemap_priority']
]);
}
}
else {
unset($entity_types[$entity_type_id]);
}
else
$sitemap->disableEntityType($entity_type_id);
}
}
$sitemap->saveConfig('entity_types', $entity_types);
parent::submitForm($form, $form_state);
// Regenerate sitemaps according to user setting.
......
......@@ -8,6 +8,7 @@ namespace Drupal\simple_sitemap;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\ContentEntityTypeInterface;
use Drupal\simple_sitemap\Form;
/**
* Simplesitemap class.
......@@ -55,6 +56,140 @@ class Simplesitemap {
->set($key, $value)->save();
}
/**
* Enables sitemap support for an entity type. Enabled entity types show
* sitemap settings on their bundles. If an enabled entity type does not
* featured bundles (e.g. 'user'), it needs to be set up with
* setBundleSettings() as well.
*
* @param string $entity_type_id
* Entity type id like 'node'.
*
* @return bool
* TRUE if entity type has been enabled, FALSE if it was not.
*/
public function enableEntityType($entity_type_id) {
$entity_types = $this->getConfig('entity_types');
if (empty($entity_types[$entity_type_id])) {
$entity_types[$entity_type_id] = [];
$this->saveConfig('entity_types', $entity_types);
return TRUE;
}
return FALSE;
}
/**
* Disables sitemap support for an entity type. Disabling support for an
* entity type deletes its sitemap settings permanently and removes sitemap
* settings from entity forms.
*
* @param string $entity_type_id
* Entity type id like 'node'.
*
* @return bool
* TRUE if entity type has been disabled, FALSE if it was not.
*/
public function disableEntityType($entity_type_id) {
$entity_types = $this->getConfig('entity_types');
if (isset($entity_types[$entity_type_id])) {
unset($entity_types[$entity_type_id]);
$this->saveConfig('entity_types', $entity_types);
return TRUE;
}
return FALSE;
}
/**
* Sets sitemap settings for a bundle less entity type (e.g. user) or a bundle
* of an entity type (e.g. page).
*
* @param string $entity_type_id
* Entity type id like 'node' the bundle belongs to.
* @param string $bundle_name
* Name of the bundle. NULL if entity type has no bundles.
* @param array $settings
* An array of sitemap settings for this bundle/entity type.
* Example: ['index' => TRUE, 'priority' => 0.5]
*/
public function setBundleSettings($entity_type_id, $bundle_name = NULL, $settings) {
$bundle_name = !empty($bundle_name) ? $bundle_name : $entity_type_id;
$entity_types = $this->getConfig('entity_types');
foreach($settings as $key => $setting) {
$entity_types[$entity_type_id][$bundle_name][$key] = $setting;
}
$this->saveConfig('entity_types', $entity_types);
}
public static function getEntityInstanceBundleName($entity) {
return $entity->getEntityTypeId() == 'menu_link_content'
? $entity->getMenuName() : $entity->bundle(); // Menu fix.
}
public static function getBundleEntityTypeId($entity) {
return $entity->getEntityTypeId() == 'menu'
? 'menu_link_content' : $entity->getEntityType()->getBundleOf(); // Menu fix.
}
public function setEntityInstanceSettings($entity_type_id, $id, $settings) {
$entity_types = $this->getConfig('entity_types');
$entity = \Drupal::entityTypeManager()->getStorage($entity_type_id)->load($id);
$bundle_name = self::getEntityInstanceBundleName($entity);
if (isset($entity_types[$entity_type_id][$bundle_name])) {
// Check if overrides are different from bundle setting before saving.
$override = FALSE;
foreach ($settings as $key => $setting) {
if ($setting != $entity_types[$entity_type_id][$bundle_name][$key]) {
$override = TRUE;
break;
}
}
if ($override) { //Save overrides for this entity if something is different.
foreach($settings as $key => $setting) {
$entity_types[$entity_type_id][$bundle_name]['entities'][$id][$key] = $setting;
}
}
else { // Else unset override.
unset($entity_types[$entity_type_id][$bundle_name]['entities'][$id]);
}
$this->saveConfig('entity_types', $entity_types);
return TRUE;
}
return FALSE;
}
public function getBundleSettings($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;
}
return FALSE;
}
public function bundleIsIndexed($entity_type_id, $bundle_name) {
$settings = $this->getBundleSettings($entity_type_id, $bundle_name);
return !empty($settings['index']);
}
public function entityTypeIsEnabled($entity_type_id) {
$entity_types = $this->getConfig('entity_types');
return isset($entity_types[$entity_type_id]);
}
public function getEntityInstanceSettings($entity_type_id, $id) {
$entity_types = $this->getConfig('entity_types');
$entity = \Drupal::entityTypeManager()->getStorage($entity_type_id)->load($id);
$bundle_name = self::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);
}
}
/**
* Returns the whole sitemap, a requested sitemap chunk,
* or the sitemap index file.
......@@ -177,7 +312,7 @@ class Simplesitemap {
return $entity_types;
}
public static function entityTypeIsAtomic($entity_type_id) { //todo: make it work with entity object as well
public static function entityTypeIsAtomic($entity_type_id) {
if ($entity_type_id == 'menu_link_content') // Menu fix.
return FALSE;
$sitemap_entity_types = self::getSitemapEntityTypes();
......
......@@ -31,9 +31,6 @@ class SimplesitemapTest extends WebTestBase {
parent::setUp();
$this->drupalCreateContentType(['type' => 'page']);
$this->config('simple_sitemap.settings')
->set('entity_types', ['node' => ['page' => ['index' => 1, 'priority' => '0.5']]])
->save();
}
/**
......@@ -43,24 +40,35 @@ class SimplesitemapTest extends WebTestBase {
// Verify sitemap.xml has been generated on install (custom path generation).
$this->drupalGet('sitemap.xml');
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
$this->assertText('http://');
$this->drupalGet('sitemap.xml');
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
$this->assertText('http://');
$this->assertRaw('urlset');
$this->assertRaw('http');
/* @var $node \Drupal\Node\NodeInterface */
$node = $this->createNode(['title' => 'A new page', 'type' => 'page']);
// Generate new sitemap.
\Drupal::service('simple_sitemap.generator')->generateSitemap('nobatch');
// Set up the module.
$sitemap = \Drupal::service('simple_sitemap.generator');
$sitemap->setBundleSettings('node', 'page', ['index' => 1, 'priority' => '0.5']);
// Verify the cache was flushed and node is in the sitemap.
$sitemap->generateSitemap('nobatch');
$this->drupalGet('sitemap.xml');
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS');
$this->assertText('node/' . $node->id());
$this->drupalGet('sitemap.xml');
$this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT');
$this->assertText('node/' . $node->id());
// Test overriding of bundle entities.
$sitemap->setEntityInstanceSettings('node', $node->id(), ['index' => 1, 'priority' => '0.6']);
$sitemap->generateSitemap('nobatch');
$this->drupalGet('sitemap.xml');
$this->assertText('0.6');
// Test disabling sitemap support for an entity type.
// $sitemap->disableEntityType('node');
// $sitemap->generateSitemap('nobatch');
// $this->drupalGet('sitemap.xml');
// $this->assertNoText('node/');
}
}
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