View source
<?php
namespace Drupal\simple_sitemap\Form;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\simple_sitemap\Entity\EntityHelper;
use Drupal\simple_sitemap\Entity\SimpleSitemap;
use Drupal\simple_sitemap\Manager\Generator;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\simple_sitemap\Settings;
class FormHelper {
use StringTranslationTrait;
protected const PRIORITY_HIGHEST = 10;
protected const PRIORITY_DIVIDER = 10;
protected $generator;
protected $entityHelper;
protected $currentUser;
protected $formState;
protected $entityCategory;
protected $entityTypeId;
protected $bundleName;
protected $instanceId;
protected $bundleSettings;
protected $settings;
protected static $allowedFormOperations = [
'default',
'edit',
'add',
'register',
];
protected static $changefreqValues = [
'always',
'hourly',
'daily',
'weekly',
'monthly',
'yearly',
'never',
];
protected static $cronIntervals = [
1,
3,
6,
12,
24,
48,
72,
96,
120,
144,
168,
];
public function __construct(Generator $generator, Settings $settings, EntityHelper $entityHelper, AccountProxyInterface $current_user) {
$this->generator = $generator;
$this->settings = $settings;
$this->entityHelper = $entityHelper;
$this->currentUser = $current_user;
}
public function processForm(FormStateInterface $form_state) : bool {
$this->formState = $form_state;
$this
->cleanUpFormInfo();
if ($this
->getEntityDataFromFormEntity()) {
$this
->negotiateSettings();
}
return $this
->supports();
}
public function setEntityCategory(?string $entity_category) : FormHelper {
$this->entityCategory = $entity_category;
return $this;
}
public function getEntityCategory() : ?string {
return $this->entityCategory;
}
public function setEntityTypeId(?string $entity_type_id) : FormHelper {
$this->entityTypeId = $entity_type_id;
return $this;
}
public function getEntityTypeId() : ?string {
return $this->entityTypeId;
}
public function setBundleName(?string $bundle_name) : FormHelper {
$this->bundleName = $bundle_name;
return $this;
}
public function getBundleName() : ?string {
return $this->bundleName;
}
public function setInstanceId(?string $instance_id) : FormHelper {
$this->instanceId = $instance_id;
return $this;
}
public function getInstanceId() : ?string {
return $this->instanceId;
}
protected function supports() : bool {
if (empty($this
->getEntityCategory())) {
return FALSE;
}
if (!$this->currentUser
->hasPermission('administer sitemap settings')) {
return FALSE;
}
if (!$this->generator
->entityManager()
->entityTypeIsEnabled($this
->getEntityTypeId())) {
return FALSE;
}
return TRUE;
}
public function entityIsNew() : bool {
return empty($entity = $this
->getFormEntity()) || $entity
->isNew();
}
public function displayRegenerateNow(array &$form_fragment) : FormHelper {
$form_fragment['simple_sitemap_regenerate_now'] = [
'#type' => 'checkbox',
'#title' => $this
->t('Regenerate all sitemaps after hitting <em>Save</em>'),
'#description' => $this
->t('This setting will regenerate all sitemaps including the above changes.'),
'#default_value' => FALSE,
];
if ($this->settings
->get('cron_generate')) {
$form_fragment['simple_sitemap_regenerate_now']['#description'] .= '<br>' . $this
->t('Otherwise the sitemaps will be regenerated during a future cron run.');
}
return $this;
}
public function negotiateSettings() : FormHelper {
$this->bundleSettings = $this->generator
->setVariants(TRUE)
->entityManager()
->getBundleSettings($this
->getEntityTypeId(), $this
->getBundleName(), TRUE, TRUE);
if ($this
->getEntityCategory() === 'instance') {
foreach ($this->bundleSettings as $variant_id => $settings) {
if (NULL !== ($instance_id = $this
->getInstanceId())) {
$this->bundleSettings[$variant_id] = $this->generator
->setVariants($variant_id)
->entityManager()
->getEntityInstanceSettings($this
->getEntityTypeId(), $instance_id);
}
$this->bundleSettings[$variant_id]['bundle_settings'] = $settings;
}
}
return $this;
}
public function displayEntitySettings(&$form_fragment) : FormHelper {
$bundle_name = !empty($this
->getBundleName()) ? $this->entityHelper
->getBundleLabel($this
->getEntityTypeId(), $this
->getBundleName()) : $this
->t('undefined');
$variants = SimpleSitemap::loadMultiple();
$form_fragment['settings']['#markup'] = empty($variants) ? $this
->t('At least one sitemap needs to be defined for a bundle to be indexable.<br>Sitemaps can be configured <a href="@url">here</a>.', [
'@url' => $GLOBALS['base_url'] . '/admin/config/search/simplesitemap',
]) : '<strong>' . $this
->t('Sitemaps') . '</strong>';
foreach ($variants as $variant_id => $variant) {
$form_fragment['settings'][$variant_id] = [
'#type' => 'details',
'#title' => '<em>' . $this
->t($variant
->label()) . '</em>',
'#open' => !empty($this->bundleSettings[$variant_id]['index']),
];
$form_fragment['settings'][$variant_id]['#disabled'] = $this
->getEntityCategory() === 'instance' && empty($this->bundleSettings[$variant_id]['bundle_settings']['index']);
$form_fragment['settings'][$variant_id]['index_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings'] = [
'#type' => 'radios',
'#default_value' => (int) $this->bundleSettings[$variant_id]['index'],
'#options' => [
$this
->getEntityCategory() === 'instance' ? $this
->t('Do not index this <em>@bundle</em> entity in variant <em>@variant_label</em>', [
'@bundle' => $bundle_name,
'@variant_label' => $this
->t($variant
->label()),
]) : $this
->t('Do not index entities of type <em>@bundle</em> in variant <em>@variant_label</em>', [
'@bundle' => $bundle_name,
'@variant_label' => $this
->t($variant
->label()),
]),
$this
->getEntityCategory() === 'instance' ? $this
->t('Index this <em>@bundle entity</em> in variant <em>@variant_label</em>', [
'@bundle' => $bundle_name,
'@variant_label' => $this
->t($variant
->label()),
]) : $this
->t('Index entities of type <em>@bundle</em> in variant <em>@variant_label</em>', [
'@bundle' => $bundle_name,
'@variant_label' => $this
->t($variant
->label()),
]),
],
'#attributes' => [
'class' => [
'enabled-for-variant',
$variant_id,
],
],
];
if ($this
->getEntityCategory() === 'instance' && isset($this->bundleSettings[$variant_id]['bundle_settings']['index'])) {
$form_fragment['settings'][$variant_id]['index_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings']['#options'][(int) $this->bundleSettings[$variant_id]['bundle_settings']['index']] .= ' <em>(' . $this
->t('default') . ')</em>';
}
$form_fragment['settings'][$variant_id]['priority_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings'] = [
'#type' => 'select',
'#title' => $this
->t('Priority'),
'#description' => $this
->getEntityCategory() === 'instance' ? $this
->t('The priority this <em>@bundle</em> entity will have in the eyes of search engine bots.', [
'@bundle' => $bundle_name,
]) : $this
->t('The priority entities of this type will have in the eyes of search engine bots.'),
'#default_value' => $this->bundleSettings[$variant_id]['priority'],
'#options' => $this
->getPrioritySelectValues(),
'#states' => [
'visible' => [
':input[name="index_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings"]' => [
'value' => 1,
],
],
],
];
if ($this
->getEntityCategory() === 'instance' && isset($this->bundleSettings[$variant_id]['bundle_settings']['priority'])) {
$form_fragment['settings'][$variant_id]['priority_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings']['#options'][$this
->formatPriority($this->bundleSettings[$variant_id]['bundle_settings']['priority'])] .= ' (' . $this
->t('default') . ')';
}
$form_fragment['settings'][$variant_id]['changefreq_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings'] = [
'#type' => 'select',
'#title' => $this
->t('Change frequency'),
'#description' => $this
->getEntityCategory() === 'instance' ? $this
->t('The frequency with which this <em>@bundle</em> entity changes. Search engine bots may take this as an indication of how often to index it.', [
'@bundle' => $bundle_name,
]) : $this
->t('The frequency with which entities of this type change. Search engine bots may take this as an indication of how often to index them.'),
'#default_value' => isset($this->bundleSettings[$variant_id]['changefreq']) ? $this->bundleSettings[$variant_id]['changefreq'] : NULL,
'#options' => $this
->getChangefreqSelectValues(),
'#states' => [
'visible' => [
':input[name="index_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings"]' => [
'value' => 1,
],
],
],
];
if ($this
->getEntityCategory() === 'instance' && isset($this->bundleSettings[$variant_id]['bundle_settings']['changefreq'])) {
$form_fragment['settings'][$variant_id]['changefreq_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings']['#options'][$this->bundleSettings[$variant_id]['bundle_settings']['changefreq']] .= ' (' . $this
->t('default') . ')';
}
$form_fragment['settings'][$variant_id]['include_images_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings'] = [
'#type' => 'select',
'#title' => $this
->t('Include images'),
'#description' => $this
->getEntityCategory() === 'instance' ? $this
->t('Determines if images referenced by this <em>@bundle</em> entity should be included in the sitemap.', [
'@bundle' => $bundle_name,
]) : $this
->t('Determines if images referenced by entities of this type should be included in the sitemap.'),
'#default_value' => isset($this->bundleSettings[$variant_id]['include_images']) ? (int) $this->bundleSettings[$variant_id]['include_images'] : 0,
'#options' => [
$this
->t('No'),
$this
->t('Yes'),
],
'#states' => [
'visible' => [
':input[name="index_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings"]' => [
'value' => 1,
],
],
],
];
if ($this
->getEntityCategory() === 'instance' && isset($this->bundleSettings[$variant_id]['bundle_settings']['include_images'])) {
$form_fragment['settings'][$variant_id]['include_images_' . $variant_id . '_' . $this
->getEntityTypeId() . '_settings']['#options'][(int) $this->bundleSettings[$variant_id]['bundle_settings']['include_images']] .= ' (' . $this
->t('default') . ')';
}
}
return $this;
}
protected function getEntityDataFromFormEntity() : bool {
if (!($form_entity = $this
->getFormEntity())) {
return FALSE;
}
$entity_type_id = $form_entity
->getEntityTypeId();
$sitemap_entity_types = $this->entityHelper
->getSupportedEntityTypes();
if (isset($sitemap_entity_types[$entity_type_id])) {
$this
->setEntityCategory('instance');
}
else {
foreach ($sitemap_entity_types as $sitemap_entity_type) {
if ($sitemap_entity_type
->getBundleEntityType() === $entity_type_id) {
$this
->setEntityCategory('bundle');
break;
}
}
}
$this
->setEntityCategory(NULL === $this
->getEntityCategory() && $entity_type_id === 'menu' ? 'bundle' : $this
->getEntityCategory());
switch ($this
->getEntityCategory()) {
case 'bundle':
$this
->setEntityTypeId($this->entityHelper
->getBundleEntityTypeId($form_entity));
$this
->setBundleName($form_entity
->id());
$this
->setInstanceId(NULL);
break;
case 'instance':
$this
->setEntityTypeId($entity_type_id);
$this
->setBundleName($this->entityHelper
->getEntityInstanceBundleName($form_entity));
$this
->setInstanceId(!$this
->entityIsNew() ? $form_entity
->id() : NULL);
break;
default:
return FALSE;
}
return TRUE;
}
protected function getFormEntity() {
$form_object = $this->formState
->getFormObject();
if (NULL !== $form_object && method_exists($form_object, 'getOperation') && method_exists($form_object, 'getEntity') && in_array($form_object
->getOperation(), self::$allowedFormOperations, TRUE)) {
return $form_object
->getEntity();
}
return FALSE;
}
public function cleanUpFormInfo() : FormHelper {
$this->entityCategory = NULL;
$this->entityTypeId = NULL;
$this->bundleName = NULL;
$this->instanceId = NULL;
$this->bundleSettings = NULL;
return $this;
}
public function valuesChanged($form, array $values) : bool {
return TRUE;
}
public function getPrioritySelectValues() : array {
$options = [];
foreach (range(0, self::PRIORITY_HIGHEST) as $value) {
$value = $this
->formatPriority($value / self::PRIORITY_DIVIDER);
$options[$value] = $value;
}
return $options;
}
public function getChangefreqSelectValues() : array {
$options = [
'' => $this
->t('- Not specified -'),
];
foreach (self::getChangefreqOptions() as $setting) {
$options[$setting] = $this
->t($setting);
}
return $options;
}
public static function getChangefreqOptions() : array {
return self::$changefreqValues;
}
public function formatPriority(string $priority) : string {
return number_format((double) $priority, 1, '.', '');
}
public static function isValidPriority(string $priority) : bool {
return is_numeric($priority) && $priority >= 0 && $priority <= 1;
}
public static function isValidChangefreq(string $changefreq) : bool {
return in_array($changefreq, self::$changefreqValues, TRUE);
}
public static function getCronIntervalOptions() : array {
$formatter = \Drupal::service('date.formatter');
$intervals = array_flip(self::$cronIntervals);
foreach ($intervals as $interval => &$label) {
$label = $formatter
->formatInterval($interval * 60 * 60);
}
return [
0 => t('On every cron run'),
] + $intervals;
}
public static function getDonationText() : string {
return '<div class="description">' . t('If you would like to say thanks and support the development of this module, a <a target="_blank" href="@url">donation</a> will be much appreciated.', [
'@url' => 'https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=5AFYRSBLGSC3W',
]) . '</div>';
}
}