782e1b85472c246540d9970ea1478c7b28795c5a
[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         $output = $this->formatDate($date);
114       }
115       $elements[$delta] = $output;
116     }
117
118     return $elements;
119   }
120
121   /**
122    * {@inheritdoc}
123    */
124   public function settingsForm(array $form, FormStateInterface $form_state) {
125     $form = parent::settingsForm($form, $form_state);
126
127     $form['future_format'] = [
128       '#type' => 'textfield',
129       '#title' => $this->t('Future format'),
130       '#default_value' => $this->getSetting('future_format'),
131       '#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
132     ];
133
134     $form['past_format'] = [
135       '#type' => 'textfield',
136       '#title' => $this->t('Past format'),
137       '#default_value' => $this->getSetting('past_format'),
138       '#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
139     ];
140
141     $form['granularity'] = [
142       '#type' => 'number',
143       '#title' => $this->t('Granularity'),
144       '#default_value' => $this->getSetting('granularity'),
145       '#description' => $this->t('How many time units should be shown in the formatted output.'),
146     ];
147
148     return $form;
149   }
150
151   /**
152    * {@inheritdoc}
153    */
154   public function settingsSummary() {
155     $summary = parent::settingsSummary();
156
157     $future_date = new DrupalDateTime('1 year 1 month 1 week 1 day 1 hour 1 minute');
158     $past_date = new DrupalDateTime('-1 year -1 month -1 week -1 day -1 hour -1 minute');
159     $summary[] = t('Future date: %display', ['%display' => $this->formatDate($future_date)]);
160     $summary[] = t('Past date: %display', ['%display' => $this->formatDate($past_date)]);
161
162     return $summary;
163   }
164
165   /**
166    * Formats a date/time as a time interval.
167    *
168    * @param \Drupal\Core\Datetime\DrupalDateTime|object $date
169    *   A date/time object.
170    *
171    * @return array
172    *   The formatted date/time string using the past or future format setting.
173    */
174   protected function formatDate(DrupalDateTime $date) {
175     $granularity = $this->getSetting('granularity');
176     $timestamp = $date->getTimestamp();
177     $options = [
178       'granularity' => $granularity,
179       'return_as_object' => TRUE,
180     ];
181
182     if ($this->request->server->get('REQUEST_TIME') > $timestamp) {
183       $result = $this->dateFormatter->formatTimeDiffSince($timestamp, $options);
184       $build = [
185         '#markup' => SafeMarkup::format($this->getSetting('past_format'), ['@interval' => $result->getString()]),
186       ];
187     }
188     else {
189       $result = $this->dateFormatter->formatTimeDiffUntil($timestamp, $options);
190       $build = [
191         '#markup' => SafeMarkup::format($this->getSetting('future_format'), ['@interval' => $result->getString()]),
192       ];
193     }
194     CacheableMetadata::createFromObject($result)->applyTo($build);
195     return $build;
196   }
197
198 }