FormHelper.php 9.69 KB
Newer Older
1 2
<?php

3
namespace Drupal\simple_sitemap\Form;
4

5
use Drupal\Core\StringTranslation\StringTranslationTrait;
Pawel G's avatar
Pawel G committed
6 7
use Drupal\simple_sitemap\Simplesitemap;
use Drupal\Core\Session\AccountProxyInterface;
8

9
/**
Pawel G's avatar
Pawel G committed
10 11
 * Class FormHelper.
 *
12
 * @package Drupal\simple_sitemap\Form
13
 */
14
class FormHelper {
15
  use StringTranslationTrait;
16

Pawel G's avatar
Pawel G committed
17 18 19 20
  const PRIORITY_DEFAULT = 0.5;
  const PRIORITY_HIGHEST = 10;
  const PRIORITY_DIVIDER = 10;

21
  private $generator;
22
  private $currentUser;
23 24 25 26
  private $formState;

  public $alteringForm = TRUE;
  public $entityCategory = NULL;
27 28
  public $entityTypeId;
  public $bundleName;
29
  public $instanceId;
30

31 32 33 34
  private static $allowedFormOperations = [
    'default',
    'edit',
    'add',
Pawel G's avatar
Pawel G committed
35
    'register',
36 37 38 39 40
  ];

  private static $valuesToCheck = [
    'simple_sitemap_index_content',
    'simple_sitemap_priority',
Pawel G's avatar
Pawel G committed
41
    'simple_sitemap_regenerate_now',
42
  ];
43

44 45
  /**
   * Form constructor.
46 47 48
   *
   * @param $generator
   * @param $current_user
49
   */
Pawel G's avatar
Pawel G committed
50 51 52 53
  public function __construct(
    Simplesitemap $generator,
    AccountProxyInterface $current_user
  ) {
54
    $this->generator = $generator;
55
    $this->currentUser = $current_user;
56
  }
Pawel G's avatar
Pawel G committed
57

58 59 60 61
  /**
   * @param $form_state
   * @return $this
   */
62
  public function processForm($form_state) {
Pawel G's avatar
Pawel G committed
63
    $this->formState = $form_state;
Pawel G's avatar
Pawel G committed
64
    if (!is_null($this->formState)) {
65
      $this->getEntityDataFromFormEntity();
Pawel G's avatar
Pawel G committed
66 67
      $this->assertAlteringForm();
    }
68
    return $this;
69 70
  }

71 72 73 74
  /**
   * @param $entity_category
   * @return $this
   */
75 76
  public function setEntityCategory($entity_category) {
    $this->entityCategory = $entity_category;
77
    return $this;
78 79
  }

80 81 82 83
  /**
   * @param $entity_type_id
   * @return $this
   */
84 85
  public function setEntityTypeId($entity_type_id) {
    $this->entityTypeId = $entity_type_id;
86
    return $this;
87 88
  }

89 90 91 92
  /**
   * @param $bundle_name
   * @return $this
   */
93 94
  public function setBundleName($bundle_name) {
    $this->bundleName = $bundle_name;
95
    return $this;
96 97
  }

98 99 100 101
  /**
   * @param $instance_id
   * @return $this
   */
102 103
  public function setInstanceId($instance_id) {
    $this->instanceId = $instance_id;
104
    return $this;
105 106
  }

Pawel G's avatar
Pawel G committed
107 108 109
  /**
   *
   */
Pawel G's avatar
Pawel G committed
110 111 112
  private function assertAlteringForm() {

    // Do not alter the form if user lacks certain permissions.
Pawel G's avatar
Pawel G committed
113
    if (!$this->currentUser->hasPermission('administer sitemap settings')) {
Pawel G's avatar
Pawel G committed
114
      $this->alteringForm = FALSE;
Pawel G's avatar
Pawel G committed
115
    }
Pawel G's avatar
Pawel G committed
116 117

    // Do not alter the form if it is irrelevant to sitemap generation.
Pawel G's avatar
Pawel G committed
118
    elseif (empty($this->entityCategory)) {
Pawel G's avatar
Pawel G committed
119
      $this->alteringForm = FALSE;
Pawel G's avatar
Pawel G committed
120
    }
Pawel G's avatar
Pawel G committed
121 122

    // Do not alter the form if entity is not enabled in sitemap settings.
Pawel G's avatar
Pawel G committed
123
    elseif (!$this->generator->entityTypeIsEnabled($this->entityTypeId)) {
Pawel G's avatar
Pawel G committed
124
      $this->alteringForm = FALSE;
Pawel G's avatar
Pawel G committed
125
    }
Pawel G's avatar
Pawel G committed
126 127 128 129

    // Do not alter the form, if sitemap is disabled for the entity type of this
    // entity instance.
    elseif ($this->entityCategory == 'instance'
Pawel G's avatar
Pawel G committed
130
      && !$this->generator->bundleIsIndexed($this->entityTypeId, $this->bundleName)) {
Pawel G's avatar
Pawel G committed
131
      $this->alteringForm = FALSE;
Pawel G's avatar
Pawel G committed
132
    }
Pawel G's avatar
Pawel G committed
133 134
  }

135 136 137
  /**
   * @param $form_fragment
   */
Pawel G's avatar
Pawel G committed
138
  public function displayRegenerateNow(&$form_fragment) {
Pawel G's avatar
Pawel G committed
139
    $form_fragment['simple_sitemap_regenerate_now'] = [
140
      '#type' => 'checkbox',
141 142
      '#title' => $this->t('Regenerate sitemap after hitting <em>Save</em>'),
      '#description' => $this->t('This setting will regenerate the whole sitemap including the above changes.'),
143
      '#default_value' => FALSE,
Pawel G's avatar
Pawel G committed
144
    ];
Pawel G's avatar
Pawel G committed
145
    if ($this->generator->getSetting('cron_generate')) {
146
      $form_fragment['simple_sitemap_regenerate_now']['#description'] .= '</br>' . $this->t('Otherwise the sitemap will be regenerated on the next cron run.');
147 148
    }
  }
149 150 151 152 153 154

