3fc315761674b7fd18b37004285545aae4393eb1
[yaffs-website] / web / core / modules / datetime / src / Plugin / Field / FieldFormatter / DateTimeTimeAgoFormatter.php
1 <?php
2
3 namespace Drupal\datetime\Plugin\Field\FieldFormatter;
4
5 use Drupal\Component\Utility\SafeMarkup;
6 use Drupal\Core\Cache\CacheableMetadata;
7 use Drupal\Core\Datetime\DateFormatterInterface;
8 use Drupal\Core\Datetime\DrupalDateTime;
9 use Drupal\Core\Field\FieldDefinitionInterface;
10 use Drupal\Core\Field\FieldItemListInterface;
11 use Drupal\Core\Field\FormatterBase;
12 use Drupal\Core\Form\FormStateInterface;
13 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
14 use Symfony\Component\HttpFoundation\Request;
15 use Symfony\Component\DependencyInjection\ContainerInterface;
16
17 /**
18  * Plugin implementation of the 'Time ago' formatter for 'datetime' fields.
19  *
20  * @FieldFormatter(
21  *   id = "datetime_time_ago",
22  *   label = @Translation("Time ago"),
23  *   field_types = {
24  *     "datetime"
25  *   }
26  * )
27  */
28 class DateTimeTimeAgoFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
29
30   /**
31    * The date formatter service.
32    *
33    * @var \Drupal\Core\Datetime\DateFormatterInterface
34    */
35   protected $dateFormatter;
36
37   /**
38    * The current Request object.
39    *
40    * @var \Symfony\Component\HttpFoundation\Request
41    */
42   protected $request;
43
44   /**
45    * Constructs a DateTimeTimeAgoFormatter object.
46    *
47    * @param string $plugin_id
48    *   The plugin_id for the formatter.
49    * @param mixed $plugin_definition
50    *   The plugin implementation definition.
51    * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
52    *   The definition of the field to which the formatter is associated.
53    * @param array $settings
54    *   The formatter settings.
55    * @param string $label
56    *   The formatter label display setting.
57    * @param string $view_mode
58    *   The view mode.
59    * @param array $third_party_settings
60    *   Third party settings.
61    * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
62    *   The date formatter service.
63    * @param \Symfony\Component\HttpFoundation\Request $request
64    *   The current request.
65    */
66   public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatterInterface $date_formatter, Request $request) {
67     parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
68
69     $this->dateFormatter = $date_formatter;
70     $this->request = $request;
71   }
72
73   /**
74    * {@inheritdoc}
75    */
76   public static function defaultSettings() {
77     $settings = [
78       'future_format' => '@interval hence',
79       'past_format' => '@interval ago',
80       'granularity' => 2,
81     ] + parent::defaultSettings();
82
83     return $settings;
84   }
85
86   /**
87    * {@inheritdoc}
88    */
89   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
90     return new static(
91       $plugin_id,
92       $plugin_definition,
93       $configuration['field_definition'],
94       $configuration['settings'],
95       $configuration['label'],
96       $configuration['view_mode'],
97       $configuration['third_party_settings'],
98       $container->get('date.formatter'),
99       $container->get('request_stack')->getCurrentRequest()
100     );
101   }
102
103   /**
104    * {@inheritdoc}
105    */
106   public function viewElements(FieldItemListInterface $items, $langcode) {
107     $elements = [];
108
109     foreach ($items as $delta => $item) {
110       $date = $item->date;
111       $output = [];
112       if (!empty($item->date)) {
113         if ($this->getFieldSetting('datetime_type') == 'date') {
114           // A date without time will pick up the current time, use the default.
115           datetime_date_default_time($date);
116         }
117         $output = $this->formatDate($date);
118       }
119       $elements[$delta] = $output;
120     }
121
122     return $elements;
123   }
124
125   /**
126    * {@inheritdoc}
127    */
128   public function settingsForm(array $form, FormStateInterface $form_state) {
129     $form = parent::settingsForm($form, $form_state);
130
131     $form['future_format'] = [
132       '#type' => 'textfield',
133       '#title' => $this->t('Future format'),
134       '#default_value' => $this->getSetting('future_format'),
135       '#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
136     ];
137
138     $form['past_format'] = [
139       '#type' => 'textfield',
140       '#title' => $this->t('Past format'),
141       '#default_value' => $this->getSetting('past_format'),
142       '#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
143     ];
144
145     $form['granularity'] = [
146       '#type' => 'number',
147       '#title' => $this->t('Granularity'),
148       '#default_value' => $this->getSetting('granularity'),
149       '#description' => $this->t('How many time units should be shown in the formatted output.'),
150     ];
151
152     return $form;
153   }
154
155   /**
156    * {@inheritdoc}
157    */
158   public function settingsSummary() {
159     $summary = parent::settingsSummary();
160
161     $future_date = new DrupalDateTime('1 year 1 month 1 week 1 day 1 hour 1 minute');
162     $past_date = new DrupalDateTime('-1 year -1 month -1 week -1 day -1 hour -1 minute');
163     $summary[] = t('Future date: %display', ['%display' => $this->formatDate($future_date)]);
164     $summary[] = t('Past date: %display', ['%display' => $this->formatDate($past_date)]);
165
166     return $summary;
167   }
168
169   /**
170    * Formats a date/time as a time interval.
171    *
172    * @param \Drupal\Core\Datetime\DrupalDateTime|object $date
173    *   A date/time object.
174    *
175    * @return array
176    *   The formatted date/time string using the past or future format setting.
177    */
178   protected function formatDate(DrupalDateTime $date) {
179     $granularity = $this->getSetting('granularity');
180     $timestamp = $date->getTimestamp();
181     $options = [
182       'granularity' => $granularity,
183       'return_as_object' => TRUE,
184     ];
185
186     if ($this->request->server->get('REQUEST_TIME') > $timestamp) {
187       $result = $this->dateFormatter->formatTimeDiffSince($timestamp, $options);
188       $build = [
189         '#markup' => SafeMarkup::format($this->getSetting('past_format'), ['@interval' => $result->getString()]),
190       ];
191     }
192     else {
193       $result = $this->dateFormatter->formatTimeDiffUntil($timestamp, $options);
194       $build = [
195         '#markup' => SafeMarkup::format($this->getSetting('future_format'), ['@interval' => $result->getString()]),
196       ];
197     }
198     CacheableMetadata::createFromObject($result)->applyTo($build);
199     return $build;
200   }
201
202 }