Passed
Push — master ( 6917c6...8092ee )
by Jean-Philippe
16:54 queued 01:52
created

Countdown::asDateTime()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 33
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
c 0
b 0
f 0
rs 6.7272
cc 7
eloc 12
nc 5
nop 1
1
<?php
2
3
namespace jpmurray\LaravelCountdown;
4
5
use Exception;
6
use Carbon\Carbon;
7
use DateTimeInterface;
8
use Illuminate\Foundation\Application;
9
use jpmurray\LaravelCountdown\Exceptions\InvalidArgumentToCountdown;
10
use jpmurray\LaravelCountdown\Exceptions\InvalidDateFormatToCountdown;
11
12
class Countdown
13
{
14
    const WEEKS_PER_YEAR     = 52;
15
    const DAYS_PER_WEEK      = 7;
16
    const HOURS_PER_DAY      = 24;
17
    const MINUTES_PER_HOUR   = 60;
18
    const SECONDS_PER_MINUTE = 60;
19
    const SECONDS_PER_HOUR   = 3600;
20
    const SECONDS_PER_DAY    = 86400;
21
    const SECONDS_PER_WEEK   = 604800;
22
    const SECONDS_PER_YEAR   = 31449600;
23
24
    private $from = null;
25
    private $to = null;
26
    private $delta;
27
    public $years;
28
    public $weeks;
29
    public $days;
30
    public $hours;
31
    public $minutes;
32
    public $seconds;
33
34
    /**
35
     * [__construct description]
36
     * @param Carbon $carbon [description]
37
     */
38
    public function __construct(string $timezone, Carbon $carbon)
39
    {
40
        $this->timezone = $timezone;
0 ignored issues
show
Bug Best Practice introduced by
The property timezone does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
41
        $this->carbon = $carbon->now($this->timezone);
0 ignored issues
show
Bug Best Practice introduced by
The property timezone does not exist on jpmurray\LaravelCountdown\Countdown. Did you maybe forget to declare it?
Loading history...
Bug Best Practice introduced by
The property carbon does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
42
    }
43
44
    /**
45
     * Sets the time to count from
46
     *
47
     * @param string|integer|DateTime|Carbon $time
0 ignored issues
show
Bug introduced by
The type jpmurray\LaravelCountdown\DateTime was not found. Did you mean DateTime? If so, make sure to prefix the type with \.
Loading history...
48
     *
49
     * @return self
50
     */
51
    public function from($time) : self
52
    {
53
        $this->from = $this->asDateTime($time);
54
55
        return $this;
56
    }
57
58
    /**
59
     * Sets the time to count to
60
     *
61
     * @param   string|integer|DateTime|Carbon $time
62
     *
63
     * @return  self
64
     */
65
    public function to($time = null) : self
66
    {
67
        $time ?: $this->carbon;
0 ignored issues
show
Bug Best Practice introduced by
The property carbon does not exist on jpmurray\LaravelCountdown\Countdown. Did you maybe forget to declare it?
Loading history...
68
69
        $this->to = $this->asDateTime($time);
70
71
        return $this;
72
    }
73
74
    /**
75
     * Returns the object containing the values for the countdown
76
     *
77
     * @return object
78
     */
79
    public function get()
80
    {
81
        if (is_null($this->from)) {
82
            $this->from = $this->carbon;
0 ignored issues
show
Bug Best Practice introduced by
The property carbon does not exist on jpmurray\LaravelCountdown\Countdown. Did you maybe forget to declare it?
Loading history...
83
        }
84
85
        if (is_null($this->to)) {
86
            $this->to = $this->carbon;
87
        }
88
89
        $this->delta = $this->from->diffInSeconds($this->to);
90
        
91
        $this->computeYears()
92
             ->computeWeeks()
93
             ->computeDays()
94
             ->computeHours()
95
             ->computeMinutes()
96
             ->computeSeconds();
97
98
        return $this;
99
    }
100
101
    /**
102
     * Return a timestamp as DateTime object.
103
     *
104
     * @param  mixed  $value
105
     *
106
     * @return \Carbon\Carbon
107
     */
108
    protected function asDateTime($value)
109
    {
110
        try {
111
            // If this value is already a Carbon instance, we shall just return it as is.
112
            // This prevents us having to re-instantiate a Carbon instance when we know
113
            // it already is one, which wouldn't be fulfilled by the DateTime check.
114
            if ($value instanceof Carbon) {
115
                return $value;
116
            }
117
118
             // If the value is already a DateTime instance, we will just skip the rest of
119
             // these checks since they will be a waste of time, and hinder performance
120
             // when checking the field. We will just return the DateTime right away.
121
            if ($value instanceof DateTimeInterface) {
122
                return $this->carbon->instance($value);
0 ignored issues
show
Bug Best Practice introduced by
The property carbon does not exist on jpmurray\LaravelCountdown\Countdown. Did you maybe forget to declare it?
Loading history...
123
            }
124
125
            // If this value is an integer, we will assume it is a UNIX timestamp's value
126
            // and format a Carbon object from this timestamp. This allows flexibility
127
            // when defining your date fields as they might be UNIX timestamps here.
128
            if (is_numeric($value)) {
129
                return $this->carbon->createFromTimestamp($value);
130
            }
131
132
            // If the value is in simply year, month, day format
133
            if (is_string($value) && $this->isStandardDateFormat($value)) {
134
                return $this->carbon->createFromFormat('Y-m-d', $value)->startOfDay();
135
            }
136
137
            // Finally
138
            return $this->carbon->parse((string)$value);
139
        } catch (Exception $e) {
140
            throw new InvalidDateFormatToCountdown;
141
        }
142
    }
143
144
    /**
145
     * Determine if the given value is a standard date format.
146
     *
147
     * @param  string  $value
148
     *
149
     * @return bool
150
     */
151
    protected function isStandardDateFormat(string $value) : int
152
    {
153
        return preg_match('/^(\d{4})-(\d{1,2})-(\d{1,2})$/', $value);
154
    }
155
156
    /**
157
     * Compute the number of seconds for the countdown
158
     *
159
     * @return  self
160
     */
161
    private function computeSeconds() : self
162
    {
163
        $this->seconds = intval(bcmod(intval($this->delta), self::SECONDS_PER_MINUTE));
164
165
        return $this;
166
    }
167
168
    /**
169
     * Compute the number of minutes for the countdown
170
     *
171
     * @return  self
172
     */
173
    private function computeMinutes() : self
174
    {
175
        $this->minutes = intval(bcmod((intval($this->delta) / self::SECONDS_PER_MINUTE), self::MINUTES_PER_HOUR));
176
177
        return $this;
178
    }
179
180
    /**
181
     * Compute the number of hours for the countdown
182
     *
183
     * @return  self
184
     */
185
    private function computeHours() : self
186
    {
187
        $this->hours = intval(bcmod((intval($this->delta) / self::SECONDS_PER_HOUR), self::HOURS_PER_DAY));
188
189
        return $this;
190
    }
191
192
    /**
193
     * Compute the number of days for the countdown
194
     *
195
     * @return  self
196
     */
197
    private function computeDays() : self
198
    {
199
        $this->days = intval(bcmod((intval($this->delta) / self::SECONDS_PER_DAY), self::DAYS_PER_WEEK));
200
201
        return $this;
202
    }
203
204
    /**
205
     * Compute the number of weeks for the countdown
206
     *
207
     * @return  self
208
     */
209
    private function computeWeeks() : self
210
    {
211
        $this->weeks = intval(bcmod((intval($this->delta) / self::SECONDS_PER_WEEK), self::WEEKS_PER_YEAR));
212
213
        return $this;
214
    }
215
216
    /**
217
     * Compute the number of years for the countdown
218
     *
219
     * @return  self
220
     */
221
    private function computeYears() : self
222
    {
223
        $this->years = intval(intval($this->delta) / self::SECONDS_PER_YEAR);
224
225
        return $this;
226
    }
227
}
228