  /**
   * @param $form_fragment
   * @param bool $multiple
   * @return $this
   */
Pawel G's avatar
Pawel G committed
155
  public function displayEntitySettings(&$form_fragment, $multiple = FALSE) {
156
    $prefix = $multiple ? $this->entityTypeId . '_' : '';
157

158
    if ($this->entityCategory == 'instance') {
Pawel G's avatar
Pawel G committed
159 160
      $bundle_settings = $this->generator->getBundleSettings($this->entityTypeId, $this->bundleName);
      $settings = !is_null($this->instanceId) ? $this->generator->getEntityInstanceSettings($this->entityTypeId, $this->instanceId) : $bundle_settings;
161
    }
162
    else {
Pawel G's avatar
Pawel G committed
163
      $settings = $this->generator->getBundleSettings($this->entityTypeId, $this->bundleName);
164 165 166
    }
    $index = isset($settings['index']) ? $settings['index'] : 0;
    $priority = isset($settings['priority']) ? $settings['priority'] : self::PRIORITY_DEFAULT;
167
    $bundle_name = !empty($this->bundleName) ? $this->bundleName : $this->t('undefined');
168 169 170 171 172 173

    if (!$multiple) {
      $form_fragment[$prefix . 'simple_sitemap_index_content'] = [
        '#type' => 'radios',
        '#default_value' => $index,
        '#options' => [
174 175
          0 => $this->entityCategory == 'instance' ? $this->t('Do not index this @bundle entity', ['@bundle' => $bundle_name]) : $this->t('Do not index entities of this type'),
          1 => $this->entityCategory == 'instance' ? $this->t('Index this @bundle entity', ['@bundle' => $bundle_name]) : $this->t('Index entities of this type'),
Pawel G's avatar
Pawel G committed
176
        ],
177
      ];
178
      if ($this->entityCategory == 'instance' && isset($bundle_settings['index'])) {
179
        $form_fragment[$prefix . 'simple_sitemap_index_content']['#options'][$bundle_settings['index']] .= ' <em>(' . $this->t('Default') . ')</em>';
180 181 182
      }
    }

Pawel G's avatar
Pawel G committed
183
    if ($this->entityCategory == 'instance') {
184
      $priority_description = $this->t('The priority this @bundle entity will have in the eyes of search engine bots.', ['@bundle' => $bundle_name]);
Pawel G's avatar
Pawel G committed
185 186
    }
    else {
187
      $priority_description = $this->t('The priority entities of this type will have in the eyes of search engine bots.');
Pawel G's avatar
Pawel G committed
188
    }
189 190
    $form_fragment[$prefix . 'simple_sitemap_priority'] = [
      '#type' => 'select',
191
      '#title' => $this->t('Priority'),
192 193
      '#description' => $priority_description,
      '#default_value' => $priority,
194
      '#options' => $this->getPrioritySelectValues(),
195
    ];
196
    if ($this->entityCategory == 'instance' && isset($bundle_settings['priority'])) {
197
      $form_fragment[$prefix . 'simple_sitemap_priority']['#options'][$this->formatPriority($bundle_settings['priority'])] .= ' (' . $this->t('Default') . ')';
198
    }
Pawel G's avatar
Pawel G committed
199
    return $this;
200 201 202 203 204 205 206
  }

