Passed
Push — master ( b35c98...707c53 )
by Vojta
05:27
created

DatesResolver::getEndDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 7
ccs 0
cts 0
cp 0
rs 9.4285
cc 1
eloc 4
nc 1
nop 2
crap 2
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
    public function getBoundaryDates(Carbon $date)
64
    {
65
        // reservation length
66
        $length = $this->getLength();
67
68
        // boundary dates before and after
69
        $startDatetime = $this->getBoundaryBefore($date, $length);
70
        $endDatetime = $this->getBoundaryAfter($date, $length);
71
72
        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
    private function getBoundaryBefore(Carbon $date, $length)
84
    {
85
        $startDatetime = clone $date;
86
        $startDatetime->modify('-' . $length);
87
        $startDatetime->modify('+1 second');
88
89
        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
    private function getBoundaryAfter(Carbon $date, $length)
101
    {
102
        $endDatetime = clone $date;
103
        $endDatetime->modify('+' . $length);
104
        $endDatetime->modify('-1 second');
105
106
        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
    protected function getLength()
159
    {
160
        return Config::get('vojtasvoboda.reservations::config.reservation.length', '2 hours');
161
    }
162
}
163