Test Failed
Push — main ( bb9080...58711e )
by Teo
03:09
created

Weather::setApiKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
nc 1
nop 1
dl 0
loc 3
c 1
b 0
f 0
cc 1
ccs 2
cts 2
cp 1
crap 1
rs 10
1
<?php
2
3
namespace Teca\Weather;
4
5
use Anax\Commons\ContainerInjectableInterface;
6
use Anax\Commons\ContainerInjectableTrait;
7
8
class Weather implements ContainerInjectableInterface
9
{
10
    use ContainerInjectableTrait;
11
12
    private $url = 'api.openweathermap.org/data/2.5/';
13
    private $apiKey = '';
14
15 7
    public function setUrl(string $url) : void
16
    {
17 7
        $this->url = $url;
18 7
    }
19
20 7
    public function setApiKey(string $apiKey) : void
21
    {
22 7
        $this->apiKey = $apiKey;
23 7
    }
24
25 3
    protected function getCurrent(string $query) : array
26
    {
27 3
        $url = $this->url . "weather?q=" . $query . "&units=metric";
28
29 3
        if ($this->apiKey !== '') {
30
            $url .= '&appid=' . $this->apiKey;
31
        }
32
33 3
        $data = $this->curl($url);
34
35 3
        if ($data["cod"] !== 200) {
36
            return [];
37
        }
38
39 3
        return $data;
40
    }
41
42 3
    protected function getHistory(float $lon, float $lat) : array
43
    {
44 3
        $urls = [];
45 3
        for ($i=1; $i <= 5; $i++) {
46 3
            $time = time() - $i * 24 * 60 * 60;
47 3
            $url = $this->url . "onecall/timemachine?lat=$lat&lon=$lon&dt=$time&units=metric";
48
49 3
            if ($this->apiKey !== '') {
50
                $url .= '&appid=' . $this->apiKey;
51
            }
52
53 3
            $urls[] = $url;
54
        }
55
56 3
        return $this->mcurl($urls);
57
    }
58
59 3
    protected function data(int $day, string $weather, string $weatherDesc, float $temp) : array
60
    {
61
        return [
62 3
            "day" => $day,
63 3
            "weather" => $weather,
64 3
            "weatherDescription" => $weatherDesc,
65 3
            "temp" => $temp
66
        ];
67
    }
68
69 3
    public function getForecast(string $query) : array
70
    {
71 3
        $current = $this->getCurrent($query);
72 3
        if ($current == null) {
73
            return [
74
                "error" => true,
75
                "history" => [],
76
                "today" => [],
77
                "forecast" => [],
78
                "lon" => 0,
79
                "lat" => 0
80
            ];
81
        }
82
83 3
        $lon = $current["coord"]["lon"];
84 3
        $lat = $current["coord"]["lat"];
85
86 3
        $url = $this->url . "onecall?lat=$lat&lon=$lon&exclude=current,minutely,hourly,alerts&units=metric";
87
88 3
        if ($this->apiKey !== '') {
89
            $url .= '&appid=' . $this->apiKey;
90
        }
91
92 3
        $result = $this->curl($url);
93 3
        $forecast = [];
94 3
        foreach ($result["daily"] as $index => $day) {
95 3
            $forecast[] = $this->data($index + 1, $day["weather"][0]["main"], $day["weather"][0]["description"], $day["temp"]["day"]);
96
        }
97
98 3
        $today = $this->data(0, $current["weather"][0]["main"], $current["weather"][0]["description"], $current["main"]["temp"]);
99 3
        $history = $this->getHistory($lon, $lat);
100
101
        return [
102 3
            "error" => false,
103 3
            "history" => $history,
104 3
            "today" => $today,
105 3
            "forecast" => $forecast,
106 3
            "lon" => $lon,
107 3
            "lat" => $lat
108
        ];
109
    }
110
111
    protected function mcurl(array $urls) : array
112
    {
113
        $options = [
114
            CURLOPT_RETURNTRANSFER => true,
115
        ];
116
117
        $multiCurl = curl_multi_init();
118
        $requests = [];
119
        foreach ($urls as $url) {
120
            $curl = curl_init("$url");
121
            curl_setopt_array($curl, $options);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_setopt_array() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

121
            curl_setopt_array(/** @scrutinizer ignore-type */ $curl, $options);
Loading history...
122
            curl_multi_add_handle($multiCurl, $curl);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_multi_add_handle() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

122
            curl_multi_add_handle($multiCurl, /** @scrutinizer ignore-type */ $curl);
Loading history...
123
            $requests[] = $curl;
124
        }
125
126
        $running = null;
127
        do {
128
            curl_multi_exec($multiCurl, $running);
129
        } while ($running);
130
131
        foreach ($requests as $curl) {
132
            curl_multi_remove_handle($multiCurl, $curl);
133
        }
134
        curl_multi_close($multiCurl);
135
136
        $response = [];
137
        foreach ($requests as $day => $curl) {
138
            $data = curl_multi_getcontent($curl);
139
            $data = json_decode($data, true);
140
141
            $index = sizeof($data["hourly"]);
142
            $midday = $data["hourly"][($index / 2) - 1];
143
144
            $response[] = $this->data(-$day - 1, $midday["weather"][0]["main"], $midday["weather"][0]["description"], $midday["temp"]);
145
        }
146
147
        return $response;
148
    }
149
150
    protected function curl(string $url) : array
151
    {
152
        $curl = curl_init();
153
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_setopt() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

153
        curl_setopt(/** @scrutinizer ignore-type */ $curl, CURLOPT_RETURNTRANSFER, true);
Loading history...
154
        curl_setopt($curl, CURLOPT_URL, $url);
155
156
        $data = curl_exec($curl);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_exec() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

156
        $data = curl_exec(/** @scrutinizer ignore-type */ $curl);
Loading history...
157
        curl_close($curl);
0 ignored issues
show
Bug introduced by
It seems like $curl can also be of type false; however, parameter $ch of curl_close() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

157
        curl_close(/** @scrutinizer ignore-type */ $curl);
Loading history...
158
159
        return json_decode($data, true);
160
    }
161
}
162