From 10b9f1bb0bac7b95cf6542aa979119d5a28958d8 Mon Sep 17 00:00:00 2001 From: "fefe.clochette" Date: Fri, 17 Apr 2026 17:27:57 +0200 Subject: [PATCH] preivision --- includes/lang/ca.php | 1 + includes/lang/fr.php | 1 + modules/holidays/holidays.js | 14 ++- modules/holidays/includes/api/get_weather.php | 96 +++++++++++++++---- modules/holidays/views/detail.php | 3 +- 5 files changed, 91 insertions(+), 24 deletions(-) diff --git a/includes/lang/ca.php b/includes/lang/ca.php index 04210d6..8cb568d 100644 --- a/includes/lang/ca.php +++ b/includes/lang/ca.php @@ -220,6 +220,7 @@ return [ 'weather_cloudy' => 'Ennuvolat', 'weather_rainy' => 'Plujós', 'weather_snowy' => 'Nevat', + 'weather_historical' => 'Basat en l\'històric (estimació)', // Anciennes clés Holidays non préfixées (conservades) 'outbound_trip' => 'Anada', diff --git a/includes/lang/fr.php b/includes/lang/fr.php index 416ed2b..faccd72 100644 --- a/includes/lang/fr.php +++ b/includes/lang/fr.php @@ -220,6 +220,7 @@ return [ 'weather_cloudy' => 'Nuageux', 'weather_rainy' => 'Pluvieux', 'weather_snowy' => 'Neigeux', + 'weather_historical' => 'Basé sur l\'historique (estimation)', // Anciennes clés Holidays non préfixées (conservées pour compatibilité si utilisées) 'outbound_trip' => 'Aller', diff --git a/modules/holidays/holidays.js b/modules/holidays/holidays.js index 99a6abf..75acdbc 100644 --- a/modules/holidays/holidays.js +++ b/modules/holidays/holidays.js @@ -49,10 +49,20 @@ async function loadWeatherForStep(pt) { if (res.success) { const info = getWeatherInfo(res.data.code); + + // Si c'est une estimation basée sur le passé, on adapte l'affichage + const approxSymbol = res.data.is_historical ? "~" : ""; + const badgeTitle = res.data.is_historical + ? `${info.label} (${tr("weather_historical")})` + : info.label; + const opacityStyle = res.data.is_historical + ? "opacity: 0.85; font-style: italic;" + : ""; + container.innerHTML = ` -
+
${info.icon} - ${Math.round(res.data.temp_min)}° / ${Math.round(res.data.temp_max)}°C + ${approxSymbol}${Math.round(res.data.temp_min)}° / ${Math.round(res.data.temp_max)}°C
`; } } catch (e) { diff --git a/modules/holidays/includes/api/get_weather.php b/modules/holidays/includes/api/get_weather.php index 3ac0012..c308b91 100644 --- a/modules/holidays/includes/api/get_weather.php +++ b/modules/holidays/includes/api/get_weather.php @@ -1,19 +1,18 @@ diff($targetDate); $daysDiff = (int)$interval->format('%R%a'); -// 4. Choix du bon modèle météo (Prévisions vs Historique) -if ($daysDiff < -2) { +// --- 🧠 GESTION INTELLIGENTE DU TEMPS (Prévisions vs Historique) --- +if ($daysDiff > 16) { + // 1. VOYAGE LOINTAIN : Calcul de la moyenne sur 3 ans + $currentYear = (int)$today->format('Y'); + $monthDay = $targetDate->format('m-d'); + if ($monthDay === '02-29') $monthDay = '02-28'; // Sécurité année bissextile + + $tempMaxSum = 0; + $tempMinSum = 0; + $validYearsCount = 0; + $representativeCode = 0; // On gardera le code de l'année N-1 + + for ($i = 1; $i <= 3; $i++) { + $pastYear = $currentYear - $i; + $searchDate = $pastYear . '-' . $monthDay; + + $url = "https://archive-api.open-meteo.com/v1/archive?latitude=$lat&longitude=$lng&daily=weather_code,temperature_2m_max,temperature_2m_min&timezone=auto&start_date=$searchDate&end_date=$searchDate"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 2); // Timeout court pour ne pas ralentir le serveur + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + $res = curl_exec($ch); + curl_close($ch); + + if ($res) { + $data = json_decode($res, true); + if (isset($data['daily']['temperature_2m_max'][0])) { + $tempMaxSum += $data['daily']['temperature_2m_max'][0]; + $tempMinSum += $data['daily']['temperature_2m_min'][0]; + + if ($i === 1) { // On prend le temps qu'il a fait à N-1 pour l'icône + $representativeCode = $data['daily']['weather_code'][0]; + } + $validYearsCount++; + } + } + } + + // Si on a pu récupérer au moins une année de données + if ($validYearsCount > 0) { + echo json_encode([ + 'success' => true, + 'data' => [ + 'code' => $representativeCode, + 'temp_max' => round($tempMaxSum / $validYearsCount, 1), // Moyenne arrondie à 1 décimale + 'temp_min' => round($tempMinSum / $validYearsCount, 1), + 'is_historical' => true + ] + ]); + } else { + echo json_encode(['success' => false, 'message' => 'Archives indisponibles']); + } + exit; // On arrête l'exécution ici pour les voyages lointains + +} elseif ($daysDiff < -2) { + // 2. VOYAGE PASSÉ : On interroge les archives pour cette date précise $baseUrl = "https://archive-api.open-meteo.com/v1/archive"; + $searchDate = $date; } else { + // 3. FUTUR PROCHE (Prévisions fiables) : On interroge les prévisions $baseUrl = "https://api.open-meteo.com/v1/forecast"; + $searchDate = $date; } -$url = "$baseUrl?latitude=$lat&longitude=$lng&daily=weather_code,temperature_2m_max,temperature_2m_min&timezone=auto&start_date=$date&end_date=$date"; +// --- APPEL API CLASSIQUE (Pour les prévisions et les voyages passés) --- +$url = "$baseUrl?latitude=$lat&longitude=$lng&daily=weather_code,temperature_2m_max,temperature_2m_min&timezone=auto&start_date=$searchDate&end_date=$searchDate"; -// 5. Interrogation d'Open-Meteo via cURL (plus robuste) $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); -curl_setopt($ch, CURLOPT_TIMEOUT, 5); // Timeout de 5 secondes max -curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Contourne les erreurs SSL en local - +curl_setopt($ch, CURLOPT_TIMEOUT, 5); +curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $res = curl_exec($ch); -$curlError = curl_error($ch); // On capture l'erreur exacte au cas où curl_close($ch); if (!$res) { - echo json_encode([ - 'success' => false, - 'message' => 'Erreur API Open-Meteo', - 'debug' => $curlError, // L'inspecteur JS nous donnera la vraie raison ! - 'url' => $url - ]); + echo json_encode(['success' => false, 'message' => 'Erreur API Open-Meteo']); exit; } -// 6. Formatage et envoi au Javascript + +$data = json_decode($res, true); + if (isset($data['daily']['weather_code'][0])) { echo json_encode([ 'success' => true, 'data' => [ 'code' => $data['daily']['weather_code'][0], 'temp_max' => $data['daily']['temperature_2m_max'][0], - 'temp_min' => $data['daily']['temperature_2m_min'][0] + 'temp_min' => $data['daily']['temperature_2m_min'][0], + 'is_historical' => false ] ]); } else { diff --git a/modules/holidays/views/detail.php b/modules/holidays/views/detail.php index 510527b..7c4048a 100644 --- a/modules/holidays/views/detail.php +++ b/modules/holidays/views/detail.php @@ -386,7 +386,8 @@ window.I18N = { 'weather_cloudy': "", 'weather_rainy': "", 'weather_snowy': "", - 'weather_forecast': "" + 'weather_forecast': "", + 'weather_historical': "" }; // Fallback de sécurité pour s'assurer que les modales peuvent toujours se fermer