Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
65.08% covered (warning)
65.08%
41 / 63
42.86% covered (danger)
42.86%
3 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
OverallCalendar
65.08% covered (warning)
65.08%
41 / 63
42.86% covered (danger)
42.86%
3 / 7
18.13
0.00% covered (danger)
0.00%
0 / 1
 insertSlotsBulk
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
3.01
 cancelAvailability
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 purgeMissingAvailabilityByScope
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 deleteOlderThan
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 book
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
2
 unbook
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 readSlots
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace BO\Zmsdb;
4
5use BO\Zmsdb\Query\OverallCalendar as Calender;
6use DateInterval;
7use DateTimeImmutable;
8use DateTimeInterface;
9
10class OverallCalendar extends Base
11{
12    public function insertSlotsBulk(array $rows): void
13    {
14        if (!$rows) {
15            return;
16        }
17
18        $placeholders = rtrim(str_repeat('(?,?,?,?,?),', count($rows)), ',');
19        $sql = sprintf(Query\OverallCalendar::UPSERT_MULTI, $placeholders);
20
21        $params = [];
22        foreach ($rows as $r) {
23            $params[] = $r[0];
24            $params[] = $r[1];
25            $params[] = $r[2]->format('Y-m-d H:i:s');
26            $params[] = (int)$r[3];
27            $params[] = $r[4] ?? 'free';
28        }
29        $this->perform($sql, $params);
30    }
31
32    public function cancelAvailability(int $scopeId, int $availabilityId): void
33    {
34        $this->perform(Calender::CANCEL_AVAILABILITY, [
35            'scope_id' => $scopeId,
36            'availability_id' => $availabilityId,
37        ]);
38    }
39
40    public function purgeMissingAvailabilityByScope(
41        \DateTimeInterface $dateTime,
42        int $scopeId
43    ): bool {
44        return (bool) $this->perform(
45            Query\OverallCalendar::PURGE_MISSING_AVAIL_BY_SCOPE,
46            [
47                'dateString' => $dateTime->format('Y-m-d'),
48                'scopeID'    => $scopeId,
49            ]
50        );
51    }
52
53
54    public function deleteOlderThan(DateTimeInterface $date): bool
55    {
56        return (bool) $this->perform(Calender::DELETE_ALL_BEFORE, [
57            'threshold' => $date->format('Y-m-d 00:00:00'),
58        ]);
59    }
60
61    public function book(
62        int $scopeId,
63        string $startTime,
64        int $processId,
65        int $slotUnits
66    ): void {
67        $start = new DateTimeImmutable($startTime);
68        $end   = $start->add(new DateInterval('PT' . ($slotUnits * 5) . 'M'));
69
70        $seat = $this->fetchValue(Calender::FIND_FREE_SEAT, [
71            'scope' => $scopeId,
72            'start' => $start->format('Y-m-d H:i:s'),
73            'end'   => $end  ->format('Y-m-d H:i:s'),
74            'units' => $slotUnits,
75        ]);
76
77        if (!$seat) {
78            error_log("Failed to book a seat for scope ID {$scopeId} from {$start->format('Y-m-d H:i:s')} to {$end->format('Y-m-d H:i:s')}. No free seats available.");
79            return;
80        }
81
82        $this->perform(Calender::BLOCK_SEAT_RANGE, [
83            'pid'   => $processId,
84            'units' => $slotUnits,
85            'scope' => $scopeId,
86            'seat'  => $seat,
87            'start' => $start->format('Y-m-d H:i:s'),
88            'end'   => $end  ->format('Y-m-d H:i:s'),
89        ]);
90    }
91
92    public function unbook(int $scopeId, int $processId): void
93    {
94        $this->perform(Calender::UNBOOK_PROCESS, [
95            'scope_id' => $scopeId,
96            'process_id' => $processId,
97        ]);
98    }
99
100    public function readSlots(
101        array $scopeIds,
102        string $from,
103        string $until,
104        ?string $updatedAfter = null
105    ): array {
106        if (empty($scopeIds)) {
107            return [];
108        }
109
110        $in_list = implode(',', array_map('intval', $scopeIds));
111        $until = (new \DateTime($until))->modify('+1 day')->format('Y-m-d');
112
113        if ($updatedAfter === null) {
114            $sql = sprintf(Calender::SELECT_RANGE, $in_list);
115            $params = ['from' => $from, 'until' => $until];
116        } else {
117            $sql = sprintf(Calender::SELECT_RANGE_UPDATED, $in_list);
118            $params = [
119                'from'         => $from,
120                'until'        => $until,
121                'updatedAfter' => $updatedAfter
122            ];
123        }
124
125        return $this->fetchAll($sql, $params);
126    }
127}