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

3
namespace Drupal\simple_sitemap\Form;
4

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

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

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

Pawel G's avatar
Pawel G committed
22 23 24
  /**
   * @var \Drupal\simple_sitemap\Simplesitemap
   */
25
  protected $generator;
Pawel G's avatar
Pawel G committed
26 27 28 29

  /**
   * @var \Drupal\simple_sitemap\EntityHelper
   */
30
  protected $entityHelper;
Pawel G's avatar
Pawel G committed
31 32 33 34

  /**
   * @var \Drupal\Core\Session\AccountProxyInterface
   */
35
  protected $currentUser;
Pawel G's avatar
Pawel G committed
36 37 38 39

  /**
   * @var \Drupal\Core\Form\FormState
   */
40
  protected $formState;
41

Pawel G's avatar
Pawel G committed
42 43 44
  /**
   * @var string|null
   */
Pawel G's avatar
Pawel G committed
45
  protected $entityCategory;
Pawel G's avatar
Pawel G committed
46 47 48 49

  /**
   * @var string
   */
50
  protected $entityTypeId;
Pawel G's avatar
Pawel G committed
51 52 53 54

  /**
   * @var string
   */
55
  protected $bundleName;
Pawel G's avatar
Pawel G committed
56 57 58 59

  /**
   * @var string
   */
60
  protected $instanceId;
61

62
  protected static $allowedFormOperations = [
63 64 65
    'default',
    'edit',
    'add',
Pawel G's avatar
Pawel G committed
66
    'register',
67 68
  ];

69
  protected static $valuesToCheck = [
70 71
    'simple_sitemap_index_content',
    'simple_sitemap_priority',
Pawel G's avatar
Pawel G committed
72
    'simple_sitemap_regenerate_now',
73
  ];
74

75
  /**
76 77 78 79
   * FormHelper constructor.
   * @param \Drupal\simple_sitemap\Simplesitemap $generator
   * @param \Drupal\simple_sitemap\EntityHelper $entityHelper
   * @param \Drupal\Core\Session\AccountProxyInterface $current_user
80
   */
Pawel G's avatar
Pawel G committed
81 82
  public function __construct(
    Simplesitemap $generator,
83
    EntityHelper $entityHelper,
Pawel G's avatar
Pawel G committed
84 85
    AccountProxyInterface $current_user
  ) {
86
    $this->generator = $generator;
87
    $this->entityHelper = $entityHelper;
88
    $this->currentUser = $current_user;
89
  }
Pawel G's avatar
Pawel G committed
90

91
  /**
Pawel G's avatar
Pawel G committed
92 93
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   * @return bool
94
   */
Pawel G's avatar
Pawel G committed
95
  public function processForm(FormStateInterface $form_state) {
Pawel G's avatar
Pawel G committed
96
    $this->formState = $form_state;
97
    $this->getEntityDataFromFormEntity();
Pawel G's avatar
Pawel G committed
98
    return $this->supports();
99 100
  }

101
  /**
Pawel G's avatar
Pawel G committed
102
   * @param string $entity_category
103 104
   * @return $this
   */
105 106
  public function setEntityCategory($entity_category) {
    $this->entityCategory = $entity_category;
107
    return $this;
108 109
  }

110
  /**
111
   * @return null|string
112
   */
113 114 115 116 117 118 119 120
  public function getEntityCategory() {
    return $this->entityCategory;
  }

  /**
 * @param string $entity_type_id
 * @return $this
 */
121 122
  public function setEntityTypeId($entity_type_id) {
    $this->entityTypeId = $entity_type_id;
123
    return $this;
124 125
  }

126 127 128 129 130 131 132
  /**
   * @return string
   */
  public function getEntityTypeId() {
    return $this->entityTypeId;
  }

133
  /**
Pawel G's avatar
Pawel G committed
134
   * @param string $bundle_name
135 136
   * @return $this
   */
137 138
  public function setBundleName($bundle_name) {
    $this->bundleName = $bundle_name;
139
    return $this;
140 141
  }

142 143 144 145 146 147 148
  /**
   * @return string
   */
  public function getBundleName() {
    return $this->bundleName;
  }

149
  /**
Pawel G's avatar
Pawel G committed
150
   * @param string $instance_id
151 152
   * @return $this
   */
153 154
  public function setInstanceId($instance_id) {
    $this->instanceId = $instance_id;
155
    return $this;
156 157
  }

158 159 160 161 162 163 164
  /**
   * @return string
   */
  public function getInstanceId() {
    return $this->instanceId;
  }

Pawel G's avatar
Pawel G committed
165
  /**
Pawel G's avatar
Pawel G committed
166
   * @return bool
Pawel G's avatar
Pawel G committed
167
   */
