Completed
Push — master ( df69eb...a67720 )
by
unknown
20:24 queued 14s
created
apps/weather_status/lib/Service/WeatherStatusService.php 1 patch
Indentation   +333 added lines, -333 removed lines patch added patch discarded remove patch
@@ -33,362 +33,362 @@
 block discarded – undo
33 33
  * @psalm-import-type WeatherStatusLocationWithMode from ResponseDefinitions
34 34
  */
35 35
 class WeatherStatusService {
36
-	public const MODE_BROWSER_LOCATION = 1;
37
-	public const MODE_MANUAL_LOCATION = 2;
36
+    public const MODE_BROWSER_LOCATION = 1;
37
+    public const MODE_MANUAL_LOCATION = 2;
38 38
 
39
-	private IClient $client;
40
-	private ICache $cache;
41
-	private string $version;
39
+    private IClient $client;
40
+    private ICache $cache;
41
+    private string $version;
42 42
 
43
-	public function __construct(
44
-		private IClientService $clientService,
45
-		private IConfig $config,
46
-		private IL10N $l10n,
47
-		private LoggerInterface $logger,
48
-		private IAccountManager $accountManager,
49
-		private IUserManager $userManager,
50
-		private IAppManager $appManager,
51
-		private ICacheFactory $cacheFactory,
52
-		private ?string $userId,
53
-	) {
54
-		$this->version = $appManager->getAppVersion(Application::APP_ID);
55
-		$this->client = $clientService->newClient();
56
-		$this->cache = $cacheFactory->createDistributed('weatherstatus');
57
-	}
43
+    public function __construct(
44
+        private IClientService $clientService,
45
+        private IConfig $config,
46
+        private IL10N $l10n,
47
+        private LoggerInterface $logger,
48
+        private IAccountManager $accountManager,
49
+        private IUserManager $userManager,
50
+        private IAppManager $appManager,
51
+        private ICacheFactory $cacheFactory,
52
+        private ?string $userId,
53
+    ) {
54
+        $this->version = $appManager->getAppVersion(Application::APP_ID);
55
+        $this->client = $clientService->newClient();
56
+        $this->cache = $cacheFactory->createDistributed('weatherstatus');
57
+    }
58 58
 
59
-	/**
60
-	 * Change the weather status mode. There are currently 2 modes:
61
-	 * - ask the browser
62
-	 * - use the user defined address
63
-	 * @param int $mode New mode
64
-	 * @return WeatherStatusSuccess success state
65
-	 */
66
-	public function setMode(int $mode): array {
67
-		$this->config->setUserValue($this->userId, Application::APP_ID, 'mode', strval($mode));
68
-		return ['success' => true];
69
-	}
59
+    /**
60
+     * Change the weather status mode. There are currently 2 modes:
61
+     * - ask the browser
62
+     * - use the user defined address
63
+     * @param int $mode New mode
64
+     * @return WeatherStatusSuccess success state
65
+     */
66
+    public function setMode(int $mode): array {
67
+        $this->config->setUserValue($this->userId, Application::APP_ID, 'mode', strval($mode));
68
+        return ['success' => true];
69
+    }
70 70
 
71
-	/**
72
-	 * Get favorites list
73
-	 * @return list<string>
74
-	 */
75
-	public function getFavorites(): array {
76
-		$favoritesJson = $this->config->getUserValue($this->userId, Application::APP_ID, 'favorites', '');
77
-		return json_decode($favoritesJson, true) ?: [];
78
-	}
71
+    /**
72
+     * Get favorites list
73
+     * @return list<string>
74
+     */
75
+    public function getFavorites(): array {
76
+        $favoritesJson = $this->config->getUserValue($this->userId, Application::APP_ID, 'favorites', '');
77
+        return json_decode($favoritesJson, true) ?: [];
78
+    }
79 79
 
80
-	/**
81
-	 * Set favorites list
82
-	 * @param list<string> $favorites
83
-	 * @return WeatherStatusSuccess success state
84
-	 */
85
-	public function setFavorites(array $favorites): array {
86
-		$this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites));
87
-		return ['success' => true];
88
-	}
80
+    /**
81
+     * Set favorites list
82
+     * @param list<string> $favorites
83
+     * @return WeatherStatusSuccess success state
84
+     */
85
+    public function setFavorites(array $favorites): array {
86
+        $this->config->setUserValue($this->userId, Application::APP_ID, 'favorites', json_encode($favorites));
87
+        return ['success' => true];
88
+    }
89 89
 
