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

3
namespace Drupal\simple_sitemap\Form;
4

5 6
use Drupal\Core\StringTranslation\StringTranslationTrait;

7
/**
gbyte.co's avatar
gbyte.co committed
8 9
 * Class FormHelper.
 *
10
 * @package Drupal\simple_sitemap\Form
11
 */
12
class FormHelper {
13
  use StringTranslationTrait;
14

gbyte.co's avatar
gbyte.co committed
15 16 17 18
  const PRIORITY_DEFAULT = 0.5;
  const PRIORITY_HIGHEST = 10;
  const PRIORITY_DIVIDER = 10;

19
  private $generator;
20
  private $currentUser;
21 22 23 24
  private $formState;

  public $alteringForm = TRUE;
  public $entityCategory = NULL;
25 26
  public $entityTypeId;
  public $bundleName;
27
  public $instanceId;
28

29 30 31 32
  private static $allowedFormOperations = [
    'default',
    'edit',
    'add',
gbyte.co's avatar
gbyte.co committed
33
    'register',
34 35 36 37 38
  ];

  private static $valuesToCheck = [
    'simple_sitemap_index_content',
    'simple_sitemap_priority',
gbyte.co's avatar
gbyte.co committed
39
    'simple_sitemap_regenerate_now',
40
  ];
41

42 43
  /**
   * Form constructor.
44 45 46
   *
   * @param $generator
   * @param $current_user
47
   */
48
  public function __construct($generator, $current_user) {
49
    $this->generator = $generator;
50
    $this->currentUser = $current_user;
51
  }
52

53 54 55 56
  /**
   * @param $form_state
   * @return $this
   */
57
  public function processForm($form_state) {
58
    $this->formState = $form_state;
gbyte.co's avatar
gbyte.co committed
59
    if (!is_null($this->formState)) {
60
      $this->getEntityDataFromFormEntity();
gbyte.co's avatar
gbyte.co committed
61 62
      $this->assertAlteringForm();
    }
63
    return $this;
64 65
  }

66 67 68 69
  /**
   * @param $entity_category
   * @return $this
   */
70 71
  public function setEntityCategory($entity_category) {
    $this->entityCategory = $entity_category;
72
    return $this;
73 74
  }

75 76 77 78
  /**
   * @param $entity_type_id
   * @return $this
   */
79 80
  public function setEntityTypeId($entity_type_id) {
    $this->entityTypeId = $entity_type_id;
81
    return $this;
82 83
  }

84 85 86 87
  /**
   * @param $bundle_name
   * @return $this
   */
88 89
  public function setBundleName($bundle_name) {
    $this->bundleName = $bundle_name;
90
    return $this;
91 92
  }

93 94 95 96
  /**
   * @param $instance_id
   * @return $this
   */
97 98
  public function setInstanceId($instance_id) {
    $this->instanceId = $instance_id;
99
    return $this;
100 101
  }

gbyte.co's avatar
gbyte.co committed
102 103 104
  /**
   *
   */
gbyte.co's avatar
gbyte.co committed
105 106 107
  private function assertAlteringForm() {

    // Do not alter the form if user lacks certain permissions.
gbyte.co's avatar
gbyte.co committed
108
    if (!$this->currentUser->hasPermission('administer sitemap settings')) {
gbyte.co's avatar
gbyte.co committed
109
      $this->alteringForm = FALSE;
gbyte.co's avatar
gbyte.co committed
110
    }
gbyte.co's avatar
gbyte.co committed
111 112

    // Do not alter the form if it is irrelevant to sitemap generation.
gbyte.co's avatar
gbyte.co committed
113
    elseif (empty($this->entityCategory)) {
gbyte.co's avatar
gbyte.co committed
114
      $this->alteringForm = FALSE;
gbyte.co's avatar
gbyte.co committed
115
    }
gbyte.co's avatar
gbyte.co committed
116 117

    // Do not alter the form if entity is not enabled in sitemap settings.
gbyte.co's avatar
gbyte.co committed
118
    elseif (!$this->generator->entityTypeIsEnabled($this->entityTypeId)) {
gbyte.co's avatar
gbyte.co committed
119
      $this->alteringForm = FALSE;
gbyte.co's avatar
gbyte.co committed
120
    }
gbyte.co's avatar
gbyte.co committed
121 122 123 124

    // Do not alter the form, if sitemap is disabled for the entity type of this
    // entity instance.
    elseif ($this->entityCategory == 'instance'
gbyte.co's avatar
gbyte.co committed
125
      && !$this->generator->bundleIsIndexed($this->entityTypeId, $this->bundleName)) {
gbyte.co's avatar
gbyte.co committed
126
      $this->alteringForm = FALSE;
gbyte.co's avatar
gbyte.co committed
127
    }
gbyte.co's avatar
gbyte.co committed
128 129
  }

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

