View source
<?php
namespace Drupal\fullcalendar_view;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\StringTranslation\StringTranslationTrait;
class FullcalendarViewPreprocess {
use StringTranslationTrait;
protected static $viewIndex = 0;
public function process(array &$variables) {
$view = $variables['view'];
$view_index = self::$viewIndex++;
$style = $view->style_plugin;
$options = $style->options;
$fields = $view->field;
$language = \Drupal::languageManager()
->getCurrentLanguage();
$user = $variables['user'];
$token = '';
if (!$user
->isAnonymous()) {
$token = \Drupal::csrfToken()
->get($user
->id());
}
$event_bundle_type = $options['bundle_type'];
$entity_type = $view
->getBaseEntityType();
if ($entity_type
->id() === 'node') {
$add_form = 'node/add/' . $event_bundle_type;
}
else {
$entity_links = $entity_type
->get('links');
if (isset($entity_links['add-form'])) {
$add_form = str_replace('{' . $entity_type
->id() . '}', $event_bundle_type, $entity_links['add-form']);
}
elseif (isset($entity_links['add-page'])) {
$add_form = str_replace('{' . $entity_type
->id() . '}', $event_bundle_type, $entity_links['add-page']);
}
}
$entity_manager = \Drupal::entityTypeManager();
$access_handler = $entity_manager
->getAccessControlHandler($entity_type
->id());
$dbl_click_to_create = FALSE;
if ($access_handler
->createAccess($event_bundle_type)) {
$dbl_click_to_create = TRUE;
}
$variables['entity_id'] = $entity_type
->id();
$variables['options'] = $options;
$variables['showAddEvent'] = $dbl_click_to_create && $options['createEventLink'];
$timeFormat = $options['timeFormat'];
$start_field = $options['start'];
if (empty($start_field)) {
return;
}
$end_field = $options['end'];
$tax_field = $options['tax_field'];
$duration_field = isset($options['duration']) ? $options['duration'] : NULL;
$rrule_field = isset($options['rrule']) ? $options['rrule'] : NULL;
switch ($options['default_date_source']) {
case 'now':
$default_date = date('Y-m-d');
break;
case 'fixed':
$default_date = $options['defaultDate'];
break;
default:
}
$default_lang = $options['defaultLanguage'] === 'current_lang' ? $this
->fullcalendar_view_map_langcodes($language
->getId()) : $options['defaultLanguage'];
$color_content = $options['color_bundle'];
$color_tax = $options['color_taxonomies'];
$start_field_option = $fields[$start_field]->options;
$end_field_option = empty($end_field) ? NULL : $fields[$end_field]->options;
$timezone = !empty($start_field_option['settings']['timezone_override']) ? $start_field_option['settings']['timezone_override'] : date_default_timezone_get();
$first_day = isset($options['firstDay']) ? intval($options['firstDay']) : 0;
$left_buttons = Xss::filter($options['left_buttons']);
$right_buttons = Xss::filter($options['right_buttons']);
$entries = [];
if (!empty($start_field)) {
$title_allowed_tags = Xss::getAdminTagList();
if (($tag_key = array_search('a', $title_allowed_tags)) !== false) {
unset($title_allowed_tags[$tag_key]);
}
$timezone_service = \Drupal::service('fullcalendar_view.timezone_conversion_service');
foreach ($view->result as $row) {
$view->row_index = $row->index;
$current_entity = $row->_entity;
if (!$current_entity
->hasField($start_field)) {
continue;
}
$entity_id = $current_entity
->id();
$entity_bundle = $current_entity
->bundle();
if (!empty($view->field[$tax_field])) {
$event_type = $view->style_plugin
->getFieldValue($row->index, $tax_field);
if (!empty($event_type)) {
if (is_array($event_type)) {
$event_type = reset($event_type);
}
}
else {
$event_type = '';
}
}
$start_dates = $current_entity
->get($start_field)
->getValue();
$end_dates = empty($end_field) || !$current_entity
->hasField($end_field) ? '' : $current_entity
->get($end_field)
->getValue();
foreach ($fields as $name => $field) {
if (method_exists($field, 'advancedRender')) {
$field->view->row_index = $row->index;
$des = $field
->advancedRender($row);
}
}
if (empty($options['title']) || $options['title'] == 'title') {
$title = $fields['title']
->advancedRender($row);
}
elseif (!empty($fields[$options['title']])) {
$title = $fields[$options['title']]
->advancedRender($row);
}
else {
$title = t('Invalid event title');
}
$link_url = strstr($title, 'href="');
if ($link_url) {
$link_url = substr($link_url, 6);
$link_url = strstr($link_url, '"', true);
}
else {
$link_url = '';
}
if (!empty($start_dates) && is_array($start_dates)) {
foreach ($start_dates as $i => $start_date) {
$entry = [
'title' => Xss::filter($title, $title_allowed_tags),
'id' => $row->index . "-{$i}",
'eid' => $entity_id,
'url' => $link_url,
'des' => isset($des) ? $des : '',
];
if (!empty($duration_field) && !empty($fields[$duration_field])) {
$entry['duration'] = $fields[$duration_field]
->advancedRender($row);
}
if (!empty($start_date)) {
$start_date_value = $start_date['value'];
if ($start_field_option['type'] === 'timestamp') {
$start_date_value = intval($start_date_value);
$start_date_value = date(DATE_ATOM, $start_date_value);
}
elseif (strpos($start_field_option['type'], 'datetime') === FALSE && strpos($start_field_option['type'], 'daterange') === FALSE) {
if (empty($variables['fullcalendar_fieldtypes'])) {
continue 2;
}
else {
$valid = FALSE;
foreach ($variables['fullcalendar_fieldtypes'] as $fieldtype) {
if (strpos($start_field_option['type'], $fieldtype) === 0) {
$valid = TRUE;
break;
}
}
if (!$valid) {
continue 2;
}
}
}
if (!$current_entity
->access('update')) {
$entry['editable'] = FALSE;
}
if (!isset($default_date)) {
$default_date = substr($start_date_value, 0, 10);
}
$all_day = strlen($start_date_value) < 11 ? TRUE : FALSE;
if ($all_day) {
$entry['start'] = $start_date_value;
$entry['allDay'] = true;
}
else {
$entry['start'] = $timezone_service
->utcToLocal($start_date_value, $timezone);
}
}
else {
continue 2;
}
if (!empty($end_dates[$i])) {
if ($end_field_option['type'] === 'timestamp') {
$end_date = $end_dates[$i]['value'];
$end_date = intval($end_date);
$end_date = date(DATE_ATOM, $end_date);
}
elseif (strpos($end_field_option['type'], 'daterange') !== FALSE) {
$end_date = $end_dates[$i]['end_value'];
}
elseif (strpos($end_field_option['type'], 'datetime') === FALSE) {
$end_date = '';
}
else {
$end_date = $end_dates[$i]['value'];
}
if (!empty($end_date)) {
$all_day = strlen($end_date) < 11 ? TRUE : FALSE;
if ($all_day) {
$end = new DrupalDateTime($end_date);
$end
->modify('+1 day');
$entry['end'] = $end
->format('Y-m-d');
$entry['allDay'] = true;
}
else {
$entry['end'] = $timezone_service
->utcToLocal($end_date, $timezone);
}
}
}
else {
$entry['eventDurationEditable'] = FALSE;
}
if (isset($event_type) && isset($color_tax[$event_type])) {
$entry['backgroundColor'] = $color_tax[$event_type];
}
elseif (isset($color_content[$entity_bundle])) {
$entry['backgroundColor'] = $color_content[$entity_bundle];
}
if (!empty($rrule_field)) {
$rrule = $current_entity
->hasField($rrule_field) ? $current_entity
->get($rrule_field)
->getString() : '';
if (!empty($rrule)) {
$entry['rrule'] = Xss::filter($rrule);
$entry['editable'] = FALSE;
}
}
$entries[] = $entry;
}
}
}
unset($view->row_index);
$calendar_options = [
'plugins' => [
'moment',
'interaction',
'dayGrid',
'timeGrid',
'list',
'rrule',
],
'timeZone' => $timezone,
'defaultView' => isset($options['default_view']) ? $options['default_view'] : 'dayGridMonth',
'defaultDate' => empty($default_date) ? date('Y-m-d') : $default_date,
'header' => [
'left' => $left_buttons,
'center' => 'title',
'right' => $right_buttons,
],
'eventTimeFormat' => $timeFormat,
'firstDay' => $first_day,
'locale' => $default_lang,
'events' => $entries,
'navLinks' => $options['nav_links'] !== 0,
'editable' => $options['updateAllowed'] !== 0,
'eventLimit' => isset($options['eventLimit']) ? intval($options['eventLimit']) : 2,
'eventOverlap' => $options['allowEventOverlap'] !== 0,
];
$dialog_options = [
'left' => 0,
'top' => 0,
'width' => 640,
'height' => 480,
'movable' => true,
'resizable' => true,
'style' => [
'backgroundColor' => 'rgba(255,255,255,0.9)',
'font-size' => '1rem',
],
];
$variables['#attached']['library'][] = 'fullcalendar_view/fullcalendar';
if ($options['dialogWindow']) {
$variables['#attached']['library'][] = 'fullcalendar_view/libraries.jsframe';
}
$variables['view_index'] = $view_index;
$variables['view_id'] = $view->storage
->id();
$variables['display_id'] = $view->current_display;
$variables['#attached']['drupalSettings']['fullCalendarView'][$view_index] = [
'languageSelector' => $options['languageSelector'],
'updateConfirm' => $options['updateConfirm'],
'dialogWindow' => $options['dialogWindow'],
'eventBundleType' => $event_bundle_type,
'startField' => $start_field,
'endField' => $end_field,
'dblClickToCreate' => $dbl_click_to_create,
'entityType' => $entity_type
->id(),
'addForm' => isset($add_form) ? $add_form : '',
'token' => $token,
'openEntityInNewTab' => $options['openEntityInNewTab'],
'calendar_options' => json_encode($calendar_options),
'dialog_options' => json_encode($dialog_options),
];
}
}
private function fullcalendar_view_map_langcodes($langcode) {
switch ($langcode) {
case "en-x-simple":
return "en";
case "pt-pt":
return "pt";
case "zh-hans":
return "zh-cn";
case "zh-hant":
return "zh-tw";
default:
return $langcode;
}
}
}