90
-	/**
91
-	 * Try to use the address set in user personal settings as weather location
92
-	 *
93
-	 * @return WeatherStatusLocationWithSuccess with success state and address information
94
-	 */
95
-	public function usePersonalAddress(): array {
96
-		$account = $this->accountManager->getAccount($this->userManager->get($this->userId));
97
-		try {
98
-			$address = $account->getProperty('address')->getValue();
99
-		} catch (PropertyDoesNotExistException $e) {
100
-			return ['success' => false];
101
-		}
102
-		if ($address === '') {
103
-			return ['success' => false];
104
-		}
105
-		return $this->setAddress($address);
106
-	}
90
+    /**
91
+     * Try to use the address set in user personal settings as weather location
92
+     *
93
+     * @return WeatherStatusLocationWithSuccess with success state and address information
94
+     */
95
+    public function usePersonalAddress(): array {
96
+        $account = $this->accountManager->getAccount($this->userManager->get($this->userId));
97
+        try {
98
+            $address = $account->getProperty('address')->getValue();
99
+        } catch (PropertyDoesNotExistException $e) {
100
+            return ['success' => false];
101
+        }
102
+        if ($address === '') {
103
+            return ['success' => false];
104
+        }
105
+        return $this->setAddress($address);
106
+    }
107 107
 
108
-	/**
109
-	 * Set address and resolve it to get coordinates
110
-	 * or directly set coordinates and get address with reverse geocoding
111
-	 *
112
-	 * @param string|null $address Any approximative or exact address
113
-	 * @param float|null $lat Latitude in decimal degree format
114
-	 * @param float|null $lon Longitude in decimal degree format
115
-	 * @return WeatherStatusLocationWithSuccess with success state and address information
116
-	 */
117
-	public function setLocation(?string $address, ?float $lat, ?float $lon): array {
118
-		if (!is_null($lat) && !is_null($lon)) {
119
-			// store coordinates
120
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'lat', strval($lat));
121
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'lon', strval($lon));
122
-			// resolve and store formatted address
123
-			$address = $this->resolveLocation($lat, $lon);
124
-			$address = $address ?: $this->l10n->t('Unknown address');
125
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'address', $address);
126
-			// get and store altitude
127
-			$altitude = $this->getAltitude($lat, $lon);
128
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'altitude', strval($altitude));
129
-			return [
130
-				'address' => $address,
131
-				'success' => true,
132
-			];
133
-		} elseif ($address) {
134
-			return $this->setAddress($address);
135
-		} else {
136
-			return ['success' => false];
137
-		}
138
-	}
108
+    /**
109
+     * Set address and resolve it to get coordinates
110
+     * or directly set coordinates and get address with reverse geocoding
111
+     *
112
+     * @param string|null $address Any approximative or exact address
113
+     * @param float|null $lat Latitude in decimal degree format
114
+     * @param float|null $lon Longitude in decimal degree format
115
+     * @return WeatherStatusLocationWithSuccess with success state and address information
116
+     */
117
+    public function setLocation(?string $address, ?float $lat, ?float $lon): array {
118
+        if (!is_null($lat) && !is_null($lon)) {
119
+            // store coordinates
120
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'lat', strval($lat));
121
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'lon', strval($lon));
122
+            // resolve and store formatted address
123
+            $address = $this->resolveLocation($lat, $lon);
124
+            $address = $address ?: $this->l10n->t('Unknown address');
125
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'address', $address);
126
+            // get and store altitude
127
+            $altitude = $this->getAltitude($lat, $lon);
128
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'altitude', strval($altitude));
129
+            return [
130
+                'address' => $address,
131
+                'success' => true,
132
+            ];
133
+        } elseif ($address) {
134
+            return $this->setAddress($address);
135
+        } else {
136
+            return ['success' => false];
137
+        }
138
+    }
139 139
 
