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