090edd4a9d8f86f6a70b123699706c8167c839ef
[yaffs-website] / web / core / modules / path / src / Plugin / Field / FieldWidget / PathWidget.php
1 <?php
2
3 namespace Drupal\path\Plugin\Field\FieldWidget;
4
5 use Drupal\Core\Field\FieldItemListInterface;
6 use Drupal\Core\Field\WidgetBase;
7 use Drupal\Core\Form\FormStateInterface;
8 use Symfony\Component\Validator\ConstraintViolationInterface;
9
10 /**
11  * Plugin implementation of the 'path' widget.
12  *
13  * @FieldWidget(
14  *   id = "path",
15  *   label = @Translation("URL alias"),
16  *   field_types = {
17  *     "path"
18  *   }
19  * )
20  */
21 class PathWidget extends WidgetBase {
22
23   /**
24    * {@inheritdoc}
25    */
26   public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
27     $entity = $items->getEntity();
28
29     $element += [
30       '#element_validate' => [[get_class($this), 'validateFormElement']],
31     ];
32     $element['alias'] = [
33       '#type' => 'textfield',
34       '#title' => $element['#title'],
35       '#default_value' => $items[$delta]->alias,
36       '#required' => $element['#required'],
37       '#maxlength' => 255,
38       '#description' => $this->t('Specify an alternative path by which this data can be accessed. For example, type "/about" when writing an about page.'),
39     ];
40     $element['pid'] = [
41       '#type' => 'value',
42       '#value' => $items[$delta]->pid,
43     ];
44     $element['source'] = [
45       '#type' => 'value',
46       '#value' => !$entity->isNew() ? '/' . $entity->toUrl()->getInternalPath() : NULL,
47      ];
48     $element['langcode'] = [
49       '#type' => 'value',
50       '#value' => $items[$delta]->langcode,
51     ];
52
53     // If the advanced settings tabs-set is available (normally rendered in the
54     // second column on wide-resolutions), place the field as a details element
55     // in this tab-set.
56     if (isset($form['advanced'])) {
57       $element += [
58         '#type' => 'details',
59         '#title' => t('URL path settings'),
60         '#open' => !empty($items[$delta]->alias),
61         '#group' => 'advanced',
62         '#access' => $entity->get('path')->access('edit'),
63         '#attributes' => [
64           'class' => ['path-form'],
65         ],
66         '#attached' => [
67           'library' => ['path/drupal.path'],
68         ],
69       ];
70       $element['#weight'] = 30;
71     }
72
73     return $element;
74   }
75
76   /**
77    * Form element validation handler for URL alias form element.
78    *
79    * @param array $element
80    *   The form element.
81    * @param \Drupal\Core\Form\FormStateInterface $form_state
82    *   The form state.
83    */
84   public static function validateFormElement(array &$element, FormStateInterface $form_state) {
85     // Trim the submitted value of whitespace and slashes.
86     $alias = rtrim(trim($element['alias']['#value']), " \\/");
87     if (!empty($alias)) {
88       $form_state->setValueForElement($element['alias'], $alias);
89
90       // Validate that the submitted alias does not exist yet.
91       $is_exists = \Drupal::service('path.alias_storage')->aliasExists($alias, $element['langcode']['#value'], $element['source']['#value']);
92       if ($is_exists) {
93         $form_state->setError($element['alias'], t('The alias is already in use.'));
94       }
95     }
96
97     if ($alias && $alias[0] !== '/') {
98       $form_state->setError($element['alias'], t('The alias needs to start with a slash.'));
99     }
100   }
101
102   /**
103    * {@inheritdoc}
104    */
105   public function errorElement(array $element, ConstraintViolationInterface $violation, array $form, FormStateInterface $form_state) {
106     return $element['alias'];
107   }
108
109 }