140
-	/**
141
-	 * Provide address information from coordinates
142
-	 *
143
-	 * @param float $lat Latitude in decimal degree format
144
-	 * @param float $lon Longitude in decimal degree format
145
-	 */
146
-	private function resolveLocation(float $lat, float $lon): ?string {
147
-		$params = [
148
-			'lat' => number_format($lat, 2),
149
-			'lon' => number_format($lon, 2),
150
-			'addressdetails' => 1,
151
-			'format' => 'json',
152
-		];
153
-		$url = 'https://nominatim.openstreetmap.org/reverse';
154
-		$result = $this->requestJSON($url, $params);
155
-		return $this->formatOsmAddress($result);
156
-	}
140
+    /**
141
+     * Provide address information from coordinates
142
+     *
143
+     * @param float $lat Latitude in decimal degree format
144
+     * @param float $lon Longitude in decimal degree format
145
+     */
146
+    private function resolveLocation(float $lat, float $lon): ?string {
147
+        $params = [
148
+            'lat' => number_format($lat, 2),
149
+            'lon' => number_format($lon, 2),
150
+            'addressdetails' => 1,
151
+            'format' => 'json',
152
+        ];
153
+        $url = 'https://nominatim.openstreetmap.org/reverse';
154
+        $result = $this->requestJSON($url, $params);
155
+        return $this->formatOsmAddress($result);
156
+    }
157 157
 
158
-	/**
159
-	 * Get altitude from coordinates
160
-	 *
161
-	 * @param float $lat Latitude in decimal degree format
162
-	 * @param float $lon Longitude in decimal degree format
163
-	 * @return float altitude in meter
164
-	 */
165
-	private function getAltitude(float $lat, float $lon): float {
166
-		$params = [
167
-			'locations' => $lat . ',' . $lon,
168
-		];
169
-		$url = 'https://api.opentopodata.org/v1/srtm30m';
170
-		$result = $this->requestJSON($url, $params);
171
-		$altitude = 0;
172
-		if (isset($result['results']) && is_array($result['results']) && count($result['results']) > 0
173
-			&& is_array($result['results'][0]) && isset($result['results'][0]['elevation'])) {
174
-			$altitude = floatval($result['results'][0]['elevation']);
175
-		}
176
-		return $altitude;
177
-	}
158
+    /**
159
+     * Get altitude from coordinates
160
+     *
161
+     * @param float $lat Latitude in decimal degree format
162
+     * @param float $lon Longitude in decimal degree format
163
+     * @return float altitude in meter
164
+     */
165
+    private function getAltitude(float $lat, float $lon): float {
166
+        $params = [
167
+            'locations' => $lat . ',' . $lon,
168
+        ];
169
+        $url = 'https://api.opentopodata.org/v1/srtm30m';
170
+        $result = $this->requestJSON($url, $params);
171
+        $altitude = 0;
172
+        if (isset($result['results']) && is_array($result['results']) && count($result['results']) > 0
173
+            && is_array($result['results'][0]) && isset($result['results'][0]['elevation'])) {
174
+            $altitude = floatval($result['results'][0]['elevation']);
175
+        }
176
+        return $altitude;
177
+    }
178 178
 
179
-	/**
180
-	 * @return string Formatted address from JSON nominatim result
181
-	 */
182
-	private function formatOsmAddress(array $json): ?string {
183
-		if (isset($json['address']) && isset($json['display_name'])) {
184
-			$jsonAddr = $json['address'];
185
-			$cityAddress = '';
186
-			// priority : city, town, village, municipality
187
-			if (isset($jsonAddr['city'])) {
188
-				$cityAddress .= $jsonAddr['city'];
189
-			} elseif (isset($jsonAddr['town'])) {
190
-				$cityAddress .= $jsonAddr['town'];
191
-			} elseif (isset($jsonAddr['village'])) {
192
-				$cityAddress .= $jsonAddr['village'];
193
-			} elseif (isset($jsonAddr['municipality'])) {
194
-				$cityAddress .= $jsonAddr['municipality'];
195
-			} else {
196
-				return $json['display_name'];
197
-			}
198
-			// post code
199
-			if (isset($jsonAddr['postcode'])) {
200
-				$cityAddress .= ', ' . $jsonAddr['postcode'];
201
-			}
202
-			// country
203
-			if (isset($jsonAddr['country'])) {
204
-				$cityAddress .= ', ' . $jsonAddr['country'];
205
-				return $cityAddress;
206
-			} else {
207
-				return $json['display_name'];
208
-			}
209
-		} elseif (isset($json['display_name'])) {
210
-			return $json['display_name'];
211
-		}
212
-		return null;
213
-	}
179
+    /**
180
+     * @return string Formatted address from JSON nominatim result
181
+     */
182
+    private function formatOsmAddress(array $json): ?string {
183
+        if (isset($json['address']) && isset($json['display_name'])) {
184
+            $jsonAddr = $json['address'];
185
+            $cityAddress = '';
186
+            // priority : city, town, village, municipality
187
+            if (isset($jsonAddr['city'])) {
188
+                $cityAddress .= $jsonAddr['city'];
189
+            } elseif (isset($jsonAddr['town'])) {
190
+                $cityAddress .= $jsonAddr['town'];
191
+            } elseif (isset($jsonAddr['village'])) {
192
+                $cityAddress .= $jsonAddr['village'];
193
+            } elseif (isset($jsonAddr['municipality'])) {
194
+                $cityAddress .= $jsonAddr['municipality'];
195
+            } else {
196
+                return $json['display_name'];
197
+            }
198
+            // post code
199
+            if (isset($jsonAddr['postcode'])) {
200
+                $cityAddress .= ', ' . $jsonAddr['postcode'];
201
+            }
202
+            // country
203
+            if (isset($jsonAddr['country'])) {
204
+                $cityAddress .= ', ' . $jsonAddr['country'];
205
+                return $cityAddress;
206
+            } else {
207
+                return $json['display_name'];
208
+            }
209
+        } elseif (isset($json['display_name'])) {
210
+            return $json['display_name'];
211
+        }
212
+        return null;
213
+    }
214 214
 