  /**
   * @param $form_fragment
   * @param bool $multiple
   * @return $this
   */
gbyte.co's avatar
gbyte.co committed
150
  public function displayEntitySettings(&$form_fragment, $multiple = FALSE) {
151
    $prefix = $multiple ? $this->entityTypeId . '_' : '';
152

153
    if ($this->entityCategory == 'instance') {
154 155
      $bundle_settings = $this->generator->getBundleSettings($this->entityTypeId, $this->bundleName);
      $settings = !is_null($this->instanceId) ? $this->generator->getEntityInstanceSettings($this->entityTypeId, $this->instanceId) : $bundle_settings;
156
    }
157
    else {
158
      $settings = $this->generator->getBundleSettings($this->entityTypeId, $this->bundleName);
159 160 161
    }
    $index = isset($settings['index']) ? $settings['index'] : 0;
    $priority = isset($settings['priority']) ? $settings['priority'] : self::PRIORITY_DEFAULT;
162
    $bundle_name = !empty($this->bundleName) ? $this->bundleName : $this->t('undefined');
163 164 165 166 167 168

    if (!$multiple) {
      $form_fragment[$prefix . 'simple_sitemap_index_content'] = [
        '#type' => 'radios',
        '#default_value' => $index,
        '#options' => [
169 170
          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'),
gbyte.co's avatar
gbyte.co committed
171
        ],
172
      ];
173
      if ($this->entityCategory == 'instance' && isset($bundle_settings['index'])) {
174
        $form_fragment[$prefix . 'simple_sitemap_index_content']['#options'][$bundle_settings['index']] .= ' <em>(' . $this->t('Default') . ')</em>';
175 176 177
      }
    }

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

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

221
      // Menu fix.
222
      $this->entityCategory = is_null($this->entityCategory) && $entity_type_id == 'menu' ? 'bundle' : $this->entityCategory;
223 224 225

      switch ($this->entityCategory) {
        case 'bundle':
226
          $this->entityTypeId = $this->generator->getBundleEntityTypeId($form_entity);
227 228 229 230 231
          $this->bundleName = $form_entity->id();
          $this->instanceId = NULL;
          break;

        case 'instance':
232
          $this->entityTypeId = $entity_type_id;
233
          $this->bundleName = $this->generator->getEntityInstanceBundleName($form_entity);
gbyte.co's avatar
gbyte.co committed
234 235
          // New menu link's id is '' instead of NULL, hence checking for empty.
          $this->instanceId = !empty($form_entity->id()) ? $form_entity->id() : NULL;
236 237 238 239 240 241
          break;

        default:
          return FALSE;
      }
      return TRUE;
242 243 244 245 246 247 248
    }
    return FALSE;
  }

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

  /**
   * Gets new entity Id after entity creation.
   * To be used in an entity form submit.
   *
gbyte.co's avatar
gbyte.co committed
267
   * @return int
gbyte.co's avatar
gbyte.co committed
268
   *   Entity ID.
269
   */
270 271
  public function getFormEntityId() {
    return $this->formState->getFormObject()->getEntity()->id();
272 273 274 275 276 277
  }

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

  /**
   * Gets the values needed to display the priority dropdown setting.
   *
296
   * @return array
gbyte.co's avatar
gbyte.co committed
297
   */
298
  public function getPrioritySelectValues() {
299
    $options = [];
gbyte.co's avatar
gbyte.co committed
300
    foreach (range(0, self::PRIORITY_HIGHEST) as $value) {
301
      $value = $this->formatPriority($value / self::PRIORITY_DIVIDER);
302
      $options[$value] = $value;
gbyte.co's avatar
gbyte.co committed
303 304 305
    }
    return $options;
  }
306

307 308 309 310 311
  /**
   * @param $priority
   * @return string
   */
  public function formatPriority($priority) {
gbyte.co's avatar
gbyte.co committed
312
    return number_format((float) $priority, 1, '.', '');
313 314
  }

315 316 317 318
  /**
   * @param $priority
   * @return bool
   */
319 320 321
  public static function isValidPriority($priority) {
    return !is_numeric($priority) || $priority < 0 || $priority > 1 ? FALSE : TRUE;
  }
gbyte.co's avatar
gbyte.co committed
322

323
}