Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
39.53% |
34 / 86 |
|
50.00% |
1 / 2 |
CRAP | |
0.00% |
0 / 1 |
OverallCalendarRead | |
39.53% |
34 / 86 |
|
50.00% |
1 / 2 |
72.59 | |
0.00% |
0 / 1 |
buildCalendar | |
11.86% |
7 / 59 |
|
0.00% |
0 / 1 |
169.04 | |||
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 | $time[$seatNo]['init'] = true; |
34 | |
35 | if ($row['status'] === 'termin') { |
36 | if ($row['slots'] !== null) { |
37 | $time[$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 | $info = $lastSlotInfo["$scopeKey|$seatNo"] ?? null; |
48 | if ($info && $info['openSlots'] > 0) { |
49 | $time[$seatNo] = ['status' => 'skip']; |
50 | $lastSlotInfo["$scopeKey|$seatNo"]['openSlots']--; |
51 | |
52 | if ($lastSlotInfo["$scopeKey|$seatNo"]['openSlots'] <= 0) { |
53 | unset($lastSlotInfo["$scopeKey|$seatNo"]); |
54 | } |
55 | } else { |
56 | $time[$seatNo] = ['status' => 'skip']; |
57 | } |
58 | } |
59 | } else { |
60 | $info = $lastSlotInfo["$scopeKey|$seatNo"] ?? null; |
61 | if ($info && $info['openSlots'] > 0) { |
62 | $time[$seatNo] = ['status' => 'skip']; |
63 | $lastSlotInfo["$scopeKey|$seatNo"]['openSlots']--; |
64 | |
65 | if ($lastSlotInfo["$scopeKey|$seatNo"]['openSlots'] <= 0) { |
66 | unset($lastSlotInfo["$scopeKey|$seatNo"]); |
67 | } |
68 | } else { |
69 | $time[$seatNo] = ['status' => 'open']; |
70 | unset($lastSlotInfo["$scopeKey|$seatNo"]); |
71 | } |
72 | } |
73 | } |
74 | |
75 | foreach ($calendar as &$day) { |
76 | foreach ($day['scopes'] as &$scope) { |
77 | foreach ($scope['times'] as $timeKey => $slotInfo) { |
78 | for ($seatNumber = 1; $seatNumber <= $scope['maxSeats']; $seatNumber++) { |
79 | if (!isset($slotInfo['seats'][$seatNumber])) { |
80 | $slotInfo['seats'][$seatNumber] = ['status' => 'open']; |
81 | } |
82 | } |
83 | ksort($slotInfo['seats']); |
84 | |
85 | $scope['times'][$timeKey] = [ |
86 | 'name' => $timeKey, |
87 | 'seats' => array_values($slotInfo['seats']), |
88 | ]; |
89 | } |
90 | $scope['times'] = array_values($scope['times']); |
91 | } |
92 | $day['scopes'] = array_values($day['scopes']); |
93 | } |
94 | uksort($calendar, function ($a, $b) { |
95 | return strcmp($a, $b); |
96 | }); |
97 | return ['days' => array_values($calendar)]; |
98 | } |
99 | |
100 | public function readResponse( |
101 | \Psr\Http\Message\RequestInterface $request, |
102 | \Psr\Http\Message\ResponseInterface $response, |
103 | array $args |
104 | ) { |
105 | (new Helper\User($request))->checkRights('useraccount'); |
106 | $scopeIdCsv = Validator::param('scopeIds') |
107 | ->isString()->isMatchOf('/^\d+(,\d+)*$/')->assertValid()->getValue(); |
108 | $scopeIds = array_map('intval', explode(',', $scopeIdCsv)); |
109 | |
110 | $dateFrom = Validator::param('dateFrom')->isDate('Y-m-d')->assertValid()->getValue(); |
111 | $dateUntil = Validator::param('dateUntil')->isDate('Y-m-d')->assertValid()->getValue(); |
112 | $updateAfter = Validator::param('updateAfter')->isDatetime()->setDefault(null)->getValue(); |
113 | |
114 | $flatRows = (new CalendarQuery())->readSlots( |
115 | $scopeIds, |
116 | $dateFrom, |
117 | $dateUntil, |
118 | $updateAfter |
119 | ); |
120 | |
121 | $structured = $this->buildCalendar($flatRows); |
122 | |
123 | $msg = Response\Message::create($request); |
124 | $msg->data = $structured; |
125 | $msg->meta->rows = count($flatRows); |
126 | |
127 | $response = Render::withLastModified( |
128 | $response, |
129 | (new DateTimeImmutable())->getTimestamp(), |
130 | '0' |
131 | ); |
132 | return Render::withJson( |
133 | $response, |
134 | $msg->setUpdatedMetaData(), |
135 | $msg->getStatuscode() |
136 | ); |
137 | } |
138 | } |