Completed
Push — master ( 707c53...e025a0 )
by Vojta
06:37
created

DatesResolver::getBoundaryDates()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 5
cts 5
cp 1
rs 9.4285
cc 1
eloc 5
nc 1
nop 1
crap 1
1
<?php namespace VojtaSvoboda\Reservations\Classes;
2
3
use Carbon\Carbon;
4
use Config;
5
use Illuminate\Database\Eloquent\Collection;
6
7
/**
8
 * Class DatesResolver transform reservations to booked time slots, grouped by date.
9
 *
10
 * @package VojtaSvoboda\Reservations\Classes
11
 */
12
class DatesResolver
13
{
14
    /**
15
     * Returns reserved time slots from non cancelled reservations.
16
     *
17
     * If you have reservations at 13.10.2016 at 11:00 and also at 13:00, both with 2 hours lenght, this method return
18
     * all booked slots - from 09:15 to 14:45 (when you have 15 minutes slot lenght).
19
     *
20
     * ------------ 11:00 ------------- 13:00 --------------
21
     *
22
     * Because nearest reservation can be done at 09:00 with 2 hours lenghts and next reservation at 15:00.
23
     *
24
     * @param Collection $reservations
25
     *
26
     * @return array
27
     */
28
    public function getDatesFromReservations(Collection $reservations)
29
    {
30
        // init
31
        $interval = $this->getInterval();
32
        $length = $this->getLength();
33
        $dateFormat = $this->getDateFormat();
34
        $timeFormat = $this->getTimeFormat();
35
36
        // sort reservations by date and count time slots before reservation and during the reservation
37
        $dates = [];
38
        foreach ($reservations as $reservation) {
39
40
            // init dates
41
            $startDate = $this->getStartDate($reservation, $length, $interval);
42
            $endDate = $this->getEndDate($reservation, $length);
43
            $reservationDay = $reservation->date->format($dateFormat);
44
45
            // save each booked interval
46
            while ($startDate < $endDate) {
47
                $time = $startDate->format($timeFormat);
48
                $dates[$reservationDay][$time] = $time;
49
                $startDate->modify('+' . $interval . ' minutes');
50
            }
51
        }
52
53
        return $dates;
54
    }
55
56
    /**
57
     * Get booked interval around the given date.
58
     *
59
     * @param Carbon $date
60
     *
61
     * @return array
62
     */
63 11
    public function getBoundaryDates(Carbon $date)
64
    {
65
        // reservation length
66 11
        $length = $this->getLength();
67
68
        // boundary dates before and after
69 11
        $startDatetime = $this->getBoundaryBefore($date, $length);
70 11
        $endDatetime = $this->getBoundaryAfter($date, $length);
71
72 11
        return [$startDatetime, $endDatetime];
73
    }
74
75
    /**
76
     * Get boundary date before reservation date.
77
     *
78
     * @param Carbon $date
79
     * @param string $length
80
     *
81
     * @return mixed
82
     */
83 11
    private function getBoundaryBefore(Carbon $date, $length)
84
    {
85 11
        $startDatetime = clone $date;
86 11
        $startDatetime->modify('-' . $length);
87 11
        $startDatetime->modify('+1 second');
88
89 11
        return $startDatetime;
90
    }
91
92
    /**
93
     * Get boundary date after reservation date.
94
     *
95
     * @param Carbon $date
96
     * @param string $length
97
     *
98
     * @return mixed
99
     */
100 11
    private function getBoundaryAfter(Carbon $date, $length)
101
    {
102 11
        $endDatetime = clone $date;
103 11
        $endDatetime->modify('+' . $length);
104 11
        $endDatetime->modify('-1 second');
105
106 11
        return $endDatetime;
107
    }
108
109
    /**
110
     * Get reservation imaginary start date.
111
     *
112
     * @param $reservation
113
     * @param $length
114
     * @param $interval
115
     *
116
     * @return mixed
117
     */
118
    protected function getStartDate($reservation, $length, $interval)
119
    {
120
        $startDate = $reservation->date;
121
        $startDate->modify('-' . $length);
122
        $startDate->modify('+' . $interval . ' minutes');
123
124
        return $startDate;
125
    }
126
127
    /**
128
     * Get reservation imaginary end date.
129
     *
130
     * @param $reservation
131
     * @param $length
132
     *
133
     * @return mixed
134
     */
135
    protected function getEndDate($reservation, $length)
136
    {
137
        $endDate = clone $reservation->date;
138
        $endDate->modify('+' . $length);
139
140
        return $endDate;
141
    }
142
143
    protected function getDateFormat()
144
    {
145
        return Config::get('vojtasvoboda.reservations::config.formats.date', 'd/m/Y');
146
    }
147
148
    protected function getTimeFormat()
149
    {
150
        return Config::get('vojtasvoboda.reservations::config.formats.time', 'H:i');
151
    }
152
153
    protected function getInterval()
154
    {
155
        return Config::get('vojtasvoboda.reservations::config.reservation.interval', 15);
156
    }
157
158 11
    protected function getLength()
159
    {
160 11
        return Config::get('vojtasvoboda.reservations::config.reservation.length', '2 hours');
161
    }
162
}
163