19declare(strict_types=1);
35 public const string ID =
'bkbiws';
55 $column_factory = $this->ui_factory->table()->column();
57 'availability' => $column_factory->text($this->
lng->txt(
'book_table_col_availability'))->withIsSortable(
true),
58 'date_time' => $column_factory->text($this->
lng->txt(
'book_table_col_datetime'))->withIsSortable(
true),
59 'title' => $column_factory->text($this->
lng->txt(
'title'))->withIsSortable(
true),
60 'description' => $column_factory->text($this->
lng->txt(
'description'))->withIsSortable(
true),
71 $bookable_items[(
int) $item[
'booking_object_id']] = (
string) $item[
'title'];
74 $field_factory = $this->ui_factory->input()->field();
76 'title' => $field_factory->text($this->
lng->txt(
'title')),
77 'description' => $field_factory->text($this->lng->txt(
'description')),
78 'objects' => $field_factory->multiSelect($this->lng->txt(
'book_filter_objects'), $bookable_items),
79 'period' => $field_factory->duration($this->lng->txt(
'book_filter_period'))
81 ->withFormat($this->
user->getDateTimeFormat()),
90 $filter_data = is_array($filter_data) ? $filter_data : [];
93 $time_slot_filter = $this->
stringFilter($filter_data,
'time_slot');
103 foreach ($booking_objects as $item) {
104 $schedule_id = (
int) $item[
'schedule_id'];
105 if ($schedule_id === 0) {
109 $object_id = (
int) $item[
'booking_object_id'];
114 $period_bounds[0] ??
null,
115 $period_bounds[1] ??
null
117 foreach ($slots as $slot) {
119 $time_slot_filter !==
null
120 && $this->
getTimeSlotLabel($slot[
'from'], $slot[
'to'], $is_all_day_schedule) !== $time_slot_filter
125 $rows[] = $this->
composeRow($item, $object_id, $slot[
'from'], $slot[
'to'], $is_all_day_schedule);
138 'availability' => $this->
buildAvailabilityCell((
int) $record[
'available'], (
int) $record[
'nr_items']),
140 (
int) $record[
'slot_from'],
141 (
int) $record[
'slot_to'],
142 (
bool) $record[
'is_all_day']
144 'title' => (string) $record[
'title'],
145 'description' => nl2br((
string) $record[
'description']),
151 return $key ===
'date_time'
152 ?
static fn(array
$a, array
$b):
int => ((
int)
$a[
'slot_from'] <=> (
int)
$b[
'slot_from']) * $direction
153 : parent::getSortCallable($key, $direction);
163 if ($definition === []) {
169 $deadline_timestamp = $now + ($deadline * 3600);
176 foreach ($definition as $weekday_key => $day_slots) {
177 $next_week_day =
new DateTimeImmutable(
'next ' . self::WEEKDAYS_MAP[$weekday_key]);
180 foreach ($day_slots as $time_range) {
181 [$start_string, $end_string] = explode(
'-', $time_range);
182 [$start_hour, $start_minute] = explode(
':', $start_string);
183 [$end_hour, $end_minute] = explode(
':', $end_string);
185 $start_timestamp = $next_week_day->setTime((
int) $start_hour, (
int) $start_minute, 0)->getTimestamp();
186 $end_timestamp = $next_week_day->setTime((
int) $end_hour, (
int) $end_minute, 0)->getTimestamp();
189 (is_int($availability_from) && $start_timestamp < $availability_from)
190 || (is_int($availability_to) && $end_timestamp > $availability_to)
196 ($deadline === 0 && $start_timestamp < $now)
197 || ($deadline === -1 && $end_timestamp < $now)
198 || ($start_timestamp < $deadline_timestamp)
204 (is_int($period_start) && $start_timestamp < $period_start)
205 || (is_int($period_end) && $end_timestamp > $period_end)
211 'from' => $start_timestamp,
212 'to' => $end_timestamp,
216 $next_week_day = $next_week_day->modify(
'+1 week');
232 bool $is_all_day =
false
234 $nr_items = (
int) $item[
'nr_items'];
238 'row_id' =>
"{$object_id}_{$slot_from}_{$slot_to}",
239 'booking_object_id' => $object_id,
240 'title' => (string) $item[
'title'],
241 'description' => (
string) ($item[
'description'] ??
''),
242 'nr_items' => $nr_items,
243 'available' => $available,
244 'is_available' => $available > 0,
245 'has_user_booking' => $this->
hasReservation($object_id, $slot_from, $slot_to, $this->
user->getId()),
248 'slot_from' => $slot_from,
249 'slot_to' => $slot_to,
250 'is_all_day' => $is_all_day,
251 'schedule_id' => (
int) $item[
'schedule_id'],
252 'post_text' => (
string) ($item[
'post_text'] ??
''),
259 $this->getReservationsForObject($object_id),
260 static fn(array $reservation):
bool =>
262 && $reservation[
'date_from'] === $slot_from
263 && $reservation[
'date_to'] === $slot_to
270 $this->getReservationsForObject($object_id),
271 static fn(array $reservation):
bool =>
273 && $reservation[
'date_from'] === $slot_from
274 && $reservation[
'date_to'] === $slot_to
283 $this->getReservationsForObject($object_id),
284 static fn(array $reservation):
bool =>
285 $reservation[
'date_from'] === $slot_from
286 && $reservation[
'date_to'] === $slot_to
295 $this->getReservationsForObject($object_id),
296 static fn(array $reservation):
bool =>
297 $reservation[
'date_from'] === $slot_from
298 && $reservation[
'date_to'] === $slot_to
304 public function formatDateTime(
int $slot_from,
int $slot_to,
bool $is_all_day =
false): string
306 $this->
lng->loadLanguageModule(
'dateplaner');
310 .
", {$this->lng->txt('book_all_day')}";
327 return $this->
lng->txt(
'book_all_day');
330 $from =
new DateTimeImmutable(
"@{$slot_from}");
331 $to =
new DateTimeImmutable(
"@{$slot_to}");
333 return "{$from->format('H:i')} - {$to->format('H:i')}";
336 private function stringFilter(array $filter_data,
string $key): ?string
338 return trim((
string) ($filter_data[$key] ??
'')) ?:
null;
344 private function arrayFilter(array $filter_data,
string $key): ?array
346 if (!isset($filter_data[$key]) || !is_array($filter_data[$key]) || $filter_data[$key] === []) {
350 return array_values(array_map(
'intval', $filter_data[$key]));
358 $period = $filter_data[
'period'] ??
null;
359 if (!is_array($period) || count($period) < 2) {
363 $from = $this->parsePeriodEndpoint($period[0] ??
null);
364 $to = $this->parsePeriodEndpoint($period[1] ??
null);
366 if ($from ===
null && $to ===
null) {
370 $default_start = $this->defaultPeriodStart()->getTimestamp();
373 $from ?? $default_start,
380 return new DateTimeImmutable(
'today',
new DateTimeZone($this->userTimeZoneId()));
385 return $this->
user->getTimeZone() ?: date_default_timezone_get();
390 if ($value ===
null || $value ===
'') {
394 if ($value instanceof DateTimeImmutable) {
395 return $value->getTimestamp();
399 return (
new DateTimeImmutable((
string) $value))->getTimestamp();
400 }
catch (Throwable) {
loadFilteredBookingObjects(?string $title_filter, ?string $description_filter, ?array $object_ids_filter)
buildAvailabilityCell(int $available, int $total)
getSortCallable(string $key, int $direction)
arrayFilter(array $filter_data, string $key)
countActiveReservations(int $object_id, int $slot_from, int $slot_to)
loadRecords(mixed $filter_data)
stringFilter(array $filter_data, string $key)
hasActiveReservation(int $object_id, int $slot_from, int $slot_to, ?int $user_id=null)
getTimeSlotLabel(int $slot_from, int $slot_to, bool $is_all_day)
composeRow(array $item, int $object_id, int $slot_from, int $slot_to, bool $is_all_day=false)
enumerateSlots(ilBookingSchedule $schedule, ?int $period_start=null, ?int $period_end=null)
const int MAX_WEEKS_IN_THE_FUTURE
buildRowCells(array $record)
parsePeriodEndpoint(mixed $value)
countReservations(int $object_id, int $slot_from, int $slot_to)
formatDateTime(int $slot_from, int $slot_to, bool $is_all_day=false)
resolvePeriod(array $filter_data)
hasReservation(int $object_id, int $slot_from, int $slot_to, ?int $user_id=null)
isAllDaySchedule(ilBookingSchedule $schedule)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getList(int $a_pool_id, ?string $a_title=null)
Get list of booking objects.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const int STATUS_CANCELLED
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const SCHEDULE_TYPE_ALL_DAY
Class for date presentation.
static formatDate(ilDateTime $date, bool $a_skip_day=false, bool $a_include_wd=false, bool $include_seconds=false, ?ilObjUser $user=null,)
static formatPeriod(ilDateTime $start, ilDateTime $end, bool $a_skip_starting_day=false, ?ilObjUser $user=null)
Format a period of two dates Shows: 14.
@classDescription Date and time handling
A Column describes the form of presentation for a certain aspect of data, i.e.
$a
thx to https://mlocati.github.io/php-cs-fixer-configurator for the examples