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