You are here

public function AddtocalView::viewElements in Add to Cal 8.2

Same name and namespace in other branches
  1. 8 src/Plugin/Field/FieldFormatter/AddtocalView.php \Drupal\addtocal\Plugin\Field\FieldFormatter\AddtocalView::viewElements()

Builds a renderable array for a field value.

Parameters

\Drupal\Core\Field\FieldItemListInterface $items: The field values to be rendered.

string $langcode: The language that should be used to render the field.

Return value

array A renderable array for $items, as an array of child elements keyed by consecutive numeric indexes starting from 0.

Overrides DateTimeCustomFormatter::viewElements

File

src/Plugin/Field/FieldFormatter/AddtocalView.php, line 157

Class

AddtocalView
Add to Cal view formatter.

Namespace

Drupal\addtocal\Plugin\Field\FieldFormatter

Code

public function viewElements(FieldItemListInterface $items, $langcode) {
  $entity = $items
    ->getEntity();
  $field = $this->fieldDefinition;
  $elements['#attached']['library'][] = 'addtocal/addtocal';
  $elements['#cache']['contexts'][] = 'timezone';
  foreach ($items as $delta => $item) {
    $elements[$delta] = [];

    /** @var \Drupal\Core\Datetime\DrupalDateTime $start_date */
    $start_date = $item->start_date ?? $item->date ?? NULL;

    /** @var \Drupal\Core\Datetime\DrupalDateTime $end_date */
    $end_date = $item->end_date ?? $start_date;
    if (!$start_date || !$end_date) {
      continue;
    }
    $this
      ->setTimeZone($start_date);
    $this
      ->setTimeZone($end_date);
    $is_all_day = in_array($this
      ->getFieldSetting('datetime_type'), [
      'date',
      'allday',
    ]);
    if ($is_all_day) {

      // A date without time will pick up the current time, set to midnight.
      $start_date
        ->modify('midnight');
      $end_date
        ->modify('midnight');
    }
    $is_start_date_before_end_date = $start_date
      ->getPhpDateTime() < $end_date
      ->getPhpDateTime();
    $is_now_before_start_date = new \DateTime('now') < $start_date
      ->getPhpDateTime();
    $elements[$delta]['start_date']['#plain_text'] = $this
      ->formatDate($start_date);
    if ($is_start_date_before_end_date) {
      $separator = $this
        ->getSetting('separator');
      $elements[$delta]['separator']['#plain_text'] = $separator ? ' ' . $separator . ' ' : ' ';
      $elements[$delta]['end_date']['#plain_text'] = $this
        ->formatDate($end_date);
    }
    $token_data = [
      $field
        ->getTargetEntityTypeId() => $entity,
    ];
    $title = $this->token
      ->replace($this
      ->getSetting('event_title'), $token_data) ?: $entity
      ->label();
    if ($is_all_day) {
      $date_diff = $end_date
        ->diff($start_date);

      // Google calendar all day events count days a little differently:
      $diff_days = 1 + $date_diff->days;
      $link = Link::createAllDay($title, $start_date
        ->getPhpDateTime(), $diff_days);
    }
    else {
      $link = Link::create($title, $start_date
        ->getPhpDateTime(), $end_date
        ->getPhpDateTime());
    }
    $link
      ->address($this->token
      ->replace($this
      ->getSetting('location'), $token_data));
    $link
      ->description($this->token
      ->replace($this
      ->getSetting('description'), $token_data));
    $element_id = 'addtocal-' . $entity
      ->bundle() . '-' . $field
      ->getName() . '-' . $entity
      ->id() . '--' . $delta;
    $addtocal_access = $this
      ->getSetting('past_events') ? TRUE : $is_now_before_start_date;
    $links = [
      '#theme' => 'addtocal_links',
      '#addtocal_link' => $link,
      '#id' => $element_id,
      '#attributes' => [],
      '#button_text' => $this
        ->t('Add to Calendar'),
      '#button_attributes' => [
        'aria-label' => $this
          ->t('Open Add to Calendar menu'),
      ],
      '#menu_attributes' => [],
      '#items' => [
        'google' => [
          'title' => $this
            ->t('Google'),
          'aria-label' => $this
            ->t('Add to Google Calendar'),
          'generator' => new Google(),
        ],
        'yahoo' => [
          'title' => $this
            ->t('Yahoo!'),
          'aria-label' => $this
            ->t('Add to Yahoo Calendar'),
          'generator' => new Yahoo(),
        ],
        'web_outlook' => [
          'title' => $this
            ->t('Outlook.com'),
          'aria-label' => $this
            ->t('Add to Outlook.com Calendar'),
          'generator' => new WebOutlook(),
        ],
        'ics' => [
          'title' => $this
            ->t('iCal / MS Outlook'),
          'aria-label' => $this
            ->t('Add to iCal / MS Outlook'),
          'generator' => new Ics(),
        ],
      ],
      '#access' => $addtocal_access,
    ];
    $context = [
      'items' => $items,
      'langcode' => $langcode,
      'delta' => $delta,
    ];
    $this->moduleHandler
      ->alter('addtocal_links', $links, $context);
    $elements[$delta]['addtocal'] = $links;
  }
  return $elements;
}