config = new weatherapi_c(); } public function requireModuleEnabled(): void { if (!$this->config->enabled->isTrue()) { throw new Exception('The weatherapi module is not enabled'); } } public function requireValidSecretKey(): void { if ($this->config->secret_key->getVariableValue() === null || $this->config->secret_key->getVariableValue() === '') { throw new Exception('Invalid secret key defined in the config (weatherapi_secret_key_c)'); } } public function sendRequest(string $endpoint, array $query = []): object { $this->requireModuleEnabled(); $this->requireValidSecretKey(); $endpoint = ltrim($endpoint, '/'); $query = array_merge(['key' => $this->config->secret_key->getVariableValue()], $query); $url = $this->api_url . $endpoint . '?' . http_build_query($query); $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', ]); $response = curl_exec($curl); $status_code = curl_getinfo($curl, CURLINFO_HTTP_CODE); $error = curl_error($curl); curl_close($curl); if ($error) { throw new Exception('cURL request failed: ' . $error); } if ($response === false || $response === '') { throw new Exception('Empty response from WeatherAPI'); } $decoded = json_decode($response); if (json_last_error() !== JSON_ERROR_NONE || !is_object($decoded) && !is_array($decoded)) { throw new Exception('Invalid response from WeatherAPI'); } if ($status_code >= 400) { $message = 'WeatherAPI request failed with HTTP ' . $status_code; if (is_object($decoded) && isset($decoded->error->message)) { $message .= ': ' . $decoded->error->message; } throw new Exception($message); } return (object)$decoded; } public function current(string $query, array $options = []): object { return $this->sendRequest('current.json', array_merge(['q' => $query], $options)); } public function forecast(string $query, int $days = 1, array $options = []): object { return $this->sendRequest('forecast.json', array_merge(['q' => $query, 'days' => $days], $options)); } public function history(string $query, string $date, array $options = []): object { return $this->sendRequest('history.json', array_merge(['q' => $query, 'dt' => $date], $options)); } public function astronomy(string $query, string $date, array $options = []): object { return $this->sendRequest('astronomy.json', array_merge(['q' => $query, 'dt' => $date], $options)); } public function timezone(string $query, array $options = []): object { return $this->sendRequest('timezone.json', array_merge(['q' => $query], $options)); } public function sports(string $query, array $options = []): object { return $this->sendRequest('sports.json', array_merge(['q' => $query], $options)); } public function search(string $query, array $options = []): object { return $this->sendRequest('search.json', array_merge(['q' => $query], $options)); } public function marine(string $query, int $days = 1, array $options = []): object { return $this->sendRequest('marine.json', array_merge(['q' => $query, 'days' => $days], $options)); } public function future(string $query, string $date, array $options = []): object { return $this->sendRequest('future.json', array_merge(['q' => $query, 'dt' => $date], $options)); } }