Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
74 / 74
100.00% covered (success)
100.00%
14 / 14
CRAP
100.00% covered (success)
100.00%
1 / 1
ScopeList
100.00% covered (success)
100.00%
74 / 74
100.00% covered (success)
100.00%
14 / 14
43
100.00% covered (success)
100.00%
1 / 1
 getShortestBookableStart
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getGreatestBookableEnd
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getShortestBookableStartOnOpenedScope
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 getGreatestBookableEndOnOpenedScope
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 withoutDublicates
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 withUniqueScopes
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 addScopeList
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 withLessData
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 sortByName
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
3
 withProviderID
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
4
 addRequiredSlots
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 getRequiredSlotsByScope
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 hasOpenedScope
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
 getProviderList
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3namespace BO\Zmsentities\Collection;
4
5use BO\Zmsentities\Helper\Sorter;
6use BO\Zmsentities\Scope;
7
8/**
9 * @extends Base<\BO\Zmsentities\Scope>
10 */
11class ScopeList extends Base
12{
13    public const string ENTITY_CLASS = '\BO\Zmsentities\Scope';
14
15    protected $slotsByID = [];
16
17    /**
18    * Get shortest bookable start date of a scope in scopelist
19    *
20    * @return \DateTimeImmutable $date
21    */
22    public function getShortestBookableStart($now)
23    {
24        $date = $now;
25        foreach ($this as $scope) {
26            $startDate = $scope->getBookableStartDate($now);
27            $date = ($startDate > $date) ? $startDate : $date;
28        }
29        return $date;
30    }
31
32    /**
33    * Get longest bookable end date of a scope in scopelist
34    *
35    * @return \DateTimeImmutable $date
36    */
37    public function getGreatestBookableEnd($now)
38    {
39        $date = $now;
40        foreach ($this as $scope) {
41            $endDate = $scope->getBookableEndDate($now);
42            $date = ($endDate > $date) ? $endDate : $date;
43        }
44        return $date;
45    }
46
47    /**
48    * Get shortest bookable start date of a opened scope in scopelist
49    *
50    * @return \DateTimeImmutable $date, null
51    */
52    public function getShortestBookableStartOnOpenedScope($now)
53    {
54        $date = null;
55        foreach ($this as $scope) {
56            if ($scope->getStatus('availability', 'isOpened')) {
57                $date = $now;
58                $startDate = $scope->getBookableStartDate($date);
59                $date = ($startDate > $date) ? $startDate : $date;
60            }
61        }
62        return $date;
63    }
64
65    /**
66    * Get longest bookable end date of a opened scope in scopelist
67    *
68    * @return \DateTimeImmutable $date
69    */
70    public function getGreatestBookableEndOnOpenedScope($now)
71    {
72        $date = null;
73        foreach ($this as $scope) {
74            if ($scope->getStatus('availability', 'isOpened')) {
75                $date = $now;
76                $endDate = $scope->getBookableEndDate($date);
77                $date = ($endDate > $date) ? $endDate : $date;
78            }
79        }
80        return $date;
81    }
82
83    public function withoutDublicates($scopeList = null): self
84    {
85        $collection = new self();
86        foreach ($this as $scope) {
87            if (! $scopeList || ! $scopeList->hasEntity($scope->getId())) {
88                $collection->addEntity(clone $scope);
89            }
90        }
91        return $collection;
92    }
93
94    public function withUniqueScopes(): self
95    {
96        $scopeList = new self();
97        foreach ($this as $scope) {
98            if ($scope->getId() && ! $scopeList->hasEntity($scope->getId())) {
99                $scopeList->addEntity(clone $scope);
100            }
101        }
102        return $scopeList;
103    }
104
105    public function addScopeList($scopeList): static
106    {
107        foreach ($scopeList as $scope) {
108            $this->addEntity($scope);
109        }
110        return $this;
111    }
112
113    /**
114     * @return self
115     */
116    #[\Override]
117    public function withLessData(array $keepArray = [])
118    {
119        $scopeList = new self();
120        foreach ($this as $scope) {
121            $scopeList->addEntity(clone $scope->withLessData($keepArray));
122        }
123        return $scopeList;
124    }
125
126    /**
127     * @return static
128     */
129    #[\Override]
130    public function sortByName()
131    {
132        $this->uasort(function ($a, $b) {
133            $nameA = (isset($a->provider['name'])) ? $a->provider['name'] : ($a->shortName ?? '');
134            $nameB = (isset($b->provider['name'])) ? $b->provider['name'] : ($b->shortName ?? '');
135            return strcmp(
136                Sorter::toSortableString(ucfirst($nameA ?? '')),
137                Sorter::toSortableString(ucfirst($nameB ?? ''))
138            );
139        });
140        return $this;
141    }
142
143    public function withProviderID($source, $providerID): self
144    {
145        $list = new ScopeList();
146        foreach ($this as $scope) {
147            if ($scope->provider['source'] == $source && $scope->provider['id'] == $providerID) {
148                $list->addEntity(clone $scope);
149            }
150        }
151        return $list;
152    }
153
154    public function addRequiredSlots($source, $providerID, $slotsRequired): static
155    {
156        $scopeList = $this->withProviderID($source, $providerID);
157        foreach ($scopeList as $scope) {
158            if (!isset($this->slotsByID[$scope->id])) {
159                $this->slotsByID[$scope->id] = 0;
160            }
161            $this->slotsByID[$scope->id] += $slotsRequired;
162        }
163        return $this;
164    }
165
166    public function getRequiredSlotsByScope(Scope $scope)
167    {
168        if (isset($this->slotsByID[$scope->id])) {
169            return $this->slotsByID[$scope->id];
170        }
171        return 0;
172    }
173
174    public function hasOpenedScope(): bool
175    {
176        $isOpened = false;
177        foreach ($this as $entity) {
178            if ($entity->getStatus('availability', 'isOpened')) {
179                $isOpened = true;
180            }
181        }
182        return $isOpened;
183    }
184
185    public function getProviderList()
186    {
187        $list = new ProviderList();
188        foreach ($this as $scope) {
189            $provider = $scope->getProvider();
190            $list->addEntity($provider);
191        }
192        return $list->withUniqueProvider();
193    }
194}