Commit 65397c0d authored by gbyte.co's avatar gbyte.co

Make bundle-less entity types configurable on 'Sitemap entities' page.

parent 1b9ef2dd
......@@ -6,7 +6,6 @@ custom:
entity_types:
node: []
taxonomy_term: []
user: []
menu_link_content: []
settings:
......
......@@ -6,7 +6,7 @@ simple_sitemap.settings:
simple_sitemap.settings_entities:
route_name: simple_sitemap.settings_entities
title: 'Entities'
title: 'Sitemap entities'
base_route: simple_sitemap.settings
simple_sitemap.settings_custom:
......
......@@ -20,95 +20,28 @@ function simple_sitemap_help($route_name, \Drupal\Core\Routing\RouteMatchInterfa
* Adds sitemap settings to entity types that are supported via plugins.
*/
function simple_sitemap_form_alter(&$form, $form_state, $form_id) {
// Do not alter the form if user lacks certain permissions.
if (!\Drupal::currentUser()->hasPermission('administer sitemap settings'))
return;
$f = new Form($form, $form_state, $form_id);
// Do not alter the form if it is irrelevant to sitemap generation.
if (empty($f->entityCategory))
return;
$sitemap = \Drupal::service('simple_sitemap.generator');
// Get current entity type sitemap settings.
$entity_types = $sitemap->getConfig('entity_types');
// Do not alter the form if entity is not enabled in sitemap settings.
if (!isset($entity_types[$f->entityTypeId]))
return;
// Do not alter the form, if sitemap is disabled for the entity type of this entity instance.
if ($f->entityCategory == 'instance' && empty($entity_types[$f->entityTypeId][$f->bundleName]['index']))
return;
// Setting default form values.
$index = 0;
$priority = Form::PRIORITY_DEFAULT;
// Overwriting defaults if settings found for bundle.
if (isset($entity_types[$f->entityTypeId][$f->bundleName]['index'])) {
$bundle_index = $index = $entity_types[$f->entityTypeId][$f->bundleName]['index'];
$bundle_priority = $priority = $entity_types[$f->entityTypeId][$f->bundleName]['priority'];
}
// Overwriting defaults if settings found for this entity instance.
if ($f->entityCategory == 'instance') {
if (isset($entity_types[$f->entityTypeId][$f->bundleName]['entities'][$f->instanceId]['index'])) {
$index = $entity_types[$f->entityTypeId][$f->bundleName]['entities'][$f->instanceId]['index'];
$priority = $entity_types[$f->entityTypeId][$f->bundleName]['entities'][$f->instanceId]['priority'];
}
}
$form['simple_sitemap'] = array(
$f = new Form($form_state);
if ($f->alteringForm) {
$form['simple_sitemap'] = [
'#type' => 'details',
'#group' => isset($form['additional_settings']) ? 'additional_settings' : 'advanced',
'#title' => t('Simple XML sitemap'),
'#description' => $f->entityCategory == 'instance' ? t('Settings for this specific entity can be overridden here.') : '',
);
];
// Attach some js magic to forms.
$form['simple_sitemap']['#attached']['library'][] = 'simple_sitemap/form';
if ($f->entityTypeId != 'comment' || $f->entityCategory != 'instance') // todo: JS not working on comment entity form, hence disabling.
$form['#attached']['library'][] = 'simple_sitemap/form';
// Only attach fieldset summary js to 'additional settings' vertical tabs.
if (isset($form['additional_settings'])) {
$form['simple_sitemap']['#attached']['library'][] = 'simple_sitemap/fieldsetSummaries';
}
$form['simple_sitemap']['simple_sitemap_index_content'] = array(
'#type' => 'radios',
'#default_value' => $index,
'#options' => [
0 => $f->entityCategory == 'instance' ? t('Do not index this entity') : t('Do not index entities of this type'),
1 => $f->entityCategory == 'instance' ? t('Index this entity') : t('Index entities of this type'),
]
);
if ($f->entityCategory == 'instance' && isset($bundle_index)) {
$form['simple_sitemap']['simple_sitemap_index_content']['#options'][$bundle_index] .= ' <em>(' . t('Default') . ')</em>';
}
$form['simple_sitemap']['simple_sitemap_priority'] = array(
'#type' => 'select',
'#title' => t('Priority'),
'#description' => $f->entityCategory == 'instance' ? t('The priority this entity will have in the eyes of search engine bots.') : t('The priority entities of this bundle will have in the eyes of search engine bots.'),
'#default_value' => $priority,
'#options' => Form::getPrioritySelectValues(),
);
if ($f->entityCategory == 'instance' && isset($bundle_priority)) {
$form['simple_sitemap']['simple_sitemap_priority']['#options'][(string)$bundle_priority] .= ' (' . t('Default') . ')';
}
$form['simple_sitemap']['simple_sitemap_regenerate_now'] = array(
'#type' => 'checkbox',
'#title' => t('Regenerate sitemap after hitting <em>Save</em>'),
'#description' => t('This setting will regenerate the whole sitemap including the above changes.'),
'#default_value' => FALSE,
);
if ($sitemap->getSetting('cron_generate')) {
$form['simple_sitemap']['simple_sitemap_regenerate_now']['#description'] .= '</br>' . t('Otherwise the sitemap will be regenerated on the next cron run.');
$form['#attached']['library'][] = 'simple_sitemap/fieldsetSummaries';
}
$f->displayEntitySitemapSettings($form['simple_sitemap']);
$f->displaySitemapRegenerationSetting($form['simple_sitemap']);
}
else {
return;
}
$form['#simple_sitemap'] = $f;
// Add submission handler.
......@@ -160,8 +93,7 @@ function simple_sitemap_entity_form_submit($form, &$form_state) {
&& $values['simple_sitemap_priority'] == $entity_types[$f->entityTypeId][$f->bundleName]['priority']) {
unset($entity_types[$f->entityTypeId][$f->bundleName]['entities'][$f->instanceId]);
}
// Else save overrides for this entity.
else {
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'];
}
......@@ -184,7 +116,6 @@ function simple_sitemap_entity_form_submit($form, &$form_state) {
function simple_sitemap_cron() {
$sitemap = \Drupal::service('simple_sitemap.generator');
if ($sitemap->getSetting('cron_generate')) {
// Regenerate sitemap for all languages.
$sitemap->generateSitemap('backend');
}
}
......@@ -194,7 +125,7 @@ function simple_sitemap_cron() {
*
* Removes settings of the removed bundle.
*
* @todo Not working for menu bundles, as they are technically not bundles.
* @todo Not working for menu bundles, as they are technically not bundles. Implement hook_menu_delete().
*/
function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) {
$sitemap = \Drupal::service('simple_sitemap.generator');
......@@ -206,7 +137,7 @@ function simple_sitemap_entity_bundle_delete($entity_type_id, $bundle) {
if ($sitemap->getSetting('cron_generate')) {
$message .= '</br>' . t('Otherwise the sitemap will be regenerated on the next cron run.');
}
// drupal_set_message($message); // Commented out, as html code is visible.
// drupal_set_message($message); // todo: Commented out, as html code is visible.
}
}
......
administer sitemap settings:
title: 'Administer sitemap settings'
description: 'Administer the sitemap settings, alter inclusion and priority of content and generate the sitemap on demand.'
description: 'Administer Simple XML sitemap settings, alter inclusion and priority of content and generate the sitemap on demand.'
restrict access: false
......@@ -115,7 +115,7 @@ class Batch {
public static function finishGeneration($success, $results, $operations) {
if ($success) {
$remove_sitemap = empty($results['chunk_count']);
if (!empty($results['generate']) || $remove_sitemap/*is_null(db_query('SELECT MAX(id) FROM {simple_sitemap}')->fetchField())*/) { //todo test
if (!empty($results['generate']) || $remove_sitemap) {
SitemapGenerator::generateSitemap($results['generate'], $remove_sitemap);
}
Cache::invalidateTags(array('simple_sitemap'));
......@@ -171,7 +171,6 @@ class Batch {
$results = $query->execute();
if (!empty($results)) {
// $entities = entity_load_multiple($entity_info['entity_type_name'], $results);
$entities = \Drupal::entityTypeManager()->getStorage($entity_info['entity_type_name'])->loadMultiple($results);
foreach ($entities as $entity_id => $entity) {
......
......@@ -23,6 +23,16 @@ class SimplesitemapController extends ControllerBase {
*/
protected $sitemapGenerator;
/**
* SimplesitemapController constructor.
*
* @param \Drupal\simple_sitemap\Simplesitemap $sitemap_generator
* The sitemap generator.
*/
public function __construct($sitemap_generator) {
$this->sitemapGenerator = $sitemap_generator;
}
/**
* Returns the whole sitemap, a requested sitemap chunk, or the sitemap index file.
*
......@@ -44,16 +54,6 @@ class SimplesitemapController extends ControllerBase {
return $response;
}
/**
* SimplesitemapController constructor.
*
* @param \Drupal\simple_sitemap\Simplesitemap $sitemap_generator
* The sitemap generator.
*/
public function __construct($sitemap_generator) {
$this->sitemapGenerator = $sitemap_generator;
}
/**
* {@inheritdoc}
*/
......
......@@ -15,46 +15,135 @@ class Form {
const PRIORITY_HIGHEST = 10;
const PRIORITY_DIVIDER = 10;
public $alteringForm;
public $entityCategory;
public $entityTypeId;
public $bundleName;
public $instanceId;
private $formState;
private $formId;
private $sitemap;
/**
* Form constructor.
*/
function __construct(&$form, $form_state, $form_id) {
$this->formId = $form_id;
function __construct($form_state = NULL) {
$this->formState = $form_state;
$this->entityCategory = NULL;
$this->alteringForm = TRUE;
$this->sitemap = \Drupal::service('simple_sitemap.generator');
// Do not alter the form if user lacks certain permissions.
if (!\Drupal::currentUser()->hasPermission('administer sitemap settings')) {
$this->alteringForm = FALSE;
return;
}
$this->getEntityData();
}
if (!$this->getEntityDataFromFormId()) {
private function getEntityData() {
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;
// 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']))
$this->alteringForm = FALSE;
}
public function setEntityCategory($entity_category) {
$this->entityCategory = $entity_category;
}
/**
* This is a temporary solution to be able to set sitemap settings
* for all 'user' entities on the form 'user_admin_settings', as there is no
* general setting page where non-bundle entity types can be set up.
*
* @todo: Remove this and create a general setting page for all entity types.
*/
private function getEntityDataFromFormId() {
switch ($this->formId) {
public function setEntityTypeId($entity_type_id) {
$this->entityTypeId = $entity_type_id;
}
case 'user_admin_settings':
$this->entityCategory = 'bundle';
$this->entityTypeId = 'user';
$this->bundleName = 'user';
$this->instanceId = NULL;
return TRUE;
public function setBundleName($bundle_name) {
$this->bundleName = $bundle_name;
}
default:
return FALSE;
public function setInstanceId($instance_id) {
$this->instanceId = $instance_id;
}
public function displaySitemapRegenerationSetting(&$form_fragment) {
$form_fragment['simple_sitemap_regenerate_now'] = array(
'#type' => 'checkbox',
'#title' => t('Regenerate sitemap after hitting <em>Save</em>'),
'#description' => t('This setting will regenerate the whole sitemap including the above changes.'),
'#default_value' => FALSE,
);
if ($this->sitemap->getSetting('cron_generate')) {
$form_fragment['simple_sitemap_regenerate_now']['#description'] .= '</br>' . t('Otherwise the sitemap will be regenerated on the next cron run.');
}
}
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'];
}
if (!$multiple) {
$form_fragment[$prefix . 'simple_sitemap_index_content'] = [
'#type' => 'radios',
'#default_value' => $index,
'#options' => [
0 => $this->entityCategory == 'instance' ? t('Do not index this entity') : t('Do not index entities of this type'),
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') {
$priority_description = t('The priority this entity will have in the eyes of search engine bots.');
}
elseif (!$multiple) {
$priority_description = t('The priority entities of this bundle will have in the eyes of search engine bots.');
}
else {
$priority_description = t('The priority entities of this type will have in the eyes of search engine bots.');
}
$form_fragment[$prefix . 'simple_sitemap_priority'] = [
'#type' => 'select',
'#title' => t('Priority'),
'#description' => $priority_description,
'#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') . ')';
}
}
......
......@@ -9,6 +9,7 @@ namespace Drupal\simple_sitemap\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\simple_sitemap\Form;
/**
* SimplesitemapCustomLinksFrom
......@@ -37,11 +38,6 @@ class SimplesitemapCustomLinksForm extends ConfigFormBase {
$sitemap = \Drupal::service('simple_sitemap.generator');
$setting_string = '';
foreach ($sitemap->getConfig('custom') as $custom_link) {
// todo: remove this statement after removing the index key from the configuration.
if (isset($custom_link['index']) && $custom_link['index'] == 0)
continue;
$setting_string .= isset($custom_link['priority']) ? $custom_link['path'] . ' ' . $custom_link['priority'] : $custom_link['path'];
$setting_string .= "\r\n";
}
......@@ -59,15 +55,8 @@ class SimplesitemapCustomLinksForm extends ConfigFormBase {
'#description' => t("Please specify drupal internal (relative) paths, one per line. Do not forget to prepend the paths with a '/'. You can optionally add a priority (0.0 - 1.0) by appending it to the path after a space. The home page with the highest priority would be <em>/ 1.0</em>, the contact page with the default priority would be <em>/contact 0.5</em>."),
);
$form['simple_sitemap_custom']['simple_sitemap_regenerate_now'] = array(
'#type' => 'checkbox',
'#title' => t('Regenerate sitemap after hitting <em>Save</em>'),
'#description' => t('This setting will regenerate the whole sitemap including the above changes.'),
'#default_value' => FALSE,
);
if ($sitemap->getSetting('cron_generate')) {
$form['simple_sitemap_custom']['simple_sitemap_regenerate_now']['#description'] .= '</br>' . t('Otherwise the sitemap will be regenerated on the next cron run.');
}
$f = new Form();
$f->displaySitemapRegenerationSetting($form['simple_sitemap_custom']);
return parent::buildForm($form, $form_state);
}
......
......@@ -10,6 +10,7 @@ namespace Drupal\simple_sitemap\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\simple_sitemap\Simplesitemap;
use Drupal\simple_sitemap\Form;
/**
* SimplesitemapSettingsFrom
......@@ -38,25 +39,37 @@ class SimplesitemapEntitiesForm extends ConfigFormBase {
$sitemap = \Drupal::service('simple_sitemap.generator');
$form['simple_sitemap_entities']['entities'] = array(
'#title' => t('Supported entities'),
'#title' => t('Sitemap entities'),
'#type' => 'fieldset',
'#markup' => '<p>' . t('XML sitemap settings will be added only to entity forms of entities enabled here. Disabling an entity on this page will irreversibly delete its sitemap settings.') . '</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. node) inclusion settings have to be set on their bundle pages (e.g. 'page'). Disabling an entity type on this page will irreversibly delete its sitemap settings including per-entity overrides.") . '</p>',
);
$options = [];
$entity_types = Simplesitemap::getSitemapEntityTypes();
foreach ($entity_types as $entity_type_id => $entity_type) {
$options[$entity_type_id] = $entity_type->getLabel() ? : $entity_type_id;
}
$form['simple_sitemap_entities']['entities']['entities'] = array(
'#type' => 'checkboxes',
'#title' => t('Enable sitemap settings'),
'#description' => t(''),
'#options' => $options,
'#default_value' => array_keys($sitemap->getConfig('entity_types')),
);
$sitemap_entity_types = Simplesitemap::getSitemapEntityTypes();
$entity_types = $sitemap->getConfig('entity_types');
$f = new Form();
foreach ($sitemap_entity_types as $entity_type_id => $entity_type) {
$entity_type_label = $entity_type->getLabel() ? : $entity_type_id;
$entity_type_enabled = isset($entity_types[$entity_type_id]);
$form['simple_sitemap_entities']['entities'][$entity_type_id] = [
'#type' => 'fieldset',
'#title' => $entity_type_label,
];
$form['simple_sitemap_entities']['entities'][$entity_type_id][$entity_type_id . '_enabled'] = [
'#type' => 'checkbox',
'#title' => t('Enable @entity_type_label support', array('@entity_type_label' => strtolower($entity_type_label))),
'#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,
];
if (Simplesitemap::entityTypeIsAtomic($entity_type_id)) {
$form['simple_sitemap_entities']['entities'][$entity_type_id][$entity_type_id . '_enabled']['#description'] = t('Sitemap settings for this entity type can be set below and overridden on its entity pages.');
$f->setEntityCategory('bundle');
$f->setEntityTypeId($entity_type_id);
$f->setBundleName($entity_type_id);
$f->displayEntitySitemapSettings($form['simple_sitemap_entities']['entities'][$entity_type_id][$entity_type_id . '_settings'], TRUE);
}
}
$f->displaySitemapRegenerationSetting($form['simple_sitemap_entities']['entities']);
return parent::buildForm($form, $form_state);
}
......@@ -66,17 +79,30 @@ class SimplesitemapEntitiesForm extends ConfigFormBase {
public function submitForm(array &$form, FormStateInterface $form_state) {
$sitemap = \Drupal::service('simple_sitemap.generator');
$entity_types = $sitemap->getConfig('entity_types');
foreach($form_state->getValue('entities') as $entity_type_name => $enable) {
if (!$enable) {
unset($entity_types[$entity_type_name]);
$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] = [];
}
}
else {
unset($entity_types[$entity_type_id]);
}
elseif (empty($entity_types[$entity_type_name])) {
$entity_types[$entity_type_name] = [];
}
}
$sitemap->saveConfig('entity_types', $entity_types);
parent::submitForm($form, $form_state);
// Regenerate sitemaps according to user setting.
if ($form_state->getValue('simple_sitemap_regenerate_now')) {
$sitemap->generateSitemap();
}
}
}
......@@ -27,7 +27,7 @@ class Simplesitemap {
*/
function __construct(ConfigFactoryInterface $config_factory) {
$this->config = $config_factory->get('simple_sitemap.settings');
$this->sitemap = db_query("SELECT * FROM {simple_sitemap}")->fetchAllAssoc('id');
$this->sitemap = \Drupal::service('database')->query("SELECT * FROM {simple_sitemap}")->fetchAllAssoc('id');
}
/**
......@@ -176,4 +176,18 @@ class Simplesitemap {
}
return $entity_types;
}
public static function entityTypeIsAtomic($entity_type_id) { //todo: make it work with entity object as well
if ($entity_type_id == 'menu_link_content') // Menu fix.
return FALSE;
$sitemap_entity_types = self::getSitemapEntityTypes();
if (isset($sitemap_entity_types[$entity_type_id])) {
$entity_type = $sitemap_entity_types[$entity_type_id];
if (empty($entity_type->getBundleEntityType())) {
return TRUE;
}
return FALSE;
}
return FALSE; //todo: throw exception
}
}
......@@ -92,18 +92,21 @@ class SitemapGenerator {
*
* @param array $links
* All links with their multilingual versions and settings.
* @param bool $remove_sitemap
* Remove old sitemap from database before inserting the new one.
*/
public static function generateSitemap($links, $remove_sitemap = FALSE) {
// Invoke alter hook.
\Drupal::moduleHandler()->alter('simple_sitemap_links', $links);
$values = array(
'id' => $remove_sitemap ? 1 : db_query('SELECT MAX(id) FROM {simple_sitemap}')->fetchField() + 1,
'id' => $remove_sitemap ? 1 : \Drupal::service('database')->query('SELECT MAX(id) FROM {simple_sitemap}')->fetchField() + 1,
'sitemap_string' => self::generateSitemapChunk($links),
'sitemap_created' => REQUEST_TIME,
);
if ($remove_sitemap)
db_truncate('simple_sitemap')->execute();
db_insert('simple_sitemap')->fields($values)->execute();
if ($remove_sitemap) {
\Drupal::service('database')->truncate('simple_sitemap')->execute();
}
\Drupal::service('database')->insert('simple_sitemap')->fields($values)->execute();
}
/**
......
......@@ -32,7 +32,7 @@ class SimplesitemapTest extends WebTestBase {
$this->drupalCreateContentType(['type' => 'page']);
$this->config('simple_sitemap.settings')
->set('entity_types', ['node_type' => ['page' => ['index' => 1, 'priority' => '0.5']]])
->set('entity_types', ['node' => ['page' => ['index' => 1, 'priority' => '0.5']]])
->save();
}
......
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