215
-	/**
216
-	 * Set address and resolve it to get coordinates
217
-	 *
218
-	 * @param string $address Any approximative or exact address
219
-	 * @return WeatherStatusLocationWithSuccess with success state and address information (coordinates and formatted address)
220
-	 */
221
-	public function setAddress(string $address): array {
222
-		$addressInfo = $this->searchForAddress($address);
223
-		if (isset($addressInfo['display_name']) && isset($addressInfo['lat']) && isset($addressInfo['lon'])) {
224
-			$formattedAddress = $this->formatOsmAddress($addressInfo);
225
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'address', $formattedAddress);
226
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'lat', strval($addressInfo['lat']));
227
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'lon', strval($addressInfo['lon']));
228
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'mode', strval(self::MODE_MANUAL_LOCATION));
229
-			// get and store altitude
230
-			$altitude = $this->getAltitude(floatval($addressInfo['lat']), floatval($addressInfo['lon']));
231
-			$this->config->setUserValue($this->userId, Application::APP_ID, 'altitude', strval($altitude));
232
-			return [
233
-				'lat' => $addressInfo['lat'],
234
-				'lon' => $addressInfo['lon'],
235
-				'address' => $formattedAddress,
236
-				'success' => true,
237
-			];
238
-		} else {
239
-			return ['success' => false];
240
-		}
241
-	}
215
+    /**
216
+     * Set address and resolve it to get coordinates
217
+     *
218
+     * @param string $address Any approximative or exact address
219
+     * @return WeatherStatusLocationWithSuccess with success state and address information (coordinates and formatted address)
220
+     */
221
+    public function setAddress(string $address): array {
222
+        $addressInfo = $this->searchForAddress($address);
223
+        if (isset($addressInfo['display_name']) && isset($addressInfo['lat']) && isset($addressInfo['lon'])) {
224
+            $formattedAddress = $this->formatOsmAddress($addressInfo);
225
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'address', $formattedAddress);
226
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'lat', strval($addressInfo['lat']));
227
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'lon', strval($addressInfo['lon']));
228
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'mode', strval(self::MODE_MANUAL_LOCATION));
229
+            // get and store altitude
230
+            $altitude = $this->getAltitude(floatval($addressInfo['lat']), floatval($addressInfo['lon']));
231
+            $this->config->setUserValue($this->userId, Application::APP_ID, 'altitude', strval($altitude));
232
+            return [
233
+                'lat' => $addressInfo['lat'],
234
+                'lon' => $addressInfo['lon'],
235
+                'address' => $formattedAddress,
236
+                'success' => true,
237
+            ];
238
+        } else {
239
+            return ['success' => false];
240
+        }
241
+    }
242 242
 