Pawel G's avatar
Pawel G committed
168
  protected function supports() {
Pawel G's avatar
Pawel G committed
169 170

    // Do not alter the form if user lacks certain permissions.
Pawel G's avatar
Pawel G committed
171
    if (!$this->currentUser->hasPermission('administer sitemap settings')) {
Pawel G's avatar
Pawel G committed
172
      return FALSE;
Pawel G's avatar
Pawel G committed
173
    }
Pawel G's avatar
Pawel G committed
174 175

    // Do not alter the form if it is irrelevant to sitemap generation.
176
    elseif (empty($this->getEntityCategory())) {
Pawel G's avatar
Pawel G committed
177
      return FALSE;
Pawel G's avatar
Pawel G committed
178
    }
Pawel G's avatar
Pawel G committed
179 180

    // Do not alter the form if entity is not enabled in sitemap settings.
181
    elseif (!$this->generator->entityTypeIsEnabled($this->getEntityTypeId())) {
Pawel G's avatar
Pawel G committed
182
      return FALSE;
Pawel G's avatar
Pawel G committed
183
    }
Pawel G's avatar
Pawel G committed
184 185 186

    // Do not alter the form, if sitemap is disabled for the entity type of this
    // entity instance.
187 188
    elseif ($this->getEntityCategory() == 'instance'
      && !$this->generator->bundleIsIndexed($this->getEntityTypeId(), $this->getBundleName())) {
Pawel G's avatar
Pawel G committed
189
      return FALSE;
Pawel G's avatar
Pawel G committed
190
    }
Pawel G's avatar
Pawel G committed
191 192

    return TRUE;
Pawel G's avatar
Pawel G committed
193 194
  }

195
  /**
Pawel G's avatar
Pawel G committed
196
   * @param array $form_fragment
197
   */
Pawel G's avatar
Pawel G committed
198
  public function displayRegenerateNow(&$form_fragment) {
Pawel G's avatar
Pawel G committed
199
    $form_fragment['simple_sitemap_regenerate_now'] = [
200
      '#type' => 'checkbox',
201 202
      '#title' => $this->t('Regenerate sitemap after hitting <em>Save</em>'),
      '#description' => $this->t('This setting will regenerate the whole sitemap including the above changes.'),
203
      '#default_value' => FALSE,
Pawel G's avatar
Pawel G committed
204
    ];
Pawel G's avatar
Pawel G committed
205
    if ($this->generator->getSetting('cron_generate')) {
206
      $form_fragment['simple_sitemap_regenerate_now']['#description'] .= '</br>' . $this->t('Otherwise the sitemap will be regenerated during a future cron run.');
207 208
    }
  }
209 210

  /**
211
   * @param array $form_fragment
212 213 214
   * @param bool $multiple
   * @return $this
   */
215
  public function displayEntitySettings(&$form_fragment, $multiple = FALSE) {
216
    $prefix = $multiple ? $this->getEntityTypeId() . '_' : '';
217

218 219 220
    if ($this->getEntityCategory() == 'instance') {
      $bundle_settings = $this->generator->getBundleSettings($this->getEntityTypeId(), $this->getBundleName());
      $settings = NULL !== $this->getInstanceId() ? $this->generator->getEntityInstanceSettings($this->getEntityTypeId(), $this->getInstanceId()) : $bundle_settings;
221
    }
222
    else {
223
      $settings = $this->generator->getBundleSettings($this->getEntityTypeId(), $this->getBundleName());
224 225 226
    }
    $index = isset($settings['index']) ? $settings['index'] : 0;
    $priority = isset($settings['priority']) ? $settings['priority'] : self::PRIORITY_DEFAULT;
227
    $bundle_name = !empty($this->getBundleName()) ? $this->getBundleName() : $this->t('undefined');
228 229 230 231 232 233

    if (!$multiple) {
      $form_fragment[$prefix . 'simple_sitemap_index_content'] = [
        '#type' => 'radios',
        '#default_value' => $index,
        '#options' => [
234 235
          0 => $this->getEntityCategory() == 'instance' ? $this->t('Do not index this @bundle entity', ['@bundle' => $bundle_name]) : $this->t('Do not index entities of this type'),
          1 => $this->getEntityCategory() == 'instance' ? $this->t('Index this @bundle entity', ['@bundle' => $bundle_name]) : $this->t('Index entities of this type'),
Pawel G's avatar
Pawel G committed
236
        ],
237
      ];
238
      if ($this->getEntityCategory() == 'instance' && isset($bundle_settings['index'])) {
239
        $form_fragment[$prefix . 'simple_sitemap_index_content']['#options'][$bundle_settings['index']] .= ' <em>(' . $this->t('Default') . ')</em>';
240 241 242
      }
    }

243
    if ($this->getEntityCategory() == 'instance') {
244
      $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
245 246
    }
    else {
247
      $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
248
    }
249 250
    $form_fragment[$prefix . 'simple_sitemap_priority'] = [
      '#type' => 'select',
251
      '#title' => $this->t('Priority'),
252 253
      '#description' => $priority_description,
      '#default_value' => $priority,
254
      '#options' => $this->getPrioritySelectValues(),
255
    ];
256
    if ($this->getEntityCategory() == 'instance' && isset($bundle_settings['priority'])) {
257
      $form_fragment[$prefix . 'simple_sitemap_priority']['#options'][$this->formatPriority($bundle_settings['priority'])] .= ' (' . $this->t('Default') . ')';
258
    }
Pawel G's avatar
Pawel G committed
259
    return $this;
260 261 262 263 264 265 266
  }

  /**
   * 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
267
   *   TRUE if this is a bundle or bundle instance form, FALSE otherwise.
268
   */
