Passed
Push — master ( a62b41...518ca5 )
by Oliver
03:36
created

OpeningHoursForDay::nextOpen()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 4.0466

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 6
cts 7
cp 0.8571
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 4
nop 1
crap 4.0466
1
<?php
2
3
namespace Webfactor\Laravel\OpeningHours\Entities;
4
5
use Countable;
6
use ArrayAccess;
7
use ArrayIterator;
8
use IteratorAggregate;
9
use Webfactor\Laravel\OpeningHours\Exceptions\OverlappingTimeRanges;
10
use Webfactor\Laravel\OpeningHours\Helpers\Arr;
11
12
class OpeningHoursForDay implements ArrayAccess, Countable, IteratorAggregate
13
{
14
    /** @var \Spatie\OpeningHours\TimeRange[] */
15
    protected $openingHours = [];
16
17 26
    public static function fromStrings(array $strings)
18
    {
19 26
        $openingHoursForDay = new static();
20
21 26
        $timeRanges = Arr::map($strings, function ($string) {
22 25
            return TimeRange::fromString($string);
23 26
        });
24
25 26
        $openingHoursForDay->guardAgainstTimeRangeOverlaps($timeRanges);
26
27 25
        $openingHoursForDay->openingHours = $timeRanges;
28
29 25
        return $openingHoursForDay;
30
    }
31
32 6
    public function isOpenAt(Time $time)
33
    {
34 6
        foreach ($this->openingHours as $timeRange) {
35 4
            if ($timeRange->containsTime($time)) {
36 4
                return true;
37
            }
38
        }
39
40 6
        return false;
41
    }
42
43 4
    public function nextOpen(Time $time)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
44
    {
45 4
        foreach ($this->openingHours as $timeRange) {
46 4
            if ($nextOpen = $this->findNextOpenInWorkingHours($time, $timeRange)) {
47
                return $nextOpen;
48
            }
49
50 4
            if ($nextOpen = $this->findNextOpenInFreeTime($time, $timeRange)) {
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $nextOpen is correct as $this->findNextOpenInFreeTime($time, $timeRange) (which targets Webfactor\Laravel\Openin...indNextOpenInFreeTime()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
51 4
                return $nextOpen;
52
            }
53
        }
54
55 3
        return false;
56
    }
57
58 4
    protected function findNextOpenInWorkingHours(Time $time, TimeRange $timeRange)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
59
    {
60 4
        if ($timeRange->containsTime($time) && next($timeRange) !== $timeRange) {
61 2
            return next($timeRange);
62
        }
63 3
    }
64
65 4
    protected function findNextOpenInFreeTime(Time $time, TimeRange $timeRange, TimeRange &$prevTimeRange = null)
66
    {
67 4
        $timeOffRange = $prevTimeRange ?
68
            TimeRange::fromString($prevTimeRange->end().'-'.$timeRange->start()) :
69 4
            TimeRange::fromString('00:00-'.$timeRange->start());
70
71 4
        if ($timeOffRange->containsTime($time) || $timeOffRange->start()->isSame($time)) {
72 4
            return $timeRange->start();
73
        }
74
75 2
        $prevTimeRange = $timeRange;
76 2
    }
77
78
    public function offsetExists($offset): bool
79
    {
80
        return isset($this->openingHours[$offset]);
81
    }
82
83 6
    public function offsetGet($offset)
84
    {
85 6
        return $this->openingHours[$offset];
86
    }
87
88
    public function offsetSet($offset, $value)
89
    {
90
        throw new \Exception();
91
    }
92
93
    public function offsetUnset($offset)
94
    {
95
        unset($this->openingHours[$offset]);
96
    }
97
98 12
    public function count(): int
99
    {
100 12
        return count($this->openingHours);
101
    }
102
103
    public function getIterator()
104
    {
105
        return new ArrayIterator($this->openingHours);
106
    }
107
108 4
    public function isEmpty(): bool
109
    {
110 4
        return empty($this->openingHours);
111
    }
112
113 2
    public function map(callable $callback): array
114
    {
115 2
        return Arr::map($this->openingHours, $callback);
116
    }
117
118 26
    protected function guardAgainstTimeRangeOverlaps(array $openingHours)
119
    {
120 26
        foreach (Arr::createUniquePairs($openingHours) as $timeRanges) {
121 9
            if ($timeRanges[0]->overlaps($timeRanges[1])) {
122 9
                throw OverlappingTimeRanges::forRanges($timeRanges[0], $timeRanges[1]);
123
            }
124
        }
125 25
    }
126
}
127