243
-	/**
244
-	 * Ask nominatim information about an unformatted address
245
-	 *
246
-	 * @param string Unformatted address
247
-	 * @return array{display_name?: string, lat?: string, lon?: string, error?: string} Full Nominatim result for the given address
248
-	 */
249
-	private function searchForAddress(string $address): array {
250
-		$params = [
251
-			'q' => $address,
252
-			'format' => 'json',
253
-			'addressdetails' => '1',
254
-			'extratags' => '1',
255
-			'namedetails' => '1',
256
-			'limit' => '1',
257
-		];
258
-		$url = 'https://nominatim.openstreetmap.org/search';
259
-		$results = $this->requestJSON($url, $params);
243
+    /**
244
+     * Ask nominatim information about an unformatted address
245
+     *
246
+     * @param string Unformatted address
247
+     * @return array{display_name?: string, lat?: string, lon?: string, error?: string} Full Nominatim result for the given address
248
+     */
249
+    private function searchForAddress(string $address): array {
250
+        $params = [
251
+            'q' => $address,
252
+            'format' => 'json',
253
+            'addressdetails' => '1',
254
+            'extratags' => '1',
255
+            'namedetails' => '1',
256
+            'limit' => '1',
257
+        ];
258
+        $url = 'https://nominatim.openstreetmap.org/search';
259
+        $results = $this->requestJSON($url, $params);
260 260
 
261
-		if (isset($results['error'])) {
262
-			return ['error' => (string)$results['error']];
263
-		}
261
+        if (isset($results['error'])) {
262
+            return ['error' => (string)$results['error']];
263
+        }
264 264
 
265
-		if (count($results) > 0 && is_array($results[0])) {
266
-			return [
267
-				'display_name' => (string)($results[0]['display_name'] ?? null),
268
-				'lat' => (string)($results[0]['lat'] ?? null),
269
-				'lon' => (string)($results[0]['lon'] ?? null),
270
-			];
271
-		}
265
+        if (count($results) > 0 && is_array($results[0])) {
266
+            return [
267
+                'display_name' => (string)($results[0]['display_name'] ?? null),
268
+                'lat' => (string)($results[0]['lat'] ?? null),
269
+                'lon' => (string)($results[0]['lon'] ?? null),
270
+            ];
271
+        }
272 272
 
273
-		return ['error' => $this->l10n->t('No result.')];
274
-	}
273
+        return ['error' => $this->l10n->t('No result.')];
274
+    }
275 275
 
276
-	/**
277
-	 * Get stored user location
278
-	 *
279
-	 * @return WeatherStatusLocationWithMode which contains coordinates, formatted address and current weather status mode
280
-	 */
281
-	public function getLocation(): array {
282
-		$lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', '');
283
-		$lon = $this->config->getUserValue($this->userId, Application::APP_ID, 'lon', '');
284
-		$address = $this->config->getUserValue($this->userId, Application::APP_ID, 'address', '');
285
-		$mode = $this->config->getUserValue($this->userId, Application::APP_ID, 'mode', self::MODE_MANUAL_LOCATION);
286
-		return [
287
-			'lat' => $lat,
288
-			'lon' => $lon,
289
-			'address' => $address,
290
-			'mode' => intval($mode),
291
-		];
292
-	}
276
+    /**
277
+     * Get stored user location
278
+     *
279
+     * @return WeatherStatusLocationWithMode which contains coordinates, formatted address and current weather status mode
280
+     */
281
+    public function getLocation(): array {
282
+        $lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', '');
283
+        $lon = $this->config->getUserValue($this->userId, Application::APP_ID, 'lon', '');
284
+        $address = $this->config->getUserValue($this->userId, Application::APP_ID, 'address', '');
285
+        $mode = $this->config->getUserValue($this->userId, Application::APP_ID, 'mode', self::MODE_MANUAL_LOCATION);
286
+        return [
287
+            'lat' => $lat,
288
+            'lon' => $lon,
289
+            'address' => $address,
290
+            'mode' => intval($mode),
291
+        ];
292
+    }
293 293
 
