Completed
Push — master ( 8f5bc0...179bc9 )
by WEBEWEB
03:06
created

TimeSlotHelper   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 237
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 33
lcom 1
cbo 4
dl 0
loc 237
rs 9.76
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A contains() 0 5 2
B equals() 0 27 6
A fullJoin() 0 14 2
A fullJoinWithout() 0 20 5
A hasFullJoin() 0 3 1
A hasInnerJoin() 0 7 4
A innerJoin() 0 14 2
A leftJoin() 0 10 2
B leftJoinWithout() 0 24 6
A rightJoin() 0 3 1
A rightJoinWithout() 0 3 1
A sort() 0 9 1
1
<?php
2
3
/**
4
 * This file is part of the core-library package.
5
 *
6
 * (c) 2018 WEBEWEB
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace WBW\Library\Core\Model\Organizer;
13
14
use WBW\Library\Core\Argument\DateTimeHelper;
15
use WBW\Library\Core\Sorting\QuickSort;
16
17
/**
18
 * Time slot helper.
19
 *
20
 * @author webeweb <https://github.com/webeweb/>
21
 * @package WBW\Library\Core\Model\Organizer
22
 */
23
class TimeSlotHelper {
24
25
    /**
26
     * Determines if a time slot A contains a time slot b.
27
     *
28
     * @param TimeSlot $a The time slot A.
29
     * @param TimeSlot $b The time slot B.
30
     * @return bool Returns true in case of success, false otherwise.
31
     */
32
    public static function contains(TimeSlot $a, TimeSlot $b) {
33
        $c1 = DateTimeHelper::isBetween($b->getStartDate(), $a->getStartDate(), $a->getEndDate());
34
        $c2 = DateTimeHelper::isBetween($b->getEndDate(), $a->getStartDate(), $a->getEndDate());
35
        return $c1 && $c2;
36
    }
37
38
    /**
39
     * Determines if two time slots are equals.
40
     *
41
     * @param TimeSlot $a The time slot A.
42
     * @param TimeSlot $b The time slot B.
43
     * @return boolean Returns true in case of success, false otherwise.
44
     */
45
    public static function equals(TimeSlot $a, TimeSlot $b) {
46
47
        // Compare the start dates.
48
        if (false === DateTimeHelper::equals($a->getStartDate(), $b->getStartDate())) {
49
            return false;
50
        }
51
52
        // Compare the end dates.
53
        if (false === DateTimeHelper::equals($a->getEndDate(), $b->getEndDate())) {
54
            return false;
55
        }
56
57
        // Compare the time slots count.
58
        if (count($a->getTimeSlots()) !== count($b->getTimeSlots())) {
59
            return false;
60
        }
61
62
        // Handle each time slot.
63
        for ($i = count($a->getTimeSlots()) - 1; 0 <= $i; --$i) {
64
            if (false === self::equals($a->getTimeSlots()[$i], $b->getTimeSlots()[$i])) {
65
                return false;
66
            }
67
        }
68
69
        //
70
        return true;
71
    }
72
73
    /**
74
     * Full join two time slots.
75
     *
76
     * @param TimeSlot $a The time slot A.
77
     * @param TimeSlot $b The time slot B.
78
     * @return TimeSlot|null Returns a time slot in case of success, null otherwise.
79
     */
80
    public static function fullJoin(TimeSlot $a, TimeSlot $b) {
81
82
        // Has full join ?
83
        if (false === self::hasFullJoin($a, $b)) {
84
            return null;
85
        }
86
87
        // Initialize the date/times.
88
        $startDate = DateTimeHelper::getSmaller($a->getStartDate(), $b->getStartDate());
89
        $endDate   = DateTimeHelper::getGreater($a->getEndDate(), $b->getEndDate());
90
91
        // Return the time slot.
92
        return new TimeSlot(clone $startDate, clone $endDate);
93
    }
94
95
    /**
96
     * Full join two time slots without time slots intersection.
97
     *
98
     * @param TimeSlot $a The time slot A.
99
     * @param TimeSlot $b The time slot B.
100
     * @return TimeSlot[] Returns the time slots in case of success, null otherwise.
101
     */
102
    public static function fullJoinWithout(TimeSlot $a, TimeSlot $b) {
103
104
        // Initialize the time slots.
105
        $leftJoins  = self::leftJoinWithout($a, $b);
106
        $rightJoins = self::rightJoinWithout($a, $b);
107
108
        // Check the time slots.
109
        if (null === $leftJoins && null === $rightJoins) {
110
            return null;
111
        }
112
        if (null === $leftJoins) {
113
            return $rightJoins;
114
        }
115
        if (null === $rightJoins) {
116
            return $leftJoins;
117
        }
118
119
        // Return the time slots.
120
        return self::sort(array_merge($leftJoins, $rightJoins));
121
    }
122
123
    /**
124
     * Determines if a time slot A has full join with time slot B.
125
     *
126
     * @param TimeSlot $a The time slot A.
127
     * @param TimeSlot $b The time slot B.
128
     * @return bool Returns true in case of success, false otherwise.
129
     */
130
    public static function hasFullJoin(TimeSlot $a, TimeSlot $b) {
131
        return true === self::hasInnerJoin($a, $b);
132
    }
133
134
    /**
135
     * Determines if a time slot A has an inner join with time slot B.
136
     *
137
     * @param TimeSlot $a The time slot A.
138
     * @param TimeSlot $b The time slot B.
139
     * @return bool Returns true in case of success, false otherwise.
140
     */
141
    public static function hasInnerJoin(TimeSlot $a, TimeSlot $b) {
142
        $c1 = DateTimeHelper::isBetween($b->getStartDate(), $a->getStartDate(), $a->getEndDate());
143
        $c2 = DateTimeHelper::isBetween($b->getEndDate(), $a->getStartDate(), $a->getEndDate());
144
        $c3 = DateTimeHelper::isBetween($a->getStartDate(), $b->getStartDate(), $b->getEndDate());
145
        $c4 = DateTimeHelper::isBetween($a->getEndDate(), $b->getStartDate(), $b->getEndDate());
146
        return $c1 || $c2 || $c3 || $c4;
147
    }
148
149
    /**
150
     * Inner join two time slots.
151
     *
152
     * @param TimeSlot $a The time slot A.
153
     * @param TimeSlot $b The time slot B.
154
     * @return TimeSlot|null Returns a time slot in case of success, null otherwise.
155
     */
156
    public static function innerJoin(TimeSlot $a, TimeSlot $b) {
157
158
        // Has inner join ?
159
        if (false === self::hasInnerJoin($a, $b)) {
160
            return null;
161
        }
162
163
        // Initialize the date/times.
164
        $startDate = DateTimeHelper::getGreater($a->getStartDate(), $b->getStartDate());
165
        $endDate   = DateTimeHelper::getSmaller($a->getEndDate(), $b->getEndDate());
166
167
        // Return the time slot.
168
        return new TimeSlot(clone $startDate, clone $endDate);
169
    }
170
171
    /**
172
     * Left join two time slots.
173
     *
174
     * @param TimeSlot $a The time slot A.
175
     * @param TimeSlot $b The time slot B.
176
     * @return TimeSlot Returns the time slot in case of success, null otherwise.
177
     */
178
    public static function leftJoin(TimeSlot $a, TimeSlot $b) {
179
180
        // Has inner join ?
181
        if (false === self::hasInnerJoin($a, $b)) {
182
            return null;
183
        }
184
185
        // Return the time slot.
186
        return new TimeSlot(clone $a->getStartDate(), clone $a->getEndDate());
187
    }
188
189
    /**
190
     * Left join two time slots without time slot B intersection.
191
     *
192
     * @param TimeSlot $a The time slot A.
193
     * @param TimeSlot $b The time slot B.
194
     * @return TimeSlot[] Returns the time slots in case of success, null otherwise.
195
     */
196
    public static function leftJoinWithout(TimeSlot $a, TimeSlot $b) {
197
198
        // Has inner join ?
199
        if (false === self::hasInnerJoin($a, $b) || true === self::contains($b, $a)) {
200
            return null;
201
        }
202
203
        // Contains ?
204
        if (true === self::contains($a, $b)) {
205
            return self::sort([
206
                    new TimeSlot(clone $a->getStartDate(), clone $b->getStartDate()),
207
                    new TimeSlot(clone $b->getEndDate(), clone $a->getEndDate()),
208
            ]);
209
        }
210
211
        // Initialize the date/times.
212
        $startDate = true === DateTimeHelper::isLessThan($a->getStartDate(), $b->getStartDate()) ? $a->getStartDate() : $b->getEndDate();
213
        $endDate   = true === DateTimeHelper::isGreaterThan($a->getEndDate(), $b->getEndDate()) ? $a->getEndDate() : $b->getStartDate();
214
215
        // Return the time slots.
216
        return [
217
            new TimeSlot(clone $startDate, clone $endDate),
218
        ];
219
    }
220
221
    /**
222
     * Right join two time slots.
223
     *
224
     * @param TimeSlot $a The time slot A.
225
     * @param TimeSlot $b The time slot B.
226
     * @return TimeSlot Returns the time slot in case of success, null otherwise.
227
     */
228
    public static function rightJoin(TimeSlot $a, TimeSlot $b) {
229
        return self::leftJoin($b, $a);
230
    }
231
232
    /**
233
     * Right join two time slots without time slot B intersection.
234
     *
235
     * @param TimeSlot $a The time slot A.
236
     * @param TimeSlot $b The time slot B.
237
     * @return TimeSlot[] Returns the time slots in case of success, null otherwise.
238
     */
239
    public static function rightJoinWithout(TimeSlot $a, TimeSlot $b) {
240
        return self::leftJoinWithout($b, $a);
241
    }
242
243
    /**
244
     * Sort time slots.
245
     *
246
     * @param TimeSlot[] $timeSlots The time slots.
247
     * @return TimeSlot[] Returns the sorted time slots.
248
     */
249
    public static function sort($timeSlots) {
250
251
        // Initialize a Qucik sort.
252
        $sorter = new QuickSort($timeSlots, new TimeSlotFunctor());
253
        $sorter->sort();
254
255
        // Return the time slots.
256
        return $sorter->getValues();
257
    }
258
259
}
260