Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
99.42% covered (success)
99.42%
170 / 171
95.83% covered (success)
95.83%
23 / 24
CRAP
0.00% covered (danger)
0.00%
0 / 1
Calendar
99.42% covered (success)
99.42%
170 / 171
95.83% covered (success)
95.83%
23 / 24
57
0.00% covered (danger)
0.00%
0 / 1
 getDefaults
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
 addDates
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 addFirstAndLastDay
100.00% covered (success)
100.00%
15 / 15
100.00% covered (success)
100.00%
1 / 1
1
 addProvider
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 addCluster
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 addRequest
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
3
 addScope
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 getScopeList
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 getRequestList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getProviderList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getDayList
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasDay
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDay
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDayByDateTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDateTimeFromDate
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasFirstAndLastDay
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getFirstDay
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 getLastDay
91.67% covered (success)
91.67%
11 / 12
0.00% covered (danger)
0.00%
0 / 1
4.01
 setLastDayTime
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 setFirstDayTime
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 getMonthList
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
2
 withLessData
100.00% covered (success)
100.00%
16 / 16
100.00% covered (success)
100.00%
1 / 1
5
 withFilledEmptyDays
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
4
 __toString
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
1<?php
2
3namespace BO\Zmsentities;
4
5/**
6 *
7 * @SuppressWarnings(CouplingBetweenObjects)
8 * @SuppressWarnings(TooManyPublicMethods)
9 * @SuppressWarnings(Complexity)
10 */
11class Calendar extends Schema\Entity
12{
13    public const PRIMARY = 'days';
14
15    public static $schema = "calendar.json";
16
17    #[\Override]
18    public function getDefaults()
19    {
20        return [
21            'firstDay' => new Day(),
22            'lastDay' => null,
23            'days' => new Collection\DayList(),
24            'clusters' => [ ],
25            'providers' => [ ],
26            'scopes' => [ ],
27            'requests' => [ ]
28        ];
29    }
30
31    public function addDates($date, \DateTimeInterface $now, $timeZone)
32    {
33        $validDate = \BO\Mellon\Validator::value($date)->isDate();
34        $date = (! $validDate->hasFailed()) ? $validDate->getValue() : $now->format('U');
35        if (! $this->toProperty()->firstDay->day->get()) {
36            $this->addFirstAndLastDay($date, $timeZone);
37        }
38        return $this;
39    }
40
41    /**
42     * Returns calendar with first and last day
43     *
44     * @return $this
45     */
46    public function addFirstAndLastDay($date, $timeZone)
47    {
48        $timeZone = new \DateTimeZone($timeZone);
49        $dateTime = Helper\DateTime::create()->setTimezone($timeZone)->setTimestamp($date);
50        $firstDay = $dateTime->setTime(0, 0, 0);
51        $lastDay = $dateTime->modify('last day of next month')->setTime(23, 59, 59);
52        $this->firstDay = array(
53            'year' => $firstDay->format('Y'),
54            'month' => $firstDay->format('m'),
55            'day' => $firstDay->format('d')
56        );
57        $this->lastDay = array(
58            'year' => $lastDay->format('Y'),
59            'month' => $lastDay->format('m'),
60            'day' => $lastDay->format('d')
61        );
62        return $this;
63    }
64
65    /**
66     * Returns calendar with added Providers
67     *
68     * @return $this
69     */
70    public function addProvider($source, $idList)
71    {
72        foreach (explode(',', $idList) as $id) {
73            if ($id) {
74                $provider = new Provider();
75                $provider->source = $source;
76                $provider->id = $id;
77                $this->providers[] = $provider;
78            }
79        }
80        return $this;
81    }
82
83    /**
84     * Returns calendar with added Clusters
85     *
86     * @return $this
87     */
88    public function addCluster($idList)
89    {
90        foreach (explode(',', $idList) as $id) {
91            $cluster = new Cluster();
92            $cluster->id = $id;
93            $this->clusters[] = $cluster;
94        }
95        return $this;
96    }
97
98    /**
99     * Returns calendar with added requests
100     *
101     * @return $this
102     */
103    public function addRequest($source, $requestList)
104    {
105        foreach (explode(',', $requestList) as $id) {
106            if ($id) {
107                $request = new Request();
108                $request->source = $source;
109                $request->id = $id;
110                $this->requests[] = $request;
111            }
112        }
113        return $this;
114    }
115
116    /**
117     * Returns calendar with added scopes
118     *
119     * @return $this
120     */
121    public function addScope($scopeList)
122    {
123        foreach (explode(',', $scopeList) as $id) {
124            if ($id) {
125                $scope = new Scope();
126                $scope->id = $id;
127                $this->scopes[] = $scope;
128            }
129        }
130        return $this;
131    }
132
133    /**
134     * Returns a list of associated scope ids
135     *
136     * @return array
137     */
138    public function getScopeList()
139    {
140        $scopeList = new \BO\Zmsentities\Collection\ScopeList();
141        if (isset($this->scopes)) {
142            foreach ($this->scopes as $scope) {
143                $scope = new Scope($scope);
144                $scopeList->addEntity($scope);
145            }
146        }
147        return $scopeList;
148    }
149
150    /**
151     * Returns a list of associated request entities
152     *
153     * @return array
154     */
155    public function getRequestList()
156    {
157        $requestList = new \BO\Zmsentities\Collection\RequestList();
158        foreach ($this->requests as $request) {
159            $request = new Request($request);
160            $requestList->addEntity($request);
161        }
162        return $requestList;
163    }
164
165    /**
166     * Returns a list of associated provider ids
167     *
168     * @return array
169     */
170    public function getProviderList()
171    {
172        $providerList = new \BO\Zmsentities\Collection\ProviderList();
173        foreach ($this->providers as $provider) {
174            $entity = new Provider($provider);
175            $providerList->addEntity($entity);
176        }
177        return $providerList;
178    }
179
180    public function getDayList()
181    {
182        if (!$this->days instanceof Collection\DayList) {
183            $this->days = new Collection\DayList($this->days);
184        }
185        return $this->days->setSortByDate();
186    }
187
188    /**
189     * Check if given day exists in calendar
190     *
191     * @return bool
192     */
193    public function hasDay($year, $month, $dayNumber)
194    {
195        return $this->getDayList()->hasDay($year, $month, $dayNumber);
196    }
197
198    /**
199     * Returns a day by given year, month and daynumber
200     *
201     * @return \ArrayObject
202     */
203    public function getDay($year, $month, $dayNumber)
204    {
205        return $this->getDayList()->getDay($year, $month, $dayNumber);
206    }
207
208    public function getDayByDateTime(\DateTimeInterface $datetime)
209    {
210        return $this->getDayList()->getDayByDateTime($datetime);
211    }
212
213    public function getDateTimeFromDate($date)
214    {
215        $day = (isset($date['day'])) ? $date['day'] : 1;
216        $date = Helper\DateTime::createFromFormat('Y-m-d', $date['year'] . '-' . $date['month'] . '-' . $day);
217        return Helper\DateTime::create($date);
218    }
219
220    /**
221     * Simple quick check, if first and last day are defined
222     *
223     */
224    public function hasFirstAndLastDay()
225    {
226        if (!$this->toProperty()->firstDay->day->get()) {
227            return false;
228        }
229        if (!$this->toProperty()->lastDay->day->get()) {
230            return false;
231        }
232        return true;
233    }
234
235    public function getFirstDay()
236    {
237        if (isset($this['firstDay'])) {
238            $dateTime = $this->getDateTimeFromDate(
239                array(
240                    'year' => $this['firstDay']['year'],
241                    'month' => $this['firstDay']['month'],
242                    'day' => $this['firstDay']['day']
243                )
244            );
245        } else {
246            $dateTime = Helper\DateTime::create();
247        }
248        return $dateTime->modify('00:00:00');
249    }
250
251    public function getLastDay($createIfNotProvided = true)
252    {
253        if (! $createIfNotProvided && ! isset($this['lastDay'])) {
254            return null;
255        }
256
257        if (isset($this['lastDay'])) {
258            $dateTime = $this->getDateTimeFromDate(
259                array(
260                    'year' => $this['lastDay']['year'],
261                    'month' => $this['lastDay']['month'],
262                    'day' => $this['lastDay']['day']
263                )
264            );
265        } else {
266            $dateTime = Helper\DateTime::create();
267        }
268        return $dateTime->modify('23:59:59');
269    }
270
271    public function setLastDayTime($date)
272    {
273        $day = new Day();
274        $day->setDateTime($date);
275        $this['lastDay'] = $day;
276        return $this;
277    }
278
279    public function setFirstDayTime($date)
280    {
281        $day = new Day();
282        $day->setDateTime($date);
283        $this['firstDay'] = $day;
284        return $this;
285    }
286
287    /**
288     * Returns a list of contained month given by firstDay and lastDay
289     * The return value is a month entity object for the first day of the month
290     *
291     * @return [\DateTime]
292     */
293    public function getMonthList()
294    {
295        $firstDay = $this->getFirstDay()->modify('first day of this month')->modify('00:00:00');
296        $lastDay = $this->getLastDay()->modify('last day of this month')->modify('23:59:59');
297        $currentDate = $firstDay;
298        if ($firstDay->getTimestamp() > $lastDay->getTimestamp()) {
299            // switch first and last day if necessary
300            $currentDate = $lastDay;
301            $lastDay = $firstDay;
302        }
303        $monthList = new Collection\MonthList();
304        do {
305            $monthList->addEntity(Month::createForDateFromDayList($currentDate, $this->days));
306            $currentDate = $currentDate->modify('+1 month');
307        } while ($currentDate->getTimestamp() < $lastDay->getTimestamp());
308        return $monthList;
309    }
310
311    /**
312     * Reduce data of dereferenced entities to a required minimum
313     *
314     */
315    #[\Override]
316    public function withLessData()
317    {
318        $entity = clone $this;
319
320        foreach ($entity['scopes'] as $scope) {
321            if ($scope->toProperty()->provider->data->isAvailable()) {
322                $payment = $scope->toProperty()->provider->data->payment->get();
323                unset($scope['provider']['data']);
324                $scope['provider']['data'] = ['payment' => $payment];
325                unset($scope['dayoff']);
326                unset($scope['status']);
327                unset($scope['preferences']);
328            }
329        }
330        foreach ($entity['days'] as $day) {
331            if (isset($day['allAppointments'])) {
332                unset($day['allAppointments']);
333            }
334        }
335        unset($entity['providers']);
336        unset($entity['clusters']);
337        unset($entity['freeProcesses']);
338        return $entity;
339    }
340
341    public function withFilledEmptyDays()
342    {
343        $entity = clone $this;
344
345        $firstDay = $this->getFirstDay()->modify('first day of this month')->modify('00:00:00');
346        $lastDay = $this->getLastDay()->modify('last day of this month')->modify('23:59:59');
347        $currentDate = $firstDay;
348        $dayList = new Collection\DayList($entity->days);
349
350        do {
351            $day = new Day([
352                'year' => $currentDate->format('Y'),
353                'month' => $currentDate->format('m'),
354                'day' => $currentDate->format('d')
355            ]);
356            $dayTimestamp = $day->toDateTime()->getTimestamp();
357            $dayFound = false;
358
359            foreach ($dayList as $checkingDay) {
360                $checkingTimestamp = $checkingDay->toDateTime()->getTimestamp();
361                if ($checkingTimestamp === $dayTimestamp) {
362                    $dayFound = true;
363                }
364            }
365
366            if (!$dayFound) {
367                $dayList->addEntity($day);
368            }
369
370            $currentDate = $currentDate->modify('+1 day');
371        } while ($currentDate->getTimestamp() < $lastDay->getTimestamp());
372
373        $entity->days = $dayList;
374
375        return $entity;
376    }
377
378    public function __toString()
379    {
380        $string = '';
381        foreach ($this->days as $day) {
382            $day = ($day instanceof Day) ? $day : new Day($day);
383            $string .= "$day\n";
384        }
385        foreach ($this->scopes as $scope) {
386            $scope = ($scope instanceof Scope) ? $scope : new Scope($scope);
387            $string .= "$scope\n";
388        }
389        return $string;
390    }
391}