294
-	/**
295
-	 * Get forecast for current location
296
-	 *
297
-	 * @return list<WeatherStatusForecast>|array{error: string}|WeatherStatusSuccess which contains success state and filtered forecast data
298
-	 */
299
-	public function getForecast(): array {
300
-		$lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', '');
301
-		$lon = $this->config->getUserValue($this->userId, Application::APP_ID, 'lon', '');
302
-		$alt = $this->config->getUserValue($this->userId, Application::APP_ID, 'altitude', '');
303
-		if (!is_numeric($alt)) {
304
-			$alt = 0;
305
-		}
306
-		if (is_numeric($lat) && is_numeric($lon)) {
307
-			return $this->forecastRequest(floatval($lat), floatval($lon), floatval($alt));
308
-		} else {
309
-			return ['success' => false];
310
-		}
311
-	}
294
+    /**
295
+     * Get forecast for current location
296
+     *
297
+     * @return list<WeatherStatusForecast>|array{error: string}|WeatherStatusSuccess which contains success state and filtered forecast data
298
+     */
299
+    public function getForecast(): array {
300
+        $lat = $this->config->getUserValue($this->userId, Application::APP_ID, 'lat', '');
301
+        $lon = $this->config->getUserValue($this->userId, Application::APP_ID, 'lon', '');
302
+        $alt = $this->config->getUserValue($this->userId, Application::APP_ID, 'altitude', '');
303
+        if (!is_numeric($alt)) {
304
+            $alt = 0;
305
+        }
306
+        if (is_numeric($lat) && is_numeric($lon)) {
307
+            return $this->forecastRequest(floatval($lat), floatval($lon), floatval($alt));
308
+        } else {
309
+            return ['success' => false];
310
+        }
311
+    }
312 312
 
313
-	/**
314
-	 * Actually make the request to the forecast service
315
-	 *
316
-	 * @param float $lat Latitude of requested forecast, in decimal degree format
317
-	 * @param float $lon Longitude of requested forecast, in decimal degree format
318
-	 * @param float $altitude Altitude of requested forecast, in meter
319
-	 * @param int $nbValues Number of forecast values (hours)
320
-	 * @return list<WeatherStatusForecast>|array{error: string} Filtered forecast data
321
-	 */
322
-	private function forecastRequest(float $lat, float $lon, float $altitude, int $nbValues = 10): array {
323
-		$params = [
324
-			'lat' => number_format($lat, 2),
325
-			'lon' => number_format($lon, 2),
326
-			'altitude' => $altitude,
327
-		];
328
-		$url = 'https://api.met.no/weatherapi/locationforecast/2.0/compact';
329
-		$weather = $this->requestJSON($url, $params);
330
-		if (isset($weather['properties']) && isset($weather['properties']['timeseries']) && is_array($weather['properties']['timeseries'])) {
331
-			return array_slice($weather['properties']['timeseries'], 0, $nbValues);
332
-		}
333
-		return ['error' => $this->l10n->t('Malformed JSON data.')];
334
-	}
313
+    /**
314
+     * Actually make the request to the forecast service
315
+     *
316
+     * @param float $lat Latitude of requested forecast, in decimal degree format
317
+     * @param float $lon Longitude of requested forecast, in decimal degree format
318
+     * @param float $altitude Altitude of requested forecast, in meter
319
+     * @param int $nbValues Number of forecast values (hours)
320
+     * @return list<WeatherStatusForecast>|array{error: string} Filtered forecast data
321
+     */
322
+    private function forecastRequest(float $lat, float $lon, float $altitude, int $nbValues = 10): array {
323
+        $params = [
324
+            'lat' => number_format($lat, 2),
325
+            'lon' => number_format($lon, 2),
326
+            'altitude' => $altitude,
327
+        ];
328
+        $url = 'https://api.met.no/weatherapi/locationforecast/2.0/compact';
329
+        $weather = $this->requestJSON($url, $params);
330
+        if (isset($weather['properties']) && isset($weather['properties']['timeseries']) && is_array($weather['properties']['timeseries'])) {
331
+            return array_slice($weather['properties']['timeseries'], 0, $nbValues);
332
+        }
333
+        return ['error' => $this->l10n->t('Malformed JSON data.')];
334
+    }
335 335
 
