addtocal-8.x-2.0-beta2/src/Plugin/Field/FieldFormatter/AddtocalGroupedView.php
src/Plugin/Field/FieldFormatter/AddtocalGroupedView.php
<?php
namespace Drupal\addtocal\Plugin\Field\FieldFormatter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Spatie\CalendarLinks\Generators\Google;
use Spatie\CalendarLinks\Generators\Ics;
use Spatie\CalendarLinks\Generators\WebOutlook;
use Spatie\CalendarLinks\Generators\WebOffice;
use Spatie\CalendarLinks\Generators\Yahoo;
use Spatie\CalendarLinks\Link;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\smart_date\Plugin\Field\FieldType\SmartDateItem;
use Drupal\Core\Datetime\DrupalDateTime;
/**
* Add to Cal grouped view formatter.
*
* @FieldFormatter(
* id = "addtocal_grouped_view",
* label = @Translation("Add to Cal grouped button"),
* field_types = {
* "date",
* "datestamp",
* "datetime",
* "daterange",
* "date_recur",
* "smartdate",
* }
* )
*/
class AddtocalGroupedView extends AddtocalView {
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
$entity = $items->getEntity();
$field = $this->fieldDefinition;
$elements['#attached']['library'][] = 'addtocal/addtocal';
$elements['#cache']['contexts'][] = 'timezone';
$last_event_date_index = count($items) - 1;
// Set first and last event date.
/** @var \Drupal\Core\Datetime\DrupalDateTime $first_event_date */
$first_event_date = $items->get(0) ?? NULL;
/** @var \Drupal\Core\Datetime\DrupalDateTime $last_event_date */
$last_event_date = $items->get($last_event_date_index) ?? NULL;
if (!$first_event_date || !$last_event_date) {
return;
}
if ($first_event_date instanceof SmartDateItem && $last_event_date instanceof SmartDateItem) {
$timezone = empty($first_event_date->timezone) ? NULL : $first_event_date->timezone;
$first_event_date = DrupalDateTime::createFromTimestamp($first_event_date->value, $timezone);
$last_event_date = DrupalDateTime::createFromTimestamp($last_event_date->end_value, $timezone);
}
// Set timezone for first and last event date.
$this->setTimeZone($first_event_date);
$this->setTimeZone($last_event_date);
// Continue to list all the dates added on the event.
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 ($item instanceof SmartDateItem) {
$timezone = empty($item->timezone) ? NULL : $item->timezone;
$start_date = DrupalDateTime::createFromTimestamp($item->value, $timezone);
$end_date = DrupalDateTime::createFromTimestamp($item->end_value, $timezone);
}
if (!$start_date || !$end_date) {
continue;
}
$this->setTimeZone($start_date);
$this->setTimeZone($end_date);
$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, ['clear' => TRUE]) ?: $entity->label();
// For multiple date events setting a particular day as all day will not make a difference.
// Use the start_date of the first day and the end_date of the last event day.
$link = Link::create($title, $first_event_date->getPhpDateTime(), $last_event_date->getPhpDateTime());
$link->address($this->token->replace($this->getSetting('location'), $token_data, ['clear' => TRUE]));
$link->description($this->token->replace($this->getSetting('description'), $token_data, ['clear' => TRUE]));
$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(),
],
'web_office' => [
'title' => $this->t('Office.com'),
'aria-label' => $this->t('Add to Office.com Calendar'),
'generator' => new WebOffice(),
],
'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'] = $delta == $last_event_date_index ? $links : [];
}
return $elements;
}
}