  /**
   * Checks if this particular form is a bundle form, or a bundle instance form
   * and gathers sitemap settings from the database.
   *
   * @return bool
Pawel G's avatar
Pawel G committed
207
   *   TRUE if this is a bundle or bundle instance form, FALSE otherwise.
208
   */
209
  private function getEntityDataFromFormEntity() {
210 211
    $form_entity = $this->getFormEntity();
    if ($form_entity !== FALSE) {
212
      $entity_type_id = $form_entity->getEntityTypeId();
213
      $sitemap_entity_types = $this->generator->getSitemapEntityTypes();
214 215
      if (isset($sitemap_entity_types[$entity_type_id])) {
        $this->entityCategory = 'instance';
216 217
      }
      else {
Pawel G's avatar
Pawel G committed
218
        foreach ($sitemap_entity_types as $sitemap_entity) {
219 220 221
          if ($sitemap_entity->getBundleEntityType() == $entity_type_id) {
            $this->entityCategory = 'bundle';
            break;
222 223 224
          }
        }
      }
225

226
      // Menu fix.
227
      $this->entityCategory = is_null($this->entityCategory) && $entity_type_id == 'menu' ? 'bundle' : $this->entityCategory;
228 229 230

      switch ($this->entityCategory) {
        case 'bundle':
231
          $this->entityTypeId = $this->generator->getBundleEntityTypeId($form_entity);
232 233 234 235 236
          $this->bundleName = $form_entity->id();
          $this->instanceId = NULL;
          break;

        case 'instance':
237
          $this->entityTypeId = $entity_type_id;
238
          $this->bundleName = $this->generator->getEntityInstanceBundleName($form_entity);
Pawel G's avatar
Pawel G committed
239 240
          // New menu link's id is '' instead of NULL, hence checking for empty.
          $this->instanceId = !empty($form_entity->id()) ? $form_entity->id() : NULL;
241 242 243 244 245 246
          break;

        default:
          return FALSE;
      }
      return TRUE;
247 248 249 250 251 252 253
    }
    return FALSE;
  }

  /**
   * Gets the object entity of the form if available.
   *
Pawel G's avatar
Pawel G committed
254
   * @return object|false
Pawel G's avatar
Pawel G committed
255 256
   *   Entity or FALSE if non-existent or if form operation is
   *   'delete'.
257 258 259 260 261
   */
  private function getFormEntity() {
    $form_object = $this->formState->getFormObject();
    if (!is_null($form_object)
      && method_exists($form_object, 'getEntity')
262
      && in_array($form_object->getOperation(), self::$allowedFormOperations)) {
263 264 265 266 267 268 269 270 271
      return $form_object->getEntity();
    }
    return FALSE;
  }

  /**
   * Gets new entity Id after entity creation.
   * To be used in an entity form submit.
   *
Pawel G's avatar
Pawel G committed
272
   * @return int
Pawel G's avatar
Pawel G committed
273
   *   Entity ID.
274
   */
Pawel G's avatar
Pawel G committed
275 276
  public function getFormEntityId() {
    return $this->formState->getFormObject()->getEntity()->id();
277 278 279 280 281 282
  }

  /**
   * Checks if simple_sitemap values have been changed after submitting the form.
   * To be used in an entity form submit.
   *
283 284
   * @param $form
   * @param $values
Pawel G's avatar
Pawel G committed
285
   *
286
   * @return bool
Pawel G's avatar
Pawel G committed
287
   *   TRUE if simple_sitemap form values have been altered by the user.
288
   */
289
  public function valuesChanged($form, $values) {
Pawel G's avatar
Pawel G committed
290
    foreach (self::$valuesToCheck as $field_name) {
291
      if (isset($values[$field_name]) && $values[$field_name] != $form['simple_sitemap'][$field_name]['#default_value']) {
292 293 294 295 296
        return TRUE;
      }
    }
    return FALSE;
  }
Pawel G's avatar
Pawel G committed
297 298 299 300

  /**
   * Gets the values needed to display the priority dropdown setting.
   *
301
   * @return array
Pawel G's avatar
Pawel G committed
302
   */
303
  public function getPrioritySelectValues() {
Pawel G's avatar
Pawel G committed
304
    $options = [];
Pawel G's avatar
Pawel G committed
305
    foreach (range(0, self::PRIORITY_HIGHEST) as $value) {
306
      $value = $this->formatPriority($value / self::PRIORITY_DIVIDER);
307
      $options[$value] = $value;
Pawel G's avatar
Pawel G committed
308 309 310
    }
    return $options;
  }
311

312 313 314 315 316
  /**
   * @param $priority
   * @return string
   */
  public function formatPriority($priority) {
Pawel G's avatar
Pawel G committed
317
    return number_format((float) $priority, 1, '.', '');
318 319
  }

320 321 322 323
  /**
   * @param $priority
   * @return bool
   */
324
  public static function isValidPriority($priority) {
325
    return is_numeric($priority) && $priority >= 0 && $priority <= 1;
326
  }
327
}