336
-	/**
337
-	 * Make a HTTP GET request and parse JSON result.
338
-	 * Request results are cached until the 'Expires' response header says so
339
-	 *
340
-	 * @param string $url Base URL to query
341
-	 * @param array $params GET parameters
342
-	 * @return array which contains the error message or the parsed JSON result
343
-	 */
344
-	private function requestJSON(string $url, array $params = []): array {
345
-		$cacheKey = $url . '|' . implode(',', $params) . '|' . implode(',', array_keys($params));
346
-		$cacheValue = $this->cache->get($cacheKey);
347
-		if ($cacheValue !== null) {
348
-			return $cacheValue;
349
-		}
336
+    /**
337
+     * Make a HTTP GET request and parse JSON result.
338
+     * Request results are cached until the 'Expires' response header says so
339
+     *
340
+     * @param string $url Base URL to query
341
+     * @param array $params GET parameters
342
+     * @return array which contains the error message or the parsed JSON result
343
+     */
344
+    private function requestJSON(string $url, array $params = []): array {
345
+        $cacheKey = $url . '|' . implode(',', $params) . '|' . implode(',', array_keys($params));
346
+        $cacheValue = $this->cache->get($cacheKey);
347
+        if ($cacheValue !== null) {
348
+            return $cacheValue;
349
+        }
350 350
 
351
-		try {
352
-			$options = [
353
-				'headers' => [
354
-					'User-Agent' => 'NextcloudWeatherStatus/' . $this->version . ' nextcloud.com'
355
-				],
356
-			];
351
+        try {
352
+            $options = [
353
+                'headers' => [
354
+                    'User-Agent' => 'NextcloudWeatherStatus/' . $this->version . ' nextcloud.com'
355
+                ],
356
+            ];
357 357
 
358
-			$reqUrl = $url;
359
-			if (count($params) > 0) {
360
-				$paramsContent = http_build_query($params);
361
-				$reqUrl = $url . '?' . $paramsContent;
362
-			}
358
+            $reqUrl = $url;
359
+            if (count($params) > 0) {
360
+                $paramsContent = http_build_query($params);
361
+                $reqUrl = $url . '?' . $paramsContent;
362
+            }
363 363
 
364
-			$response = $this->client->get($reqUrl, $options);
365
-			$body = $response->getBody();
366
-			$headers = $response->getHeaders();
367
-			$respCode = $response->getStatusCode();
364
+            $response = $this->client->get($reqUrl, $options);
365
+            $body = $response->getBody();
366
+            $headers = $response->getHeaders();
367
+            $respCode = $response->getStatusCode();
368 368
 
369
-			if ($respCode >= 400) {
370
-				return ['error' => $this->l10n->t('Error')];
371
-			} else {
372
-				$json = json_decode($body, true);
369
+            if ($respCode >= 400) {
370
+                return ['error' => $this->l10n->t('Error')];
371
+            } else {
372
+                $json = json_decode($body, true);
373 373
 
374
-				// default cache duration is one hour
375
-				$cacheDuration = 60 * 60;
376
-				if (isset($headers['Expires']) && count($headers['Expires']) > 0) {
377
-					// if the Expires response header is set, use it to define cache duration
378
-					$expireTs = (new \DateTime($headers['Expires'][0]))->getTimestamp();
379
-					$nowTs = (new \DateTime())->getTimestamp();
380
-					$duration = $expireTs - $nowTs;
381
-					if ($duration > $cacheDuration) {
382
-						$cacheDuration = $duration;
383
-					}
384
-				}
385
-				$this->cache->set($cacheKey, $json, $cacheDuration);
374
+                // default cache duration is one hour
375
+                $cacheDuration = 60 * 60;
376
+                if (isset($headers['Expires']) && count($headers['Expires']) > 0) {
377
+                    // if the Expires response header is set, use it to define cache duration
378
+                    $expireTs = (new \DateTime($headers['Expires'][0]))->getTimestamp();
379
+                    $nowTs = (new \DateTime())->getTimestamp();
380
+                    $duration = $expireTs - $nowTs;
381
+                    if ($duration > $cacheDuration) {
382
+                        $cacheDuration = $duration;
383
+                    }
384
+                }
385
+                $this->cache->set($cacheKey, $json, $cacheDuration);
386 386
 
387
-				return $json;
388
-			}
389
-		} catch (\Exception $e) {
390
-			$this->logger->warning($url . ' API error : ' . $e->getMessage(), ['exception' => $e]);
391
-			return ['error' => $e->getMessage()];
392
-		}
393
-	}
387
+                return $json;
388
+            }
389
+        } catch (\Exception $e) {
390
+            $this->logger->warning($url . ' API error : ' . $e->getMessage(), ['exception' => $e]);
391
+            return ['error' => $e->getMessage()];
392
+        }
393
+    }
394 394
 }
Please login to merge, or discard this patch.