Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
58.62% covered (warning)
58.62%
34 / 58
33.33% covered (danger)
33.33%
2 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
OverallCalendar
58.62% covered (warning)
58.62%
34 / 58
33.33% covered (danger)
33.33%
2 / 6
19.57
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
 deleteFreeRange
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
 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        $placeholders = rtrim(str_repeat('(?,?,?,?,?),', count($rows)), ',');
18        $sql = sprintf(Calender::INSERT_MULTI, $placeholders);
19
20        $params = [];
21        foreach ($rows as $r) {
22            $params[] = $r[0];
23            $params[] = $r[1];
24            $params[] = $r[2]->format('Y-m-d H:i:s');
25            $params[] = $r[3];
26            $params[] = $r[4];
27        }
28        $this->perform($sql, $params);
29    }
30
31    public function deleteFreeRange(
32        int $scopeId,
33        int $availabilityId,
34        DateTimeInterface $begin,
35        DateTimeInterface $finish
36    ): void {
37        $this->perform(Calender::DELETE_FREE_RANGE, [
38            'scope_id' => $scopeId,
39            'availability_id' => $availabilityId,
40            'begin' => $begin->format('Y-m-d H:i:s'),
41            'finish' => $finish->format('Y-m-d H:i:s'),
42        ]);
43    }
44
45    public function deleteOlderThan(DateTimeInterface $date): bool
46    {
47        return (bool) $this->perform(Calender::DELETE_ALL_BEFORE, [
48            'threshold' => $date->format('Y-m-d 00:00:00'),
49        ]);
50    }
51
52    public function book(
53        int $scopeId,
54        string $startTime,
55        int $processId,
56        int $slotUnits
57    ): void {
58        $start = new DateTimeImmutable($startTime);
59        $end   = $start->add(new DateInterval('PT' . ($slotUnits * 5) . 'M'));
60
61        $seat = $this->fetchValue(Calender::FIND_FREE_SEAT, [
62            'scope' => $scopeId,
63            'start' => $start->format('Y-m-d H:i:s'),
64            'end'   => $end  ->format('Y-m-d H:i:s'),
65            'units' => $slotUnits,
66        ]);
67
68        if (!$seat) {
69            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.");
70            return;
71        }
72
73        $this->perform(Calender::BLOCK_SEAT_RANGE, [
74            'pid'   => $processId,
75            'units' => $slotUnits,
76            'scope' => $scopeId,
77            'seat'  => $seat,
78            'start' => $start->format('Y-m-d H:i:s'),
79            'end'   => $end  ->format('Y-m-d H:i:s'),
80        ]);
81    }
82
83    public function unbook(int $scopeId, int $processId): void
84    {
85        $this->perform(Calender::UNBOOK_PROCESS, [
86            'scope_id' => $scopeId,
87            'process_id' => $processId,
88        ]);
89    }
90
91    public function readSlots(
92        array $scopeIds,
93        string $from,
94        string $until,
95        ?string $updatedAfter = null
96    ): array {
97        if (empty($scopeIds)) {
98            return [];
99        }
100
101        $in_list = implode(',', array_map('intval', $scopeIds));
102        $until = (new \DateTime($until))->modify('+1 day')->format('Y-m-d');
103
104        if ($updatedAfter === null) {
105            $sql = sprintf(Calender::SELECT_RANGE, $in_list);
106            $params = ['from' => $from, 'until' => $until];
107        } else {
108            $sql = sprintf(Calender::SELECT_RANGE_UPDATED, $in_list);
109            $params = [
110                'from'         => $from,
111                'until'        => $until,
112                'updatedAfter' => $updatedAfter
113            ];
114        }
115
116        return $this->fetchAll($sql, $params);
117    }
118}