Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / telephone / src / Plugin / Field / FieldFormatter / TelephoneLinkFormatter.php
1 <?php
2
3 namespace Drupal\telephone\Plugin\Field\FieldFormatter;
4
5 use Drupal\Core\Field\FormatterBase;
6 use Drupal\Core\Field\FieldItemListInterface;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\Core\Url;
9
10 /**
11  * Plugin implementation of the 'telephone_link' formatter.
12  *
13  * @FieldFormatter(
14  *   id = "telephone_link",
15  *   label = @Translation("Telephone link"),
16  *   field_types = {
17  *     "telephone"
18  *   }
19  * )
20  */
21 class TelephoneLinkFormatter extends FormatterBase {
22
23   /**
24    * {@inheritdoc}
25    */
26   public static function defaultSettings() {
27     return [
28       'title' => '',
29     ] + parent::defaultSettings();
30   }
31
32   /**
33    * {@inheritdoc}
34    */
35   public function settingsForm(array $form, FormStateInterface $form_state) {
36     $elements['title'] = [
37       '#type' => 'textfield',
38       '#title' => t('Title to replace basic numeric telephone number display'),
39       '#default_value' => $this->getSetting('title'),
40     ];
41
42     return $elements;
43   }
44
45   /**
46    * {@inheritdoc}
47    */
48   public function settingsSummary() {
49     $summary = [];
50     $settings = $this->getSettings();
51
52     if (!empty($settings['title'])) {
53       $summary[] = t('Link using text: @title', ['@title' => $settings['title']]);
54     }
55     else {
56       $summary[] = t('Link using provided telephone number.');
57     }
58
59     return $summary;
60   }
61
62   /**
63    * {@inheritdoc}
64    */
65   public function viewElements(FieldItemListInterface $items, $langcode) {
66     $element = [];
67     $title_setting = $this->getSetting('title');
68
69     foreach ($items as $delta => $item) {
70       // If the telephone number is 5 or less digits, parse_url() will think
71       // it's a port number rather than a phone number which causes the link
72       // formatter to throw an InvalidArgumentException. Avoid this by inserting
73       // a dash (-) after the first digit - RFC 3966 defines the dash as a
74       // visual separator character and so will be removed before the phone
75       // number is used. See https://bugs.php.net/bug.php?id=70588 for more.
76       // While the bug states this only applies to numbers <= 65535, a 5 digit
77       // number greater than 65535 will cause parse_url() to return FALSE so
78       // we need the work around on any 5 digit (or less) number.
79       // First we strip whitespace so we're counting actual digits.
80       $phone_number = preg_replace('/\s+/', '', $item->value);
81       if (strlen($phone_number) <= 5) {
82         $phone_number = substr_replace($phone_number, '-', 1, 0);
83       }
84
85       // Render each element as link.
86       $element[$delta] = [
87         '#type' => 'link',
88         // Use custom title if available, otherwise use the telephone number
89         // itself as title.
90         '#title' => $title_setting ?: $item->value,
91         // Prepend 'tel:' to the telephone number.
92         '#url' => Url::fromUri('tel:' . rawurlencode($phone_number)),
93         '#options' => ['external' => TRUE],
94       ];
95
96       if (!empty($item->_attributes)) {
97         $element[$delta]['#options'] += ['attributes' => []];
98         $element[$delta]['#options']['attributes'] += $item->_attributes;
99         // Unset field item attributes since they have been included in the
100         // formatter output and should not be rendered in the field template.
101         unset($item->_attributes);
102       }
103     }
104
105     return $element;
106   }
107
108 }