Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
86.30% |
126 / 146 |
|
93.75% |
15 / 16 |
CRAP | |
0.00% |
0 / 1 |
Exchange | |
86.30% |
126 / 146 |
|
93.75% |
15 / 16 |
97.87 | |
0.00% |
0 / 1 |
getDefaults | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
setPeriod | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
addDictionaryEntry | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 | |||
addDataSet | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
4 | |||
withLessData | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
getPositionByName | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
5 | |||
withCalculatedTotals | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
7 | |||
withMaxByHour | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
8 | |||
withRequestsSum | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
6 | |||
withAverage | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
132 | |||
withMaxAndAverageFromWaitingTime | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
10 | |||
getCalculatedTotals | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
4 | |||
toHashed | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getHashData | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
8 | |||
toGrouped | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
1 | |||
getGroupedHashSet | |
100.00% |
18 / 18 |
|
100.00% |
1 / 1 |
9 |
1 | <?php |
2 | |
3 | namespace BO\Zmsentities; |
4 | |
5 | /** |
6 | * @SuppressWarnings(Complexity) |
7 | * @SuppressWarnings(PublicMethod) |
8 | * |
9 | */ |
10 | class Exchange extends Schema\Entity |
11 | { |
12 | const PRIMARY = 'firstDay'; |
13 | |
14 | public static $schema = "exchange.json"; |
15 | |
16 | public function getDefaults() |
17 | { |
18 | return [ |
19 | 'firstDay' => new Day(), |
20 | 'lastDay' => new Day(), |
21 | 'period' => 'day', |
22 | 'dictionary' => [ ], |
23 | 'data' => [ ] |
24 | ]; |
25 | } |
26 | |
27 | public function setPeriod(\DateTimeInterface $firstDay, \DateTimeInterface $lastDay, $period = 'day') |
28 | { |
29 | $this->firstDay = (new Day())->setDateTime($firstDay); |
30 | $this->lastDay = (new Day())->setDateTime($lastDay); |
31 | $this->period = $period; |
32 | return $this; |
33 | } |
34 | |
35 | public function addDictionaryEntry($variable, $type = 'string', $description = '', $reference = '') |
36 | { |
37 | $position = count($this['dictionary']); |
38 | $this['dictionary'][$position] = [ |
39 | 'position' => $position, |
40 | 'variable' => $variable, |
41 | 'type' => $type, |
42 | 'description' => $description, |
43 | 'reference' => $reference |
44 | ]; |
45 | return $this; |
46 | } |
47 | |
48 | public function addDataSet($values) |
49 | { |
50 | if (!is_array($values) && !$values instanceof \Traversable) { |
51 | throw new \Exception("Values have to be of type array"); |
52 | } |
53 | if (count($this->dictionary) != count($values)) { |
54 | throw new \Exception("Mismatching dictionary settings for values (count mismatch)"); |
55 | } |
56 | $this->data[] = $values; |
57 | } |
58 | |
59 | public function withLessData() |
60 | { |
61 | $entity = clone $this; |
62 | if (isset($entity['firstDay'])) { |
63 | unset($entity['firstDay']); |
64 | } |
65 | if (isset($entity['lastDay'])) { |
66 | unset($entity['lastDay']); |
67 | } |
68 | if (isset($entity['period'])) { |
69 | unset($entity['period']); |
70 | } |
71 | return $entity; |
72 | } |
73 | |
74 | public function getPositionByName($name) |
75 | { |
76 | if (isset($this->dictionary)) { |
77 | foreach ($this->dictionary as $entry) { |
78 | if (isset($entry['variable']) && $entry['variable'] == $name) { |
79 | return $entry['position']; |
80 | } |
81 | } |
82 | } |
83 | return false; |
84 | } |
85 | |
86 | public function withCalculatedTotals(array $keysToCalculate = ['count'], $dateName = 'name') |
87 | { |
88 | $entity = clone $this; |
89 | $namePosition = $this->getPositionByName($dateName); |
90 | if ($namePosition) { |
91 | $totals = array_fill(0, count($entity->data[0]), 0); |
92 | $totals[$namePosition] = 'totals'; |
93 | foreach ($keysToCalculate as $name) { |
94 | $calculatePosition = $this->getPositionByName($name); |
95 | foreach ($this->data as $item) { |
96 | foreach ($item as $position => $data) { |
97 | if (is_numeric($data) && $calculatePosition == $position) { |
98 | $totals[$position] += $data; |
99 | } |
100 | } |
101 | } |
102 | } |
103 | $entity->addDataSet($totals); |
104 | } |
105 | return $entity; |
106 | } |
107 | |
108 | public function withMaxByHour(array $keysToCalculate = ['count']) |
109 | { |
110 | $entity = clone $this; |
111 | $maxima = []; |
112 | foreach ($entity->data as $dateItems) { |
113 | foreach ($dateItems as $hour => $hourItems) { |
114 | foreach ($hourItems as $key => $value) { |
115 | if (is_numeric($value) && in_array($key, $keysToCalculate)) { |
116 | $maxima[$hour][$key] = ( |
117 | isset($maxima[$hour][$key]) && $maxima[$hour][$key] > $value |
118 | ) ? $maxima[$hour][$key] : $value; |
119 | } |
120 | } |
121 | } |
122 | $entity->data['max'] = $maxima; |
123 | } |
124 | return $entity; |
125 | } |
126 | |
127 | public function withRequestsSum($keysToCalculate = ['requestscount']) |
128 | { |
129 | $entity = clone $this; |
130 | $sum = []; |
131 | foreach ($entity->data as $name => $entry) { |
132 | $sum[$name] = 0; |
133 | foreach ($entry as $dateItem) { |
134 | foreach ($dateItem as $key => $value) { |
135 | if (is_numeric($value) && in_array($key, $keysToCalculate)) { |
136 | $sum[$name] += $value; |
137 | } |
138 | } |
139 | } |
140 | } |
141 | $entity->data['sum'] = $sum; |
142 | return $entity; |
143 | } |
144 | |
145 | public function withAverage($keyToCalculate) |
146 | { |
147 | $entity = clone $this; |
148 | $average = []; |
149 | |
150 | foreach ($entity->data as $name => $entry) { |
151 | if (!is_array($entry) && !($entry instanceof \Traversable)) { |
152 | // Skip or handle non-iterable $entry appropriately. |
153 | continue; |
154 | } |
155 | |
156 | $average[$name . '_sum'] = 0; |
157 | $average[$name . '_count'] = 0; |
158 | |
159 | foreach ($entry as $dateItem) { |
160 | if (!is_array($dateItem) && !($dateItem instanceof \Traversable)) { |
161 | // Skip or handle non-iterable $dateItem appropriately. |
162 | continue; |
163 | } |
164 | |
165 | foreach ($dateItem as $key => $value) { |
166 | if (!is_numeric($value) || $key !== $keyToCalculate) { |
167 | // Skip non-numeric values or when the key doesn't match. |
168 | continue; |
169 | } |
170 | |
171 | $average[$name . '_sum'] += $value; |
172 | $average[$name . '_count']++; |
173 | } |
174 | } |
175 | |
176 | $average[$name] = $average[$name . '_count'] > 0 |
177 | ? round($average[$name . '_sum'] / $average[$name . '_count'], 2) |
178 | : null; |
179 | } |
180 | |
181 | $entity->data['average_' . $keyToCalculate] = $average; |
182 | return $entity; |
183 | } |
184 | |
185 | |
186 | public function withMaxAndAverageFromWaitingTime() |
187 | { |
188 | $entity = clone $this; |
189 | foreach ($entity->data as $date => $dateItems) { |
190 | $maxima = 0; |
191 | $total = 0; |
192 | $count = 0; |
193 | foreach ($dateItems as $hourItems) { |
194 | foreach ($hourItems as $key => $value) { |
195 | if (is_numeric($value) && 'waitingtime' == $key && 0 < $value) { |
196 | $total += $value; |
197 | $count += 1; |
198 | $maxima = ($maxima > $value) ? $maxima : $value; |
199 | } |
200 | } |
201 | } |
202 | $entity->data[$date]['max'] = $maxima; |
203 | $entity->data[$date]['average'] = (! $total || ! $count) ? 0 : floor($total / $count); |
204 | } |
205 | return $entity; |
206 | } |
207 | |
208 | public function getCalculatedTotals() |
209 | { |
210 | foreach (array_reverse($this->data) as $item) { |
211 | foreach ($item as $data) { |
212 | if ($data == 'totals') { |
213 | return $item; |
214 | } |
215 | } |
216 | } |
217 | return null; |
218 | } |
219 | |
220 | public function toHashed(array $hashfields = []) |
221 | { |
222 | $entity = clone $this; |
223 | $entity->data = $this->getHashData($hashfields); |
224 | unset($entity->dictionary); |
225 | return $entity; |
226 | } |
227 | |
228 | public function getHashData(array $hashfields = [], $first = false) |
229 | { |
230 | $hash = []; |
231 | foreach ($this->dictionary as $entry) { |
232 | foreach ($this->data as $key => $item) { |
233 | foreach ($item as $position => $data) { |
234 | if ($entry['position'] == $position) { |
235 | if (count($hashfields) && in_array($entry['variable'], $hashfields)) { |
236 | $hash[$key][$entry['variable']] = $data; |
237 | } else { |
238 | $hash[$key][$entry['variable']] = $data; |
239 | } |
240 | } |
241 | } |
242 | } |
243 | } |
244 | return ($first) ? reset($hash) : $hash; |
245 | } |
246 | |
247 | public function toGrouped(array $fields, array $hashfields) |
248 | { |
249 | $entity = clone $this; |
250 | $entity->data = $this->getGroupedHashSet($fields, $hashfields); |
251 | unset($entity->dictionary); |
252 | return $entity; |
253 | } |
254 | |
255 | public function getGroupedHashSet(array $fields, array $hashfields) |
256 | { |
257 | $list = []; |
258 | if (count($fields)) { |
259 | $field = array_shift($fields); |
260 | $fieldposition = $this->getPositionByName($field); |
261 | |
262 | $requestscountPosition = $this->getPositionByName('requestscount'); |
263 | |
264 | |
265 | foreach ($this->data as $element) { |
266 | if (isset($element[$fieldposition])) { |
267 | if (!isset($list[$element[$fieldposition]])) { |
268 | $list[$element[$fieldposition]] = clone $this; |
269 | $list[$element[$fieldposition]]->data = []; |
270 | } |
271 | if ($requestscountPosition !== false && isset($element[$requestscountPosition])) { |
272 | $element[$requestscountPosition] = (int) $element[$requestscountPosition]; |
273 | } |
274 | |
275 | $list[$element[$fieldposition]]->data[] = $element; |
276 | } |
277 | } |
278 | |
279 | foreach ($list as $key => $row) { |
280 | if ($row instanceof Exchange) { |
281 | $list[$key] = $row->getGroupedHashSet($fields, $hashfields); |
282 | } |
283 | } |
284 | } else { |
285 | return $this->getHashData($hashfields, true); |
286 | } |
287 | return $list; |
288 | } |
289 | } |