Issues (10)

src/Weather/Weather.php (5 issues)

Labels
Severity
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 8
    public function setUrl(string $url) : void
16
    {
17 8
        $this->url = $url;
18 8
    }
19
20 8
    public function setApiKey(string $apiKey) : void
21
    {
22 8
        $this->apiKey = $apiKey;
23 8
    }
24
25 4
    protected function getCurrent(string $query) : array
26
    {
27 4
        $url = $this->url . "weather?q=" . $query . "&units=metric";
28
29 4
        if ($this->apiKey !== '') {
30 1
            $url .= '&appid=' . $this->apiKey;
31
        }
32
33 4
        $data = $this->curl($url);
34
35 4
        if (empty($data)) {
36 1
            return [];
37
        }
38
39 3
        if ($data["cod"] !== 200) {
40
            return [];
41
        }
42
43 3
        return $data;
44
    }
45
46 3
    protected function getHistory(float $lon, float $lat) : array
47
    {
48 3
        $urls = [];
49 3
        for ($i=1; $i <= 5; $i++) {
50 3
            $time = time() - $i * 24 * 60 * 60;
51 3
            $url = $this->url . "onecall/timemachine?lat=$lat&lon=$lon&dt=$time&units=metric";
52
53 3
            if ($this->apiKey !== '') {
54
                $url .= '&appid=' . $this->apiKey;
55
            }
56
57 3
            $urls[] = $url;
58
        }
59
60 3
        return $this->mcurl($urls);
61
    }
62
63 3
    protected function data(int $day, string $weather, string $weatherDesc, float $temp) : array
64
    {
65
        return [
66 3
            "day" => $day,
67 3
            "weather" => $weather,
68 3
            "weatherDescription" => $weatherDesc,
69 3
            "temp" => $temp
70
        ];
71
    }
72
73 4
    public function getForecast(string $query) : array
74
    {
75 4
        $current = $this->getCurrent($query);
76 4
        if ($current == null) {
77
            return [
78 1
                "error" => true,
79
                "history" => [],
80
                "today" => [],
81
                "forecast" => [],
82
                "lon" => 0,
83
                "lat" => 0
84
            ];
85
        }
86
87 3
        $lon = $current["coord"]["lon"];
88 3
        $lat = $current["coord"]["lat"];
89
90 3
        $url = $this->url . "onecall?lat=$lat&lon=$lon&exclude=current,minutely,hourly,alerts&units=metric";
91
92 3
        if ($this->apiKey !== '') {
93
            $url .= '&appid=' . $this->apiKey;
94
        }
95
96 3
        $result = $this->curl($url);
97 3
        $forecast = [];
98 3
        foreach ($result["daily"] as $index => $day) {
99 3
            $forecast[] = $this->data($index + 1, $day["weather"][0]["main"], $day["weather"][0]["description"], $day["temp"]["day"]);
100
        }
101
102 3
        $today = $this->data(0, $current["weather"][0]["main"], $current["weather"][0]["description"], $current["main"]["temp"]);
103 3
        $history = $this->getHistory($lon, $lat);
104
105
        return [
106 3
            "error" => false,
107 3
            "history" => $history,
108 3
            "today" => $today,
109 3
            "forecast" => $forecast,
110 3
            "lon" => $lon,
111 3
            "lat" => $lat
112
        ];
113
    }
114
115
    protected function mcurl(array $urls) : array
116
    {
117
        $options = [
118
            CURLOPT_RETURNTRANSFER => true,
119
        ];
120
121
        $multiCurl = curl_multi_init();
122
        $requests = [];
123
        foreach ($urls as $url) {
124
            $curl = curl_init("$url");
125
            curl_setopt_array($curl, $options);
0 ignored issues
show
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

125
            curl_setopt_array(/** @scrutinizer ignore-type */ $curl, $options);
Loading history...
126
            curl_multi_add_handle($multiCurl, $curl);
0 ignored issues
show
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

126
            curl_multi_add_handle($multiCurl, /** @scrutinizer ignore-type */ $curl);
Loading history...
127
            $requests[] = $curl;
128
        }
129
130
        $running = null;
131
        do {
132
            curl_multi_exec($multiCurl, $running);
133
        } while ($running);
134
135
        foreach ($requests as $curl) {
136
            curl_multi_remove_handle($multiCurl, $curl);
137
        }
138
        curl_multi_close($multiCurl);
139
140
        $response = [];
141
        foreach ($requests as $day => $curl) {
142
            $data = curl_multi_getcontent($curl);
143
            $data = json_decode($data, true);
144
145
            $index = sizeof($data["hourly"]);
146
            $midday = $data["hourly"][($index / 2) - 1];
147
148
            $response[] = $this->data(-$day - 1, $midday["weather"][0]["main"], $midday["weather"][0]["description"], $midday["temp"]);
149
        }
150
151
        return $response;
152
    }
153
154
    protected function curl(string $url) : array
155
    {
156
        $curl = curl_init();
157
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
0 ignored issues
show
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

157
        curl_setopt(/** @scrutinizer ignore-type */ $curl, CURLOPT_RETURNTRANSFER, true);
Loading history...
158
        curl_setopt($curl, CURLOPT_URL, $url);
159
160
        $data = curl_exec($curl);
0 ignored issues
show
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

160
        $data = curl_exec(/** @scrutinizer ignore-type */ $curl);
Loading history...
161
        curl_close($curl);
0 ignored issues
show
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

161
        curl_close(/** @scrutinizer ignore-type */ $curl);
Loading history...
162
163
        return json_decode($data, true);
164
    }
165
}
166