Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
39.29% |
33 / 84 |
|
50.00% |
1 / 2 |
CRAP | |
0.00% |
0 / 1 |
OverallCalendarRead | |
39.29% |
33 / 84 |
|
50.00% |
1 / 2 |
38.08 | |
0.00% |
0 / 1 |
buildCalendar | |
10.53% |
6 / 57 |
|
0.00% |
0 / 1 |
81.63 | |||
readResponse | |
100.00% |
27 / 27 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace BO\Zmsapi; |
4 | |
5 | use BO\Slim\Render; |
6 | use BO\Mellon\Validator; |
7 | use BO\Zmsdb\OverallCalendar as CalendarQuery; |
8 | use DateTimeImmutable; |
9 | use DateTimeInterface; |
10 | |
11 | class OverallCalendarRead extends BaseController |
12 | { |
13 | private function buildCalendar(array $rows, int $defaultSeats = 1): array |
14 | { |
15 | $calendar = []; |
16 | $lastSlotInfo = []; |
17 | |
18 | foreach ($rows as $row) { |
19 | $dateKey = (new DateTimeImmutable($row['time']))->format('Y-m-d'); |
20 | $timeKey = (new DateTimeImmutable($row['time']))->format('H:i'); |
21 | $scopeKey = (int)$row['scope_id']; |
22 | $seatNo = (int)$row['seat']; |
23 | |
24 | $day =& $calendar[$dateKey]; |
25 | $scope =& $day['scopes'][$scopeKey]; |
26 | $time =& $scope['times'][$timeKey]['seats']; |
27 | |
28 | $day['date'] = (new DateTimeImmutable($dateKey))->getTimestamp(); |
29 | $scope['id'] = $scopeKey; |
30 | $scope['name'] = $row['scope_name']; |
31 | $scope['shortName'] = $row['scope_short']; |
32 | $scope['maxSeats'] = max($scope['maxSeats'] ?? 0, $seatNo, $defaultSeats); |
33 | |
34 | if ($row['status'] === 'termin') { |
35 | if ($row['slots'] !== null) { |
36 | $time[$seatNo] = [ |
37 | 'seatNo' => $seatNo, |
38 | 'status' => 'termin', |
39 | 'processId' => (int) $row['process_id'], |
40 | 'slots' => (int) $row['slots'], |
41 | ]; |
42 | $lastSlotInfo["$scopeKey|$seatNo"] = [ |
43 | 'processId' => (int) $row['process_id'], |
44 | 'openSlots' => (int) $row['slots'] - 1, |
45 | ]; |
46 | } else { |
47 | $time[$seatNo] = [ |
48 | 'seatNo' => $seatNo, |
49 | 'status' => 'skip' |
50 | ]; |
51 | $info = $lastSlotInfo["$scopeKey|$seatNo"] ?? null; |
52 | if ($info && --$info['openSlots'] <= 0) { |
53 | unset($lastSlotInfo["$scopeKey|$seatNo"]); |
54 | } else { |
55 | $lastSlotInfo["$scopeKey|$seatNo"] = $info; |
56 | } |
57 | } |
58 | } elseif ($row['status'] === 'cancelled') { |
59 | $time[$seatNo] = [ |
60 | 'seatNo' => $seatNo, |
61 | 'status' => 'cancelled' |
62 | ]; |
63 | unset($lastSlotInfo["$scopeKey|$seatNo"]); |
64 | } else { |
65 | $time[$seatNo] = [ |
66 | 'seatNo' => $seatNo, |
67 | 'status' => 'open' |
68 | ]; |
69 | } |
70 | } |
71 | |
72 | foreach ($calendar as &$day) { |
73 | foreach ($day['scopes'] as &$scope) { |
74 | foreach ($scope['times'] as $timeKey => $slotInfo) { |
75 | ksort($slotInfo['seats']); |
76 | $scope['times'][$timeKey] = [ |
77 | 'name' => $timeKey, |
78 | 'seats' => array_values($slotInfo['seats']), |
79 | ]; |
80 | } |
81 | $scope['times'] = array_values($scope['times']); |
82 | } |
83 | $day['scopes'] = array_values($day['scopes']); |
84 | } |
85 | uksort($calendar, fn($a, $b) => strcmp($a, $b)); |
86 | |
87 | return ['days' => array_values($calendar)]; |
88 | } |
89 | |
90 | public function readResponse( |
91 | \Psr\Http\Message\RequestInterface $request, |
92 | \Psr\Http\Message\ResponseInterface $response, |
93 | array $args |
94 | ) { |
95 | (new Helper\User($request))->checkRights('useraccount'); |
96 | $scopeIdCsv = Validator::param('scopeIds') |
97 | ->isString()->isMatchOf('/^\d+(,\d+)*$/')->assertValid()->getValue(); |
98 | $scopeIds = array_map('intval', explode(',', $scopeIdCsv)); |
99 | |
100 | $dateFrom = Validator::param('dateFrom')->isDate('Y-m-d')->assertValid()->getValue(); |
101 | $dateUntil = Validator::param('dateUntil')->isDate('Y-m-d')->assertValid()->getValue(); |
102 | $updateAfter = Validator::param('updateAfter')->isDatetime()->setDefault(null)->getValue(); |
103 | |
104 | $flatRows = (new CalendarQuery())->readSlots( |
105 | $scopeIds, |
106 | $dateFrom, |
107 | $dateUntil, |
108 | $updateAfter |
109 | ); |
110 | |
111 | $structured = $this->buildCalendar($flatRows); |
112 | |
113 | $msg = Response\Message::create($request); |
114 | $msg->data = $structured; |
115 | $msg->meta->rows = count($flatRows); |
116 | |
117 | $response = Render::withLastModified( |
118 | $response, |
119 | (new DateTimeImmutable())->getTimestamp(), |
120 | '0' |
121 | ); |
122 | return Render::withJson( |
123 | $response, |
124 | $msg->setUpdatedMetaData(), |
125 | $msg->getStatuscode() |
126 | ); |
127 | } |
128 | } |