Interim commit.
[yaffs-website] / web / modules / contrib / simple_sitemap / src / Form / FormHelper.php
1 <?php
2
3 namespace Drupal\simple_sitemap\Form;
4
5 use Drupal\Core\StringTranslation\StringTranslationTrait;
6 use Drupal\simple_sitemap\EntityHelper;
7 use Drupal\simple_sitemap\Simplesitemap;
8 use Drupal\Core\Session\AccountProxyInterface;
9 use Drupal\Core\Form\FormState;
10
11 /**
12  * Class FormHelper
13  * @package Drupal\simple_sitemap\Form
14  */
15 class FormHelper {
16   use StringTranslationTrait;
17
18   const PRIORITY_DEFAULT = 0.5;
19   const PRIORITY_HIGHEST = 10;
20   const PRIORITY_DIVIDER = 10;
21
22   /**
23    * @var \Drupal\simple_sitemap\Simplesitemap
24    */
25   protected $generator;
26
27   /**
28    * @var \Drupal\simple_sitemap\EntityHelper
29    */
30   protected $entityHelper;
31
32   /**
33    * @var \Drupal\Core\Session\AccountProxyInterface
34    */
35   protected $currentUser;
36
37   /**
38    * @var \Drupal\Core\Form\FormState
39    */
40   protected $formState;
41
42   /**
43    * @var bool
44    */
45   protected $alteringForm = TRUE;
46
47   /**
48    * @var string|null
49    */
50   protected $entityCategory = NULL;
51
52   /**
53    * @var string
54    */
55   protected $entityTypeId;
56
57   /**
58    * @var string
59    */
60   protected $bundleName;
61
62   /**
63    * @var string
64    */
65   protected $instanceId;
66
67   protected static $allowedFormOperations = [
68     'default',
69     'edit',
70     'add',
71     'register',
72   ];
73
74   protected static $valuesToCheck = [
75     'simple_sitemap_index_content',
76     'simple_sitemap_priority',
77     'simple_sitemap_regenerate_now',
78   ];
79
80   /**
81    * FormHelper constructor.
82    * @param \Drupal\simple_sitemap\Simplesitemap $generator
83    * @param \Drupal\simple_sitemap\EntityHelper $entityHelper
84    * @param \Drupal\Core\Session\AccountProxyInterface $current_user
85    */
86   public function __construct(
87     Simplesitemap $generator,
88     EntityHelper $entityHelper,
89     AccountProxyInterface $current_user
90   ) {
91     $this->generator = $generator;
92     $this->entityHelper = $entityHelper;
93     $this->currentUser = $current_user;
94   }
95
96   /**
97    * @param \Drupal\Core\Form\FormState $form_state
98    * @return $this
99    */
100   public function processForm(FormState $form_state) {
101     $this->formState = $form_state;
102     $this->getEntityDataFromFormEntity();
103     $this->assertAlteringForm();
104     return $this;
105   }
106
107   /**
108    * @return bool
109    */
110   public function alteringForm() {
111     return $this->alteringForm;
112   }
113
114   /**
115    * @param string $entity_category
116    * @return $this
117    */
118   public function setEntityCategory($entity_category) {
119     $this->entityCategory = $entity_category;
120     return $this;
121   }
122
123   /**
124    * @return null|string
125    */
126   public function getEntityCategory() {
127     return $this->entityCategory;
128   }
129
130   /**
131  * @param string $entity_type_id
132  * @return $this
133  */
134   public function setEntityTypeId($entity_type_id) {
135     $this->entityTypeId = $entity_type_id;
136     return $this;
137   }
138
139   /**
140    * @return string
141    */
142   public function getEntityTypeId() {
143     return $this->entityTypeId;
144   }
145
146   /**
147    * @param string $bundle_name
148    * @return $this
149    */
150   public function setBundleName($bundle_name) {
151     $this->bundleName = $bundle_name;
152     return $this;
153   }
154
155   /**
156    * @return string
157    */
158   public function getBundleName() {
159     return $this->bundleName;
160   }
161
162   /**
163    * @param string $instance_id
164    * @return $this
165    */
166   public function setInstanceId($instance_id) {
167     $this->instanceId = $instance_id;
168     return $this;
169   }
170
171   /**
172    * @return string
173    */
174   public function getInstanceId() {
175     return $this->instanceId;
176   }
177
178   /**
179    *
180    */
181   protected function assertAlteringForm() {
182
183     // Do not alter the form if user lacks certain permissions.
184     if (!$this->currentUser->hasPermission('administer sitemap settings')) {
185       $this->alteringForm = FALSE;
186     }
187
188     // Do not alter the form if it is irrelevant to sitemap generation.
189     elseif (empty($this->getEntityCategory())) {
190       $this->alteringForm = FALSE;
191     }
192
193     // Do not alter the form if entity is not enabled in sitemap settings.
194     elseif (!$this->generator->entityTypeIsEnabled($this->getEntityTypeId())) {
195       $this->alteringForm = FALSE;
196     }
197
198     // Do not alter the form, if sitemap is disabled for the entity type of this
199     // entity instance.
200     elseif ($this->getEntityCategory() == 'instance'
201       && !$this->generator->bundleIsIndexed($this->getEntityTypeId(), $this->getBundleName())) {
202       $this->alteringForm = FALSE;
203     }
204   }
205
206   /**
207    * @param array $form_fragment
208    */
209   public function displayRegenerateNow(&$form_fragment) {
210     $form_fragment['simple_sitemap_regenerate_now'] = [
211       '#type' => 'checkbox',
212       '#title' => $this->t('Regenerate sitemap after hitting <em>Save</em>'),
213       '#description' => $this->t('This setting will regenerate the whole sitemap including the above changes.'),
214       '#default_value' => FALSE,
215     ];
216     if ($this->generator->getSetting('cron_generate')) {
217       $form_fragment['simple_sitemap_regenerate_now']['#description'] .= '</br>' . $this->t('Otherwise the sitemap will be regenerated on the next cron run.');
218     }
219   }
220
221   /**
222    * @param array $form_fragment
223    * @param bool $multiple
224    * @return $this
225    */
226   public function displayEntitySettings(&$form_fragment, $multiple = FALSE) {
227     $prefix = $multiple ? $this->getEntityTypeId() . '_' : '';
228
229     if ($this->getEntityCategory() == 'instance') {
230       $bundle_settings = $this->generator->getBundleSettings($this->getEntityTypeId(), $this->getBundleName());
231       $settings = NULL !== $this->getInstanceId() ? $this->generator->getEntityInstanceSettings($this->getEntityTypeId(), $this->getInstanceId()) : $bundle_settings;
232     }
233     else {
234       $settings = $this->generator->getBundleSettings($this->getEntityTypeId(), $this->getBundleName());
235     }
236     $index = isset($settings['index']) ? $settings['index'] : 0;
237     $priority = isset($settings['priority']) ? $settings['priority'] : self::PRIORITY_DEFAULT;
238     $bundle_name = !empty($this->getBundleName()) ? $this->getBundleName() : $this->t('undefined');
239
240     if (!$multiple) {
241       $form_fragment[$prefix . 'simple_sitemap_index_content'] = [
242         '#type' => 'radios',
243         '#default_value' => $index,
244         '#options' => [
245           0 => $this->getEntityCategory() == 'instance' ? $this->t('Do not index this @bundle entity', ['@bundle' => $bundle_name]) : $this->t('Do not index entities of this type'),
246           1 => $this->getEntityCategory() == 'instance' ? $this->t('Index this @bundle entity', ['@bundle' => $bundle_name]) : $this->t('Index entities of this type'),
247         ],
248       ];
249       if ($this->getEntityCategory() == 'instance' && isset($bundle_settings['index'])) {
250         $form_fragment[$prefix . 'simple_sitemap_index_content']['#options'][$bundle_settings['index']] .= ' <em>(' . $this->t('Default') . ')</em>';
251       }
252     }
253
254     if ($this->getEntityCategory() == 'instance') {
255       $priority_description = $this->t('The priority this @bundle entity will have in the eyes of search engine bots.', ['@bundle' => $bundle_name]);
256     }
257     else {
258       $priority_description = $this->t('The priority entities of this type will have in the eyes of search engine bots.');
259     }
260     $form_fragment[$prefix . 'simple_sitemap_priority'] = [
261       '#type' => 'select',
262       '#title' => $this->t('Priority'),
263       '#description' => $priority_description,
264       '#default_value' => $priority,
265       '#options' => $this->getPrioritySelectValues(),
266     ];
267     if ($this->getEntityCategory() == 'instance' && isset($bundle_settings['priority'])) {
268       $form_fragment[$prefix . 'simple_sitemap_priority']['#options'][$this->formatPriority($bundle_settings['priority'])] .= ' (' . $this->t('Default') . ')';
269     }
270     return $this;
271   }
272
273   /**
274    * Checks if this particular form is a bundle form, or a bundle instance form
275    * and gathers sitemap settings from the database.
276    *
277    * @return bool
278    *   TRUE if this is a bundle or bundle instance form, FALSE otherwise.
279    */
280   protected function getEntityDataFromFormEntity() {
281     $form_entity = $this->getFormEntity();
282     if ($form_entity !== FALSE) {
283       $entity_type_id = $form_entity->getEntityTypeId();
284       $sitemap_entity_types = $this->entityHelper->getSitemapEntityTypes();
285       if (isset($sitemap_entity_types[$entity_type_id])) {
286         $this->setEntityCategory('instance');
287       }
288       else {
289         foreach ($sitemap_entity_types as $sitemap_entity) {
290           if ($sitemap_entity->getBundleEntityType() == $entity_type_id) {
291             $this->setEntityCategory('bundle');
292             break;
293           }
294         }
295       }
296
297       // Menu fix.
298       $this->setEntityCategory(NULL === $this->getEntityCategory() && $entity_type_id == 'menu' ? 'bundle' : $this->getEntityCategory());
299
300       switch ($this->getEntityCategory()) {
301         case 'bundle':
302           $this->setEntityTypeId($this->entityHelper->getBundleEntityTypeId($form_entity));
303           $this->setBundleName($form_entity->id());
304           $this->setInstanceId(NULL);
305           break;
306
307         case 'instance':
308           $this->setEntityTypeId($entity_type_id);
309           $this->setBundleName($this->entityHelper->getEntityInstanceBundleName($form_entity));
310           // New menu link's id is '' instead of NULL, hence checking for empty.
311           $this->setInstanceId(!empty($form_entity->id()) ? $form_entity->id() : NULL);
312           break;
313
314         default:
315           return FALSE;
316       }
317       return TRUE;
318     }
319     return FALSE;
320   }
321
322   /**
323    * Gets the object entity of the form if available.
324    *
325    * @return object|false
326    *   Entity or FALSE if non-existent or if form operation is
327    *   'delete'.
328    */
329   protected function getFormEntity() {
330     $form_object = $this->formState->getFormObject();
331     if (NULL !== $form_object
332       && method_exists($form_object, 'getEntity')
333       && in_array($form_object->getOperation(), self::$allowedFormOperations)) {
334       return $form_object->getEntity();
335     }
336     return FALSE;
337   }
338
339   /**
340    * Gets new entity Id after entity creation.
341    * To be used in an entity form submit.
342    *
343    * @return int
344    *   Entity ID.
345    */
346   public function getFormEntityId() {
347     return $this->formState->getFormObject()->getEntity()->id();
348   }
349
350   /**
351    * Checks if simple_sitemap values have been changed after submitting the form.
352    * To be used in an entity form submit.
353    *
354    * @param $form
355    * @param array $values
356    *
357    * @return bool
358    *   TRUE if simple_sitemap form values have been altered by the user.
359    */
360   public function valuesChanged($form, array $values) {
361     foreach (self::$valuesToCheck as $field_name) {
362       if (isset($values[$field_name]) && $values[$field_name] != $form['simple_sitemap'][$field_name]['#default_value']) {
363         return TRUE;
364       }
365     }
366     return FALSE;
367   }
368
369   /**
370    * Gets the values needed to display the priority dropdown setting.
371    *
372    * @return array
373    */
374   public function getPrioritySelectValues() {
375     $options = [];
376     foreach (range(0, self::PRIORITY_HIGHEST) as $value) {
377       $value = $this->formatPriority($value / self::PRIORITY_DIVIDER);
378       $options[$value] = $value;
379     }
380     return $options;
381   }
382
383   /**
384    * @param string $priority
385    * @return string
386    */
387   public function formatPriority($priority) {
388     return number_format((float) $priority, 1, '.', '');
389   }
390
391   /**
392    * @param string|int $priority
393    * @return bool
394    */
395   public static function isValidPriority($priority) {
396     return is_numeric($priority) && $priority >= 0 && $priority <= 1;
397   }
398 }