269
  protected function getEntityDataFromFormEntity() {
270 271
    $form_entity = $this->getFormEntity();
    if ($form_entity !== FALSE) {
272
      $entity_type_id = $form_entity->getEntityTypeId();
Pawel G's avatar
Pawel G committed
273
      $sitemap_entity_types = $this->entityHelper->getSupportedEntityTypes();
274
      if (isset($sitemap_entity_types[$entity_type_id])) {
275
        $this->setEntityCategory('instance');
276 277
      }
      else {
Pawel G's avatar
Pawel G committed
278 279 280 281 282
        /**
         * @var \Drupal\Core\Entity\EntityType $sitemap_entity_type
         */
        foreach ($sitemap_entity_types as $sitemap_entity_type) {
          if ($sitemap_entity_type->getBundleEntityType() == $entity_type_id) {
283
            $this->setEntityCategory('bundle');
284
            break;
285 286 287
          }
        }
      }
288

289
      // Menu fix.
290
      $this->setEntityCategory(NULL === $this->getEntityCategory() && $entity_type_id == 'menu' ? 'bundle' : $this->getEntityCategory());
291

292
      switch ($this->getEntityCategory()) {
293
        case 'bundle':
294 295 296
          $this->setEntityTypeId($this->entityHelper->getBundleEntityTypeId($form_entity));
          $this->setBundleName($form_entity->id());
          $this->setInstanceId(NULL);
297 298 299
          break;

        case 'instance':
300 301
          $this->setEntityTypeId($entity_type_id);
          $this->setBundleName($this->entityHelper->getEntityInstanceBundleName($form_entity));
Pawel G's avatar
Pawel G committed
302
          // New menu link's id is '' instead of NULL, hence checking for empty.
303
          $this->setInstanceId(!empty($form_entity->id()) ? $form_entity->id() : NULL);
304 305 306 307 308 309
          break;

        default:
          return FALSE;
      }
      return TRUE;
310 311 312 313 314 315 316
    }
    return FALSE;
  }

  /**
   * Gets the object entity of the form if available.
   *
Pawel G's avatar
Pawel G committed
317
   * @return \Drupal\Core\Entity\Entity|false
Pawel G's avatar
Pawel G committed
318 319
   *   Entity or FALSE if non-existent or if form operation is
   *   'delete'.
320
   */
321
  protected function getFormEntity() {
322
    $form_object = $this->formState->getFormObject();
323
    if (NULL !== $form_object
324
      && method_exists($form_object, 'getEntity')
325
      && in_array($form_object->getOperation(), self::$allowedFormOperations)) {
326 327 328 329 330 331 332 333 334
      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
335
   * @return int
Pawel G's avatar
Pawel G committed
336
   *   Entity ID.
337
   */
Pawel G's avatar
Pawel G committed
338 339
  public function getFormEntityId() {
    return $this->formState->getFormObject()->getEntity()->id();
340 341 342 343 344 345
  }

  /**
   * Checks if simple_sitemap values have been changed after submitting the form.
   * To be used in an entity form submit.
   *
346
   * @param $form
347
   * @param array $values
Pawel G's avatar
Pawel G committed
348
   *
349
   * @return bool
Pawel G's avatar
Pawel G committed
350
   *   TRUE if simple_sitemap form values have been altered by the user.
351
   */
352
  public function valuesChanged($form, array $values) {
Pawel G's avatar
Pawel G committed
353
    foreach (self::$valuesToCheck as $field_name) {
354
      if (isset($values[$field_name]) && $values[$field_name] != $form['simple_sitemap'][$field_name]['#default_value']) {
355 356 357 358 359
        return TRUE;
      }
    }
    return FALSE;
  }
Pawel G's avatar
Pawel G committed
360 361 362 363

  /**
   * Gets the values needed to display the priority dropdown setting.
   *
364
   * @return array
Pawel G's avatar
Pawel G committed
365
   */
366
  public function getPrioritySelectValues() {
Pawel G's avatar
Pawel G committed
367
    $options = [];
Pawel G's avatar
Pawel G committed
368
    foreach (range(0, self::PRIORITY_HIGHEST) as $value) {
369
      $value = $this->formatPriority($value / self::PRIORITY_DIVIDER);
370
      $options[$value] = $value;
Pawel G's avatar
Pawel G committed
371 372 373
    }
    return $options;
  }
374

375
  /**
376
   * @param string $priority
377 378 379
   * @return string
   */
  public function formatPriority($priority) {
Pawel G's avatar
Pawel G committed
380
    return number_format((float) $priority, 1, '.', '');
381 382
  }

383
  /**
384
   * @param string|int $priority
385 386
   * @return bool
   */
387
  public static function isValidPriority($priority) {
388
    return is_numeric($priority) && $priority >= 0 && $priority <= 1;
389
  }
390
}