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 @interval 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 @interval 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; } }