public function Calendar::render in Calendar 8.2
Same name and namespace in other branches
- 8 src/Plugin/views/style/Calendar.php \Drupal\calendar\Plugin\views\style\Calendar::render()
Render the display in this style.
Overrides StylePluginBase::render
File
- src/
Plugin/ views/ style/ Calendar.php, line 435
Class
- Calendar
- Views style plugin for the Calendar module.
Namespace
Drupal\calendar\Plugin\views\styleCode
public function render() {
$field_argument = NULL;
if (empty($this->view->argument)) {
return [];
}
// Add calendar style information to the view.
$this->styleInfo
->setGranularity($this->options['granularity']);
$this->styleInfo
->setCalendarPopup($this->displayHandler
->getOption('calendar_popup'));
$this->styleInfo
->setDayNameSize($this->options['day_name_size']);
$this->styleInfo
->setMini($this->options['mini']);
$this->styleInfo
->setShowWeekNumbers($this->options['with_weekno']);
$this->styleInfo
->setColorField($this->options['colors']);
$this->styleInfo
->setWeekLink($this->options['granularity_links']['week']);
$this->styleInfo
->setDayLink($this->options['granularity_links']['day']);
$this->styleInfo
->setMultiAllDayStyle($this->options['multi_allday_style']);
$this->styleInfo
->setMultiAllDayTitle($this->options['multi_allday_title']);
$this->styleInfo
->setmultiAllDayViewMode($this->options['multi_allday_viewmode']);
$calendar_arguments = $this->calendarHelper
->getCalendarArguments($this->view);
$field_argument = $calendar_arguments[0]['field'];
// Calculate offset for all dates from timezone set for current user.
// Because Drupal 8 requires PHP >= 7.1 we can use DateTime functions.
// @TODO find out if there is a need for storing offset in CalendarEvent.
$current_user = \Drupal::entityTypeManager()
->getStorage('user')
->load($this->account
->id());
if (!empty($current_user->timezone->value)) {
$tz_user = new \DateTimeZone($current_user->timezone->value);
$storagetime = new \DateTime('now', new \DateTimeZone(DateTimeItemInterface::STORAGE_TIMEZONE));
$tz_interval = \DateInterval::createFromDateString($tz_user
->getOffset($storagetime) . 'seconds');
}
else {
$tz_interval = \DateInterval::createFromDateString('0 seconds');
}
$granularity = $this->styleInfo
->getGranularity();
$color_field = $ref = NULL;
$color_info = explode('.', $this->styleInfo
->getColorField());
if (count($color_info) > 1) {
$entity_type = $color_info[0];
$color_field = $color_info[1];
// Check if color_field is some field from base entity.
if (isset($this->view->result[0]->_entity) && $this->view->result[0]->_entity
->getEntityTypeId() !== $entity_type) {
// Color_field may be part of some reference
foreach ($this->view->relationship as $field_name => $field) {
// Tricky! Index entity type uses space, not underscore.
if (isset($field->definition['entity type']) && $field->definition['entity type'] === $entity_type) {
$ref = $field_name;
}
elseif ($entity_type === 'group' && isset($color_field)) {
$ref = 'gid';
}
}
}
}
$caldays = $this->calendarHelper
->{$granularity}($this->view);
if (in_array($granularity, [
'week',
'day',
])) {
foreach ($caldays as $weekno => $data) {
foreach ($data['weekdays'] as $date => $day) {
if (is_numeric($date)) {
$caldays[$weekno]['weekdays'][(string) $date]['other'] = $this->calendarHelper
->buildDayHours();
}
}
}
}
// Build links to displays with other granularities.
foreach ($caldays as $weekno => $weekday) {
// If enabled from StyleInfo set links.
$year = $month = $week = $day_route = $week_route = NULL;
$year = $caldays[$weekno]['startweekdate']
->format('Y');
$month = $caldays[$weekno]['startweekdate']
->format('m');
$week = $weekno;
if (isset($this->options['granularity_links']['week'])) {
$week_route = $this->options['granularity_links']['week'];
}
if (isset($this->options['granularity_links']['day'])) {
$day_route = $this->options['granularity_links']['day'];
}
if ($this->styleInfo
->getShowWeekNumbers() === '1') {
$show_week = true;
}
else {
$show_week = NULL;
}
$caldays[$weekno]['linkdata'] = [
'year' => $year,
'month' => $month,
'week' => $week,
'show_week' => $show_week,
'week_route' => $week_route,
'day_route' => $day_route,
];
}
// Loop over view result rows and create Events.
$events = [];
foreach ($this->view->result as $row) {
// Fields can be multivalue.
foreach ($row->_entity
->get($field_argument) as $delta => $item) {
$event = NULL;
if (isset($item->end_value) && isset($item->value)) {
$enddate = new DrupalDateTime($item->end_value);
$startdate = new DrupalDateTime($item->value);
// Check if enddate is after start of week AND begindate before end of week.
// This is dependant on user timezone as this may split events over day borders.
$event = new CalendarEvent();
$event
->setId($row->_entity
->id());
// $event->setLabel($row->_entity->get('title')->value);
$event
->setWeekno($this->calendarHelper::weekInfoDate($startdate)['weekno']);
$event
->setEndDate($enddate
->add($tz_interval));
$event
->setStartDate($startdate
->add($tz_interval));
// @TODO set weekno before adding tz_interval?
$event
->setWeekno($this->calendarHelper::weekInfoDate($startdate)['weekno']);
if ($color_field) {
if ($ref && isset($row->_relationship_entities[$ref]->{$color_field}->color)) {
$event
->setColor($row->_relationship_entities[$ref]->{$color_field}->color);
}
elseif (isset($row->_entity->{$color_field}->color)) {
$event
->setColor($row->_entity->{$color_field}->color);
}
}
// @TODO fix rendering of row through Plugin (expecting array, string provided).
$event
->setRow($this->view->rowPlugin
->render($row));
if ($event
->getStartDate()
->format('Ymd') === $event
->getEndDate()
->format('Ymd')) {
$event
->setMultiDay(FALSE);
// To find alldays we ignore seconds.
if ($event
->getStartDate()
->format('Hi') === '0000' && $event
->getEndDate()
->format('Hi') === '2359') {
$event
->setAllDay(TRUE);
$event
->setLabel(self::renderTitle($row->_entity));
}
else {
$event
->setAllDay(FALSE);
$event
->setLength($enddate
->diff($startdate));
}
}
else {
$event
->setMultiDay(TRUE);
$event
->setLabel(self::renderTitle($row->_entity));
$event
->setAllDay(FALSE);
}
}
elseif ($item->value) {
$event = new CalendarEvent();
$event
->setId($row->_entity
->id());
$startdate = new DrupalDateTime($item->value);
$event
->setStartDate($startdate
->add($tz_interval));
$event
->setWeekno($this->calendarHelper::weekInfoDate($startdate)['weekno']);
$event
->setMultiDay(FALSE);
$event
->setAllDay(FALSE);
$event
->setLabel($row->_entity
->get('title')->value);
// @TODO fix rendering of row through Plugin (expecting array, string provided).
$event
->setRow($this->view->rowPlugin
->render($row));
}
}
$events[] = $event;
if ($event
->getMultiDay()) {
$offset = $this->calendarHelper::weekInfoDate($event
->getStartDate())['startweekdate']
->diff($event
->getStartDate());
$event
->setOffSet($offset);
$diff = $event
->getStartDate()
->diff($event
->getEndDate());
if ($diff->d < 7 - $offset->d) {
$length = $event
->getStartDate()
->diff($event
->getEndDate());
}
elseif ($event
->getOffSet()->d > 0 || $event
->getOffSet()->h > 0) {
// if ($event->getOffSet()->h > 0) {
// $days = 'P' . (7 - 1 - $event->getOffSet()->d) . 'D';
// }
// else {
$days = 'P' . (7 - $event
->getOffSet()->d) . 'D';
// }
$length = new \DateInterval($days);
}
else {
$length = new \DateInterval('P7D');
}
$event
->setLength($length);
// Multidate events may lie outside of range so we need to clone them.
if ($diff->d > $length->d) {
$year = $event
->getStartDate()
->format('Y');
$weekno = $event
->getWeekno();
$max = $weekno + (int) floor($diff->d / 7);
do {
$weekno++;
$week_start = $this->calendarHelper::weekInfo($year . $weekno)['startweekdate'];
$c_event = clone $event;
$c_event
->setStartDate($week_start);
$c_event
->setWeekno($weekno);
$c_event
->setOffset(new \DateInterval('P0D'));
// Substract first day since diff for length is measured in extra days.
$c_diff = $week_start
->diff($event
->getEndDate());
if ($c_diff->d > 7) {
$c_event
->setLength(new \DateInterval('P7D'));
}
else {
$c_event
->setLength($c_diff);
}
$events[] = $c_event;
} while ($weekno < $max);
}
}
}
// Add events to caldays array if they lie within caldays range.
foreach ($events as $event) {
if (isset($caldays[$event
->getWeekno()])) {
if ($event
->getMultiDay()) {
$caldays[$event
->getWeekno()]['weekdays'][$event
->getStartDate()
->format('Ymd')]['multiday'][$event
->getId()] = $event;
}
elseif ($event
->getAllDay()) {
$caldays[$event
->getWeekno()]['weekdays'][$event
->getStartDate()
->format('Ymd')]['allday'][$event
->getId()] = $event;
}
else {
if (in_array($granularity, [
'week',
'day',
])) {
// Check if time for startdate is present, otherwise round to nearest time.
if (array_key_exists($event
->getStartDate()
->format('H.i'), array_keys($caldays[$event
->getWeekno()]['weekdays'][$event
->getStartDate()
->format('Ymd')]['other']))) {
$caldays[$event
->getWeekno()]['weekdays'][$event
->getStartDate()
->format('Ymd')]['other'][$event
->getStartDate()
->format('H.i')][$event
->getId()] = $event;
}
else {
$nearest = $event
->getStartDate()
->format('H') . '.00';
$caldays[$event
->getWeekno()]['weekdays'][$event
->getStartDate()
->format('Ymd')]['other'][$nearest][$event
->getId()] = $event;
}
}
else {
$caldays[$event
->getWeekno()]['weekdays'][$event
->getStartDate()
->format('Ymd')]['other'][$event
->getId()] = $event;
}
}
}
}
// Derive template to use.
$template = 'calendar_' . $this->styleInfo
->getGranularity();
if ($this->view->styleInfo
->getMini()) {
$template = 'calendar_mini_' . $this->styleInfo
->getGranularity();
}
$build = [
'#theme' => $template,
'#view' => $this->view,
'#options' => $this->options,
'#rows' => $caldays,
];
return $build;
}