Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
71 / 71
100.00% covered (success)
100.00%
13 / 13
CRAP
100.00% covered (success)
100.00%
1 / 1
DayList
100.00% covered (success)
100.00%
71 / 71
100.00% covered (success)
100.00%
13 / 13
32
100.00% covered (success)
100.00%
1 / 1
 getDay
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
8
 getDayByDateTime
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDayByDay
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasDay
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 withAssociatedDays
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 setStatusByType
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 withAddedDayList
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
3
 setSortByDate
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
1
 setSort
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
1
 hasDayWithAppointments
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getFirstBookableDay
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 withDaysInDateRange
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
4
 withDaysFromPeriod
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace BO\Zmsentities\Collection;
4
5use BO\Zmsentities\Day;
6
7/**
8 * @extends Base<\BO\Zmsentities\Day>
9 */
10class DayList extends Base implements JsonUnindexed
11{
12    public const ENTITY_CLASS = '\BO\Zmsentities\Day';
13
14    /**
15     * ATTENTION: Performance critical, keep highly optimized
16     *
17     */
18    public function getDay($year, $month, $dayNumber, $createDay = true)
19    {
20        $dateHash = Day::getCalculatedDayHash($dayNumber, $month, $year);
21        if ($this->offsetExists($dateHash)) {
22            return $this[$dateHash];
23        }
24        foreach ($this as $key => $day) {
25            if (!$day instanceof Day) {
26                $day = new Day($day);
27                $this[$key] = $day;
28            }
29            if ($day->day == $dayNumber && $day->month == $month && $day->year == $year) {
30                unset($this[$key]);
31                $this[$dateHash] = $day;
32                return $day;
33            }
34        }
35        if ($createDay) {
36            $day  = new \BO\Zmsentities\Day([
37                'year' => $year,
38                'month' => $month,
39                'day' => $dayNumber
40            ]);
41            $this[$dateHash] = $day;
42            return $day;
43        }
44        return null;
45    }
46
47    public function getDayByDateTime(\DateTimeInterface $datetime)
48    {
49        return $this->getDay($datetime->format('Y'), $datetime->format('m'), $datetime->format('d'));
50    }
51
52    public function getDayByDay(\BO\Zmsentities\Day $day)
53    {
54        return $this->getDay($day->year, $day->month, $day->day);
55    }
56
57
58    public function hasDay($year, $month, $dayNumber)
59    {
60        $day = $this->getDay($year, $month, $dayNumber, false);
61        return ($day === null) ? false : true;
62    }
63
64    public function withAssociatedDays($currentDate)
65    {
66        $dayList = new self();
67        $lastDay = $currentDate->format('t');
68        for ($dayNumber = 1; $dayNumber <= $lastDay; $dayNumber++) {
69            $day = str_pad($dayNumber, 2, '0', STR_PAD_LEFT);
70            $entity = $this->getDay($currentDate->format('Y'), $currentDate->format('m'), $day);
71            $dayList->addEntity($entity);
72        }
73        return $dayList->sortByCustomKey('day');
74    }
75
76    public function setStatusByType($slotType, \DateTimeInterface $dateTime)
77    {
78        foreach ($this as $day) {
79            $day->getWithStatus($slotType, $dateTime);
80        }
81        return $this;
82    }
83
84    public function withAddedDayList(DayList $dayList)
85    {
86        $merged = new DayList();
87        foreach ($dayList as $day) {
88            // @codeCoverageIgnoreStart
89            if (!$day instanceof Day) {
90                $day = new Day($day);
91            }
92            // @codeCoverageIgnoreEnd
93            $merged->addEntity($day->withAddedDay($this->getDayByDay($day)));
94        }
95        return $merged;
96    }
97
98    public function setSortByDate()
99    {
100        $this->uasort(function ($dayA, $dayB) {
101            return (
102                intval($dayA['year'] . $dayA['month'] . $dayA['day']) -
103                intval($dayB['year'] . $dayB['month'] . $dayB['day'])
104            );
105        });
106        return $this;
107    }
108
109    public function setSort($property = 'day')
110    {
111        $this->uasort(function ($dayA, $dayB) use ($property) {
112            return strnatcmp($dayA[$property], $dayB[$property]);
113        });
114        return $this;
115    }
116
117    public function hasDayWithAppointments()
118    {
119        foreach ($this as $day) {
120            $day = new Day($day);
121            if ($day->hasAppointments()) {
122                return true;
123            }
124        }
125        return false;
126    }
127
128    public function getFirstBookableDay()
129    {
130        foreach ($this as $day) {
131            $day = new Day($day);
132            if ($day->isBookable()) {
133                return $day->toDateTime();
134            }
135        }
136        return null;
137    }
138
139    public function withDaysInDateRange(\DateTimeInterface $startDate, \DateTimeInterface $endDate)
140    {
141        $list = new self();
142        foreach ($this as $day) {
143            if (
144                $day->toDateTime() >= $startDate->modify('00:00:00') &&
145                $day->toDateTime() <= $endDate->modify('23:59:59')
146            ) {
147                $list->addEntity($day);
148            }
149        }
150        return $list;
151    }
152
153    public function withDaysFromPeriod(\DateTimeInterface $startDate, \DateTimeInterface $endDate)
154    {
155        $list = new self();
156        do {
157            $day = (new Day())->setDateTime($startDate);
158            $list->addEntity($day);
159            $startDate = $startDate->modify('+1 day');
160        } while ($startDate <= $endDate);
161        return $list;
162    }
163}