Version 1
[yaffs-website] / web / core / modules / datetime / src / Plugin / Field / FieldFormatter / DateTimeTimeAgoFormatter.php
diff --git a/web/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php b/web/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php
new file mode 100644 (file)
index 0000000..3fc3157
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+
+namespace Drupal\datetime\Plugin\Field\FieldFormatter;
+
+use Drupal\Component\Utility\SafeMarkup;
+use Drupal\Core\Cache\CacheableMetadata;
+use Drupal\Core\Datetime\DateFormatterInterface;
+use Drupal\Core\Datetime\DrupalDateTime;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\FormatterBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Plugin implementation of the 'Time ago' formatter for 'datetime' fields.
+ *
+ * @FieldFormatter(
+ *   id = "datetime_time_ago",
+ *   label = @Translation("Time ago"),
+ *   field_types = {
+ *     "datetime"
+ *   }
+ * )
+ */
+class DateTimeTimeAgoFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The date formatter service.
+   *
+   * @var \Drupal\Core\Datetime\DateFormatterInterface
+   */
+  protected $dateFormatter;
+
+  /**
+   * The current Request object.
+   *
+   * @var \Symfony\Component\HttpFoundation\Request
+   */
+  protected $request;
+
+  /**
+   * Constructs a DateTimeTimeAgoFormatter object.
+   *
+   * @param string $plugin_id
+   *   The plugin_id for the formatter.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param string $label
+   *   The formatter label display setting.
+   * @param string $view_mode
+   *   The view mode.
+   * @param array $third_party_settings
+   *   Third party settings.
+   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
+   *   The date formatter service.
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The current request.
+   */
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatterInterface $date_formatter, Request $request) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
+
+    $this->dateFormatter = $date_formatter;
+    $this->request = $request;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    $settings = [
+      'future_format' => '@interval hence',
+      'past_format' => '@interval ago',
+      'granularity' => 2,
+    ] + parent::defaultSettings();
+
+    return $settings;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['label'],
+      $configuration['view_mode'],
+      $configuration['third_party_settings'],
+      $container->get('date.formatter'),
+      $container->get('request_stack')->getCurrentRequest()
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(FieldItemListInterface $items, $langcode) {
+    $elements = [];
+
+    foreach ($items as $delta => $item) {
+      $date = $item->date;
+      $output = [];
+      if (!empty($item->date)) {
+        if ($this->getFieldSetting('datetime_type') == 'date') {
+          // A date without time will pick up the current time, use the default.
+          datetime_date_default_time($date);
+        }
+        $output = $this->formatDate($date);
+      }
+      $elements[$delta] = $output;
+    }
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $form = parent::settingsForm($form, $form_state);
+
+    $form['future_format'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Future format'),
+      '#default_value' => $this->getSetting('future_format'),
+      '#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
+    ];
+
+    $form['past_format'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Past format'),
+      '#default_value' => $this->getSetting('past_format'),
+      '#description' => $this->t('Use <em>@interval</em> where you want the formatted interval text to appear.'),
+    ];
+
+    $form['granularity'] = [
+      '#type' => 'number',
+      '#title' => $this->t('Granularity'),
+      '#default_value' => $this->getSetting('granularity'),
+      '#description' => $this->t('How many time units should be shown in the formatted output.'),
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = parent::settingsSummary();
+
+    $future_date = new DrupalDateTime('1 year 1 month 1 week 1 day 1 hour 1 minute');
+    $past_date = new DrupalDateTime('-1 year -1 month -1 week -1 day -1 hour -1 minute');
+    $summary[] = t('Future date: %display', ['%display' => $this->formatDate($future_date)]);
+    $summary[] = t('Past date: %display', ['%display' => $this->formatDate($past_date)]);
+
+    return $summary;
+  }
+
+  /**
+   * Formats a date/time as a time interval.
+   *
+   * @param \Drupal\Core\Datetime\DrupalDateTime|object $date
+   *   A date/time object.
+   *
+   * @return array
+   *   The formatted date/time string using the past or future format setting.
+   */
+  protected function formatDate(DrupalDateTime $date) {
+    $granularity = $this->getSetting('granularity');
+    $timestamp = $date->getTimestamp();
+    $options = [
+      'granularity' => $granularity,
+      'return_as_object' => TRUE,
+    ];
+
+    if ($this->request->server->get('REQUEST_TIME') > $timestamp) {
+      $result = $this->dateFormatter->formatTimeDiffSince($timestamp, $options);
+      $build = [
+        '#markup' => SafeMarkup::format($this->getSetting('past_format'), ['@interval' => $result->getString()]),
+      ];
+    }
+    else {
+      $result = $this->dateFormatter->formatTimeDiffUntil($timestamp, $options);
+      $build = [
+        '#markup' => SafeMarkup::format($this->getSetting('future_format'), ['@interval' => $result->getString()]),
+      ];
+    }
+    CacheableMetadata::createFromObject($result)->applyTo($build);
+    return $build;
+  }
+
+}