View source
<?php
namespace Drupal\office_hours;
use Drupal\Component\Utility\Html;
use Drupal\office_hours\Element\OfficeHoursDatetime;
trait OfficeHoursFormatterTrait {
public function getRows(array $items, array $settings, array $field_settings, $time = NULL) {
$default_office_hours = [
'startday' => NULL,
'endday' => NULL,
'closed' => $this
->t(Html::escape($settings['closed_format'])),
'current' => FALSE,
'next' => FALSE,
'slots' => [],
'formatted_slots' => [],
'comments' => [],
];
$office_hours = [];
for ($day = 0; $day < 7; $day++) {
$office_hours[$day] = [
'startday' => $day,
] + $default_office_hours;
}
$time = $time === NULL ? \Drupal::time()
->getRequestTime() : $time;
$today = (int) idate('w', $time);
$now = date('Hi', $time);
foreach ($items as $key => $item) {
$day = (int) $item['day'];
$start = OfficeHoursDatetime::get($item['starthours'], 'Hi');
$end = OfficeHoursDatetime::get($item['endhours'], 'Hi');
$office_hours[$day] = $office_hours[$day] ?? [
'startday' => $day,
] + $default_office_hours;
$office_hours[$day]['slots'][] = [
'start' => $start,
'end' => $end,
'comment' => $item['comment'],
];
}
$next = NULL;
foreach ($office_hours as $day => &$day_data) {
foreach ($day_data['slots'] as $slot_id => $slot) {
if ($day <= $today) {
if ($next === NULL) {
$next = $day;
}
}
if ($day == $today) {
$start = $slot['start'];
$end = $slot['end'];
if ($start > $now) {
$next = $day;
}
elseif ($start < $end && $end < $now) {
}
else {
$day_data['current'] = TRUE;
$next = $day;
}
}
elseif ($day > $today) {
if ($next === NULL) {
$next = $day;
}
elseif ($next < $today) {
$next = $day;
}
else {
}
}
else {
}
}
}
if ($next !== NULL) {
$office_hours[$next]['next'] = TRUE;
}
$office_hours = OfficeHoursDateHelper::weekDaysOrdered($office_hours, $settings['office_hours_first_day']);
if ($settings['compress']) {
$office_hours = $this
->compressSlots($office_hours);
}
if ($settings['grouped']) {
$office_hours = $this
->groupDays($office_hours);
}
$office_hours = $this
->formatLabels($office_hours, $settings);
$office_hours = $this
->formatSlots($office_hours, $settings, $field_settings);
switch ($settings['show_closed']) {
case 'open':
$office_hours = $this
->keepOpenDays($office_hours);
break;
case 'next':
$office_hours = $this
->keepNextDay($office_hours);
break;
case 'none':
$office_hours = [];
break;
case 'current':
$office_hours = $this
->keepCurrentDay($office_hours);
break;
}
return $office_hours;
}
protected function compressSlots(array $office_hours) {
foreach ($office_hours as &$info) {
if (is_array($info['slots']) && !empty($info['slots'])) {
$compressed_slot = $info['slots'][0];
foreach ($info['slots'] as $index => $slot) {
$compressed_slot['start'] = min($compressed_slot['start'], $slot['start']);
$compressed_slot['end'] = max($compressed_slot['end'], $slot['end']);
}
$info['slots'] = [
0 => $compressed_slot,
];
}
}
return $office_hours;
}
protected function groupDays(array $office_hours) {
$previous_day = NULL;
$previous_key = -100;
foreach ($office_hours as $key => &$day) {
if ($day['slots'] == $previous_day['slots'] && $key < 8) {
$day['endday'] = $day['startday'];
$day['startday'] = $previous_day['startday'];
$day['current'] = $day['current'] || $previous_day['current'];
$day['next'] = $day['next'] || $previous_day['next'];
unset($office_hours[(int) $previous_key]);
}
$previous_key = (int) $key;
$previous_day = $day;
}
return $office_hours;
}
protected function keepOpenDays(array $office_hours) {
$new_office_hours = [];
foreach ($office_hours as $day => $info) {
if (!empty($info['slots'])) {
$new_office_hours[] = $info;
}
}
return $new_office_hours;
}
protected function keepNextDay(array $office_hours) {
$new_office_hours = [];
foreach ($office_hours as $day => $info) {
if ($info['current'] || $info['next']) {
$new_office_hours[$day] = $info;
}
}
return $new_office_hours;
}
protected function keepCurrentDay(array $office_hours) {
$new_office_hours = [];
$today = (int) idate('w', $_SERVER['REQUEST_TIME']);
foreach ($office_hours as $info) {
if ($info['startday'] == $today) {
$new_office_hours[$today] = $info;
}
}
return $new_office_hours;
}
protected function formatLabels(array $office_hours, array $settings) {
$day_format = $settings['day_format'];
$day_names = OfficeHoursDateHelper::weekDaysByFormat($settings['day_format']);
$group_separator = $settings['separator']['grouped_days'];
$days_suffix = $settings['separator']['day_hours'];
foreach ($office_hours as $key => &$info) {
$label = isset($day_names[$info['startday']]) ? $day_names[$info['startday']] : \Drupal::service('date.formatter')
->format($info['startday'], 'html_date');
if ($day_format == 'none') {
$info['label'] = $label;
continue;
}
if (isset($info['endday'])) {
$label .= $group_separator . $day_names[$info['endday']];
}
$info['label'] = $label ? $label . $days_suffix : '';
}
return $office_hours;
}
protected function formatSlots(array $office_hours, array $settings, array $field_settings) {
$time_format = OfficeHoursDateHelper::getTimeFormat($settings['time_format']);
$time_separator = $settings['separator']['hours_hours'];
$slot_separator = $settings['separator']['more_hours'];
foreach ($office_hours as &$day_data) {
$day_data['formatted_slots'] = [];
$day_data['comments'] = [];
foreach ($day_data['slots'] as $key => &$slot_data) {
$formatted_slot = OfficeHoursDateHelper::formatTimeSlot($slot_data['start'], $slot_data['end'], $time_format, $time_separator);
$slot_data['formatted_slot'] = $formatted_slot;
$day_data['formatted_slots'][] = $formatted_slot;
$day_data['comments'][] = $slot_data['comment'];
}
$day_data['formatted_slots'] = empty($day_data['formatted_slots']) ? $day_data['closed'] : implode($slot_separator, $day_data['formatted_slots']);
$day_data['comments'] = array_map('Drupal\\Component\\Utility\\Html::escape', $day_data['comments']);
if ($field_settings['comment'] == 2) {
$day_data['comments'] = array_map('t', $day_data['comments']);
}
$day_data['comments'] = $field_settings['comment'] ? implode($slot_separator, $day_data['comments']) : '';
}
return $office_hours;
}
}