Darksky::timeMachine()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 16
ccs 10
cts 10
cp 1
rs 9.7333
c 0
b 0
f 0
cc 2
nc 2
nop 4
crap 2
1
<?php
2
3
namespace Darksky;
4
5
/**
6
 * Class Darksky.
7
 */
8
class Darksky
9
{
10
    const API_BASE_URL = 'https://api.darksky.net/forecast';
11
    const VALID_UNITS = [
12
        'auto',
13
        'ca',
14
        'uk2',
15
        'us',
16
        'si',
17
    ];
18
19
    const VALID_EXCLUDE = [
20
        'currently',
21
        'minutely',
22
        'hourly',
23
        'daily',
24
        'alerts',
25
        'flags',
26
    ];
27
28
    private $key;
29
    private $language;
30
    private $units;
31
    private $requestMethod;
32
33
    /**
34
     * Darksky constructor.
35
     *
36
     * @param string $key
37
     * @param string $lang
38
     * @param string $units
39
     * @param RequestMethod $requestMethod
40
     *
41
     * @throws \Exception
42
     */
43 8
    public function __construct(
44
        string $key,
45
        string $lang = 'en',
46
        string $units = 'auto',
47
        RequestMethod $requestMethod = null
48
    ) {
49 8
        $this->setKey($key);
50 8
        $this->setLanguage($lang);
51 8
        $this->setUnits($units);
52 8
        $this->requestMethod = $requestMethod ?? new Get();
53 8
    }
54
55
    /**
56
     * @param       $latitude
57
     * @param       $longitude
58
     * @param array $exclude
59
     * @param bool  $extend
60
     *
61
     * @throws \Exception
62
     *
63
     * @return string
64
     */
65 4
    public function forecast($latitude, $longitude, array $exclude = [], $extend = false)
66
    {
67
        try {
68 4
            return $this->requestMethod->submit($this->generateRequestUrl($latitude, $longitude, $exclude, $extend));
69 4
        } catch (\Exception $e) {
70 4
            throw $e;
71
        }
72
    }
73
74
    /**
75
     * @param $latitude
76
     * @param $longitude
77
     * @param $time
78
     * @param array $exclude
79
     *
80
     * @throws \Exception
81
     *
82
     * @return bool|string
83
     */
84 1
    public function timeMachine($latitude, $longitude, string $time, array $exclude = [])
85
    {
86
        try {
87 1
            return $this->requestMethod->submit(
88 1
                $this->generateRequestUrl(
89 1
                    $latitude,
90 1
                    $longitude,
91 1
                    $exclude,
92 1
                    false,
93 1
                    $time
94
                )
95
            );
96 1
        } catch (\Exception $e) {
97 1
            throw $e;
98
        }
99
    }
100
101
    /**
102
     * @return string
103
     */
104 6
    public function getKey(): string
105
    {
106 6
        return $this->key;
107
    }
108
109
    /**
110
     * @param string $key
111
     */
112 8
    public function setKey(string $key)
113
    {
114 8
        $this->key = $key;
115 8
    }
116
117
    /**
118
     * @param $latitude
119
     * @param $longitude
120
     * @param array  $exclude
121
     * @param bool   $extend
122
     * @param string $time
123
     *
124
     * @throws \Exception
125
     *
126
     * @return string
127
     */
128 5
    private function generateRequestUrl(
129
        $latitude,
130
        $longitude,
131
        array $exclude = [],
132
        $extend = false,
133
        string $time = ''
134
    ): string {
135 5
        if (!empty($time)) {
136 1
            $time = ",{$time}";
137
        }
138
139 5
        return self::API_BASE_URL.'/'.$this->getKey().'/'.$latitude.','.$longitude.$time
140 5
            .'?'.$this->generateUrlQueryString($exclude, $extend);
141
    }
142
143
    /**
144
     * @param array $exclude
145
     * @param bool  $extend
146
     *
147
     * @throws \Exception
148
     *
149
     * @return string
150
     */
151 5
    private function generateUrlQueryString(array $exclude = [], $extend = false): string
152
    {
153 5
        $queryString = ['lang' => $this->getLanguage(), 'units' => $this->getUnits()];
154
155
        // validate $exclude
156 5
        if ($this->validateExcludes($exclude) !== true) {
157 1
            $validExcludes = implode(',', self::VALID_EXCLUDE);
158
159 1
            throw new DarkskyException("Invalid excludes. Provide valid excludes: {$validExcludes}'");
160
        }
161
162 4
        if (!empty($exclude)) {
163 1
            $queryString['exclude'] = implode(',', $exclude);
164
        }
165
166 4
        if ($extend === true) {
167 3
            $queryString['extend'] = 'hourly';
168
        }
169
170 4
        return http_build_query($queryString);
171
    }
172
173
    /**
174
     * @param $exclude
175
     *
176
     * @return bool
177
     */
178 5
    private function validateExcludes(array $exclude): bool
179
    {
180 5
        if (empty($exclude)) {
181 3
            return true;
182
        }
183
184 2
        foreach ($exclude as $anExclude) {
185 2
            if (!in_array($anExclude, self::VALID_EXCLUDE)) {
186 2
                return false;
187
            }
188
        }
189
190 1
        return true;
191
    }
192
193
    /**
194
     * @return string
195
     */
196 6
    public function getLanguage(): string
197
    {
198 6
        return $this->language;
199
    }
200
201
    /**
202
     * @param string $language
203
     */
204 8
    public function setLanguage(string $language)
205
    {
206 8
        $this->language = $language;
207 8
    }
208
209
    /**
210
     * @return string
211
     */
212 6
    public function getUnits(): string
213
    {
214 6
        return $this->units;
215
    }
216
217
    /**
218
     * @param $units
219
     *
220
     * @throws \Exception
221
     */
222 8
    public function setUnits(string $units)
223
    {
224 8
        if (!in_array($units, self::VALID_UNITS)) {
225 1
            $validUnits = implode(',', self::VALID_UNITS);
226
227 1
            throw new DarkskyException("'{$units}' is not a valid unit. Valid units: {$validUnits}");
228
        }
229
230 8
        $this->units = $units;
231 8
    }
232
}
233