Compare commits


No commits in common. 'master' and 'rainette2_compat_spip2_1' have entirely different histories.

.gitattributes vendored

@ -1,375 +1,7 @@
* text=auto !eol
demo/rainette.html -text
lang/rainette.xml -text
lang/rainette_ca.php -text
lang/rainette_es.php -text
lang/rainette_fa.php -text
lang/rainette_fr.php -text
lang/rainette_sk.php -text
modeles/conditions_tempsreel.html -text
modeles/infos_ville.html -text
modeles/previsions_12h.html -text
modeles/previsions_24h.html -text
modeles/rainette_conditions.html -text
modeles/rainette_infos.html -text
modeles/rainette_previsions.html -text
prive/themes/spip/images/apixu.png -text
prive/themes/spip/images/rainette-16.png -text
prive/themes/spip/images/rainette-24.png -text
prive/themes/spip/images/weather.png -text
prive/themes/spip/images/wunderground.png -text
/rainette_fonctions.php -text
/rainette_logo-64.png -text
/rainette_pipelines.php -text
services/codes.xlsx -text
services/weather.php -text
themes/apixu/original/day/113.png -text
themes/apixu/original/day/116.png -text
themes/apixu/original/day/119.png -text
themes/apixu/original/day/122.png -text
themes/apixu/original/day/143.png -text
themes/apixu/original/day/176.png -text
themes/apixu/original/day/179.png -text
themes/apixu/original/day/182.png -text
themes/apixu/original/day/185.png -text
themes/apixu/original/day/200.png -text
themes/apixu/original/day/227.png -text
themes/apixu/original/day/230.png -text
themes/apixu/original/day/248.png -text
themes/apixu/original/day/260.png -text
themes/apixu/original/day/263.png -text
themes/apixu/original/day/266.png -text
themes/apixu/original/day/281.png -text
themes/apixu/original/day/284.png -text
themes/apixu/original/day/293.png -text
themes/apixu/original/day/296.png -text
themes/apixu/original/day/299.png -text
themes/apixu/original/day/302.png -text
themes/apixu/original/day/305.png -text
themes/apixu/original/day/308.png -text
themes/apixu/original/day/311.png -text
themes/apixu/original/day/314.png -text
themes/apixu/original/day/317.png -text
themes/apixu/original/day/320.png -text
themes/apixu/original/day/323.png -text
themes/apixu/original/day/326.png -text
themes/apixu/original/day/329.png -text
themes/apixu/original/day/332.png -text
themes/apixu/original/day/335.png -text
themes/apixu/original/day/338.png -text
themes/apixu/original/day/350.png -text
themes/apixu/original/day/353.png -text
themes/apixu/original/day/356.png -text
themes/apixu/original/day/359.png -text
themes/apixu/original/day/362.png -text
themes/apixu/original/day/365.png -text
themes/apixu/original/day/368.png -text
themes/apixu/original/day/371.png -text
themes/apixu/original/day/374.png -text
themes/apixu/original/day/377.png -text
themes/apixu/original/day/386.png -text
themes/apixu/original/day/389.png -text
themes/apixu/original/day/392.png -text
themes/apixu/original/day/395.png -text
themes/apixu/original/night/113.png -text
themes/apixu/original/night/116.png -text
themes/apixu/original/night/119.png -text
themes/apixu/original/night/122.png -text
themes/apixu/original/night/143.png -text
themes/apixu/original/night/176.png -text
themes/apixu/original/night/179.png -text
themes/apixu/original/night/182.png -text
themes/apixu/original/night/185.png -text
themes/apixu/original/night/200.png -text
themes/apixu/original/night/227.png -text
themes/apixu/original/night/230.png -text
themes/apixu/original/night/248.png -text
themes/apixu/original/night/260.png -text
themes/apixu/original/night/263.png -text
themes/apixu/original/night/266.png -text
themes/apixu/original/night/281.png -text
themes/apixu/original/night/284.png -text
themes/apixu/original/night/293.png -text
themes/apixu/original/night/296.png -text
themes/apixu/original/night/299.png -text
themes/apixu/original/night/302.png -text
themes/apixu/original/night/305.png -text
themes/apixu/original/night/308.png -text
themes/apixu/original/night/311.png -text
themes/apixu/original/night/314.png -text
themes/apixu/original/night/317.png -text
themes/apixu/original/night/320.png -text
themes/apixu/original/night/323.png -text
themes/apixu/original/night/326.png -text
themes/apixu/original/night/329.png -text
themes/apixu/original/night/332.png -text
themes/apixu/original/night/335.png -text
themes/apixu/original/night/338.png -text
themes/apixu/original/night/350.png -text
themes/apixu/original/night/353.png -text
themes/apixu/original/night/356.png -text
themes/apixu/original/night/359.png -text
themes/apixu/original/night/362.png -text
themes/apixu/original/night/365.png -text
themes/apixu/original/night/368.png -text
themes/apixu/original/night/371.png -text
themes/apixu/original/night/374.png -text
themes/apixu/original/night/377.png -text
themes/apixu/original/night/386.png -text
themes/apixu/original/night/389.png -text
themes/apixu/original/night/392.png -text
themes/apixu/original/night/395.png -text
themes/apixu/original/night/Thumbs.db -text
themes/weather/sticker/0.png -text
themes/weather/sticker/1.png -text
themes/weather/sticker/10.png -text
themes/weather/sticker/11.png -text
themes/weather/sticker/12.png -text
themes/weather/sticker/13.png -text
themes/weather/sticker/14.png -text
themes/weather/sticker/15.png -text
themes/weather/sticker/16.png -text
themes/weather/sticker/17.png -text
themes/weather/sticker/18.png -text
themes/weather/sticker/19.png -text
themes/weather/sticker/2.png -text
themes/weather/sticker/20.png -text
themes/weather/sticker/21.png -text
themes/weather/sticker/22.png -text
themes/weather/sticker/23.png -text
themes/weather/sticker/24.png -text
themes/weather/sticker/25.png -text
themes/weather/sticker/26.png -text
themes/weather/sticker/27.png -text
themes/weather/sticker/28.png -text
themes/weather/sticker/29.png -text
themes/weather/sticker/3.png -text
themes/weather/sticker/30.png -text
themes/weather/sticker/31.png -text
themes/weather/sticker/32.png -text
themes/weather/sticker/33.png -text
themes/weather/sticker/34.png -text
themes/weather/sticker/35.png -text
themes/weather/sticker/36.png -text
themes/weather/sticker/37.png -text
themes/weather/sticker/38.png -text
themes/weather/sticker/39.png -text
themes/weather/sticker/4.png -text
themes/weather/sticker/40.png -text
themes/weather/sticker/41.png -text
themes/weather/sticker/42.png -text
themes/weather/sticker/43.png -text
themes/weather/sticker/44.png -text
themes/weather/sticker/45.png -text
themes/weather/sticker/46.png -text
themes/weather/sticker/47.png -text
themes/weather/sticker/5.png -text
themes/weather/sticker/6.png -text
themes/weather/sticker/7.png -text
themes/weather/sticker/8.png -text
themes/weather/sticker/9.png -text
themes/weather/sticker/na.png -text
themes/weatherbit/original/a01d.png -text
themes/weatherbit/original/a01n.png -text
themes/weatherbit/original/a02d.png -text
themes/weatherbit/original/a02n.png -text
themes/weatherbit/original/a03d.png -text
themes/weatherbit/original/a03n.png -text
themes/weatherbit/original/a04d.png -text
themes/weatherbit/original/a04n.png -text
themes/weatherbit/original/a05d.png -text
themes/weatherbit/original/a05n.png -text
themes/weatherbit/original/a06d.png -text
themes/weatherbit/original/a06n.png -text
themes/weatherbit/original/c01d.png -text
themes/weatherbit/original/c01n.png -text
themes/weatherbit/original/c02d.png -text
themes/weatherbit/original/c02n.png -text
themes/weatherbit/original/c03d.png -text
themes/weatherbit/original/c03n.png -text
themes/weatherbit/original/c04d.png -text
themes/weatherbit/original/c04n.png -text
themes/weatherbit/original/d01d.png -text
themes/weatherbit/original/d01n.png -text
themes/weatherbit/original/d02d.png -text
themes/weatherbit/original/d02n.png -text
themes/weatherbit/original/d03d.png -text
themes/weatherbit/original/d03n.png -text
themes/weatherbit/original/f01d.png -text
themes/weatherbit/original/f01n.png -text
themes/weatherbit/original/r01d.png -text
themes/weatherbit/original/r01n.png -text
themes/weatherbit/original/r02d.png -text
themes/weatherbit/original/r02n.png -text
themes/weatherbit/original/r03d.png -text
themes/weatherbit/original/r03n.png -text
themes/weatherbit/original/r04d.png -text
themes/weatherbit/original/r04n.png -text
themes/weatherbit/original/r05d.png -text
themes/weatherbit/original/r05n.png -text
themes/weatherbit/original/r06d.png -text
themes/weatherbit/original/r06n.png -text
themes/weatherbit/original/s01d.png -text
themes/weatherbit/original/s01n.png -text
themes/weatherbit/original/s02d.png -text
themes/weatherbit/original/s02n.png -text
themes/weatherbit/original/s03d.png -text
themes/weatherbit/original/s03n.png -text
themes/weatherbit/original/s04d.png -text
themes/weatherbit/original/s04n.png -text
themes/weatherbit/original/s05d.png -text
themes/weatherbit/original/s05n.png -text
themes/weatherbit/original/s06d.png -text
themes/weatherbit/original/s06n.png -text
themes/weatherbit/original/t01d.png -text
themes/weatherbit/original/t01n.png -text
themes/weatherbit/original/t02d.png -text
themes/weatherbit/original/t02n.png -text
themes/weatherbit/original/t03d.png -text
themes/weatherbit/original/t03n.png -text
themes/weatherbit/original/t04d.png -text
themes/weatherbit/original/t04n.png -text
themes/weatherbit/original/t05d.png -text
themes/weatherbit/original/t05n.png -text
themes/weatherbit/original/u00d.png -text
themes/weatherbit/original/u00n.png -text
themes/wunderground/observation/chanceflurries.png -text
themes/wunderground/observation/chancerain.png -text
themes/wunderground/observation/chancesleet.png -text
themes/wunderground/observation/chancesnow.png -text
themes/wunderground/observation/chancetstorms.png -text
themes/wunderground/observation/clear.png -text
themes/wunderground/observation/cloudy.png -text
themes/wunderground/observation/flurries.png -text
themes/wunderground/observation/fog.png -text
themes/wunderground/observation/hazy.png -text
themes/wunderground/observation/mostlycloudy.png -text
themes/wunderground/observation/mostlysunny.png -text
themes/wunderground/observation/nt_chanceflurries.png -text
themes/wunderground/observation/nt_chancerain.png -text
themes/wunderground/observation/nt_chancesleet.png -text
themes/wunderground/observation/nt_chancesnow.png -text
themes/wunderground/observation/nt_chancetstorms.png -text
themes/wunderground/observation/nt_clear.png -text
themes/wunderground/observation/nt_cloudy.png -text
themes/wunderground/observation/nt_flurries.png -text
themes/wunderground/observation/nt_fog.png -text
themes/wunderground/observation/nt_hazy.png -text
themes/wunderground/observation/nt_mostlycloudy.png -text
themes/wunderground/observation/nt_mostlysunny.png -text
themes/wunderground/observation/nt_partlycloudy.png -text
themes/wunderground/observation/nt_rain.png -text
themes/wunderground/observation/nt_sleet.png -text
themes/wunderground/observation/nt_snow.png -text
themes/wunderground/observation/nt_sunny.png -text
themes/wunderground/observation/nt_tstorms.png -text
themes/wunderground/observation/nt_unknown.png -text
themes/wunderground/observation/partlycloudy.png -text
themes/wunderground/observation/partlysunny.png -text
themes/wunderground/observation/rain.png -text
themes/wunderground/observation/sleet.png -text
themes/wunderground/observation/snow.png -text
themes/wunderground/observation/sunny.png -text
themes/wunderground/observation/tstorms.png -text
themes/wunderground/observation/unknown.png -text
themes/wunderground/observation/unused/cloudy.png -text
themes/wunderground/observation/unused/hail.png -text
themes/wunderground/observation/unused/light_rain.png -text
themes/wunderground/observation/unused/shower2.png -text
themes/wunderground/observation/unused/tstorm1.png -text
themes/wwo/original/day/113.png -text
themes/wwo/original/day/116.png -text
themes/wwo/original/day/119.png -text
themes/wwo/original/day/122.png -text
themes/wwo/original/day/143.png -text
themes/wwo/original/day/176.png -text
themes/wwo/original/day/179.png -text
themes/wwo/original/day/182.png -text
themes/wwo/original/day/185.png -text
themes/wwo/original/day/200.png -text
themes/wwo/original/day/227.png -text
themes/wwo/original/day/230.png -text
themes/wwo/original/day/248.png -text
themes/wwo/original/day/260.png -text
themes/wwo/original/day/263.png -text
themes/wwo/original/day/266.png -text
themes/wwo/original/day/281.png -text
themes/wwo/original/day/284.png -text
themes/wwo/original/day/293.png -text
themes/wwo/original/day/296.png -text
themes/wwo/original/day/299.png -text
themes/wwo/original/day/302.png -text
themes/wwo/original/day/305.png -text
themes/wwo/original/day/308.png -text
themes/wwo/original/day/311.png -text
themes/wwo/original/day/314.png -text
themes/wwo/original/day/317.png -text
themes/wwo/original/day/320.png -text
themes/wwo/original/day/323.png -text
themes/wwo/original/day/326.png -text
themes/wwo/original/day/329.png -text
themes/wwo/original/day/332.png -text
themes/wwo/original/day/335.png -text
themes/wwo/original/day/338.png -text
themes/wwo/original/day/350.png -text
themes/wwo/original/day/353.png -text
themes/wwo/original/day/356.png -text
themes/wwo/original/day/359.png -text
themes/wwo/original/day/362.png -text
themes/wwo/original/day/365.png -text
themes/wwo/original/day/368.png -text
themes/wwo/original/day/371.png -text
themes/wwo/original/day/374.png -text
themes/wwo/original/day/377.png -text
themes/wwo/original/day/386.png -text
themes/wwo/original/day/389.png -text
themes/wwo/original/day/392.png -text
themes/wwo/original/day/395.png -text
themes/wwo/original/night/113.png -text
themes/wwo/original/night/116.png -text
themes/wwo/original/night/119.png -text
themes/wwo/original/night/122.png -text
themes/wwo/original/night/143.png -text
themes/wwo/original/night/176.png -text
themes/wwo/original/night/179.png -text
themes/wwo/original/night/182.png -text
themes/wwo/original/night/185.png -text
themes/wwo/original/night/200.png -text
themes/wwo/original/night/227.png -text
themes/wwo/original/night/230.png -text
themes/wwo/original/night/248.png -text
themes/wwo/original/night/260.png -text
themes/wwo/original/night/263.png -text
themes/wwo/original/night/266.png -text
themes/wwo/original/night/281.png -text
themes/wwo/original/night/284.png -text
themes/wwo/original/night/293.png -text
themes/wwo/original/night/296.png -text
themes/wwo/original/night/299.png -text
themes/wwo/original/night/302.png -text
themes/wwo/original/night/305.png -text
themes/wwo/original/night/308.png -text
themes/wwo/original/night/311.png -text
themes/wwo/original/night/314.png -text
themes/wwo/original/night/317.png -text
themes/wwo/original/night/320.png -text
themes/wwo/original/night/323.png -text
themes/wwo/original/night/326.png -text
themes/wwo/original/night/329.png -text
themes/wwo/original/night/332.png -text
themes/wwo/original/night/335.png -text
themes/wwo/original/night/338.png -text
themes/wwo/original/night/350.png -text
themes/wwo/original/night/353.png -text
themes/wwo/original/night/356.png -text
themes/wwo/original/night/359.png -text
themes/wwo/original/night/362.png -text
themes/wwo/original/night/365.png -text
themes/wwo/original/night/368.png -text
themes/wwo/original/night/371.png -text
themes/wwo/original/night/374.png -text
themes/wwo/original/night/377.png -text
themes/wwo/original/night/386.png -text
themes/wwo/original/night/389.png -text
themes/wwo/original/night/392.png -text
themes/wwo/original/night/395.png -text
images/rainette-16.png -text
images/rainette-24.png -text
/plugin.xml -text
prive/exec/configurer_rainette.html -text
/rainette_options.php -text
/readme.txt -text

@ -1,35 +0,0 @@
* Ce fichier contient l'action `effacer_parametrage` lancée par un utilisateur pour
* effacer le paramétrage utilisateur d'un service donné.
if (!defined('_ECRIRE_INC_VERSION')) {
* Cette action permet à l'utilisateur d'effacer le paramétrage utioisateur d'un service.
* Cette action est réservée aux utilisateurs pouvant accéder à la configuration.
* Elle ne nécessite comme argument uniquement l'id du service.
* @return void
function action_effacer_parametrage_dist() : void {
// Sécurisation.
// L'argument attendu est l'id du service concerné.
$securiser_action = charger_fonction('securiser_action', 'inc');
$service = $securiser_action();
// Verification des autorisations : pour recharger laconfiguration il suffit
// d'avoir l'autorisation "configurer".
if (!autoriser('configurer')) {
echo minipres();
// Rechargement de touttes les configurations statiques de Rainette et des services.

@ -1,33 +0,0 @@
* Ce fichier contient l'action `recharger_configuration` lancée par un utilisateur pour
* recharger la configuration technique de Rainette et celle des services.
if (!defined('_ECRIRE_INC_VERSION')) {
* Cette action permet à l'utilisateur de recharger la configuration technique de Rainette et celle des services
* à partir de leur fichier YAML.
* Cette action est réservée aux utilisateurs pouvant accéder à la configuration.
* @return void
function action_recharger_configuration_dist() : void {
// Sécurisation.
// -- Aucun argument attendu.
// Verification des autorisations : pour recharger laconfiguration il suffit
// d'avoir l'autorisation "configurer".
if (!autoriser('configurer')) {
echo minipres();
// Rechargement de touttes les configurations statiques de Rainette et des services.

@ -1,51 +0,0 @@
/* Layout Gala 24 pour la demo de Rainette */
/* --------------------------------------- */
body{font: 76% arial,sans-serif}
p{margin:0 10px 10px}
a{display:block;color: #981793;padding:10px}
div#header h1{height:80px;line-height:80px;margin:0;
padding-left:10px;background: #eee;color: #79b30b}
div#content p{line-height:1.4}
div#footer{background: #333;color: #fff}
div#footer p{margin:0;padding:5px 10px}
/* Personnalisation pour la demo */
a.spip-admin-boutons {display: inline;}
div#header h1{color:#798f74}
div#header h1 img{vertical-align: middle;}
.h2{text-align:center;border-bottom:2px solid #798f74;color:#798f74}
table{border:1px solid #000000;border-collapse:collapse;}
caption {background:#333;color:#eee;}
th {font-weight: bold;border-bottom:1px solid #000}
thead th {background: #ddd;}
th,td,caption {padding: 0.75em;border-right:1px solid #000;}
tbody tr:nth-child(even) th,
tbody tr:nth-child(even) td,
tbody tr.even th,
tbody tr.even td {background: #eee;}
tbody tr td.erreur {background: #fbe3e4;}
tbody tr td.nonapi {background: #fff6bf;}
tbody tr td.groupe {background: #798f74; color: #fff; font-weight: bold; text-align: center;}
div.clearfix{margin-bottom:30px; display: block; clear: both;}
div.notice{padding:1em;color: #514721;border:2px solid #ffd324;background-color:#fff6bf;}
.menu .h2{border:0;color:#000;}
.menu .menu-items{margin-bottom: 0;}
.menu-items {border-bottom:0 none;border-top: 1px solid #eee;list-style: none outside none;margin: 0 0 1.5em;padding: 0;}
.menu-items .item {border-bottom: 1px solid #eee;clear: both;list-style: square outside none;margin-left: 0;overflow: hidden;padding: 0.75em 0;}
.menu-items .item:hover {background-color: #eee;}
.menu-items .item a {text-decoration:none;padding:0 0 0 1em;}
.menu-items .item a:hover {text-decoration:underline;}
.menu-items .item .on {padding:0 0 0 1em;}

@ -1,30 +0,0 @@
[(#REM) <!--
Afficher les données d'execution des services, à savoir, les compteurs d'appels de chaque service.
Arguments :
- aucun
<table class="spip">
<caption><strong>Ex&eacute;cution des services</strong></caption>
<BOUCLE_head(DATA) {source table, #LISTE{'dernier_appel', year, month, day, hour, minute, second}}>
<BOUCLE_service(DATA) {source table, #ENV{execution}}>
<BOUCLE_execution(DATA) {source table, #VALEUR}>

@ -1,52 +0,0 @@
[(#REM) <!--
Afficher les données de chaque service concerné dans un tableau permettant de comparer les valeurs et les types.
Arguments :
- mode : infos, conditions ou prévisions
- jeu : tableau du jeu de données service => lieu
- donnees : tableau global des données du mode pour chaque service concerné par le jeu
<table class="spip">
<caption><strong>Comparaisons des donn&#233;es de #ENV{mode}</strong></caption>
<BOUCLE_head(DATA) {source table, #ENV{jeu}}>
<BOUCLE_comparer(DATA) {source table, #ENV{donnees}}>
<BOUCLE_valeur(DATA) {source table, #ENV{jeu}}>
<td[ colspan=(#ENV{jeu}|count|plus{1})] class="groupe">
[-- (#VAL{rainette:groupe_}|concat{#_comparer:VALEUR|table_valeur{#CLE/groupe}}|_T) --]
[<br :><i>(#_comparer:VALEUR|table_valeur{#CLE/rangement})</i>]
<td[ class="(#_comparer:VALEUR|table_valeur{#CLE/erreur})"]>

@ -1,193 +0,0 @@
<!DOCTYPE html>
<html xml:lang="#LANG" lang="#LANG" xmlns="">
<meta http-equiv='Content-Type' content='text/html; charset=#CHARSET' />
<title>Rainette - Demo</title>
[<link rel="stylesheet" href="(#CHEMIN{demo/demo.css})" type="text/css" />]
#SET{service, #ENV{service, #VAL|rainette_service_defaut}}
#SET{mode, #ENV{mode, conditions}}
#SET{jeu, #VAL|rainette_debug_jeu_defaut}
#SET{lieu, #ENV{ville, #GET{jeu/#GET{service}}}}
<div id="container">
<div id="header">
<img height="48" width="48" title="Plugin Rainette" alt="Plugin Rainette" src="#CHEMIN_IMAGE{rainette-64.png}"/>
</div> <!--header-->
<div id="wrapper">
<div id="content">
<BOUCLE_service_parametre(CONDITION){si #GET{service}|rainette_debug_service_est_parametre}>
<a name="infos" href="#"></a>
<div class="clearfix">
<div class="clearfix">
<h3 class="h3">Utilisation du mod&eacute;le <strong>rainette_infos</strong></h3>
[(#MODELE{rainette_infos,lieu=#GET{lieu},sous_modele=infos_ville, service=#GET{service}})]
[<div class="clearfix">
<br />
<h3 class="h3">Affichage debug du tableau des informations</h3>
(#GET{lieu}|rainette_debug_afficher_cache{infos, #GET{service}})
<div class="clearfix">
<h3 class="h3">Utilisation de la balise <strong>RAINETTE_INFOS</strong></h3>
<li>Ville observ&eacute;e:&nbsp;[<strong>(#RAINETTE_INFOS{#GET{lieu}, ville, #GET{service}})</strong>]</li>
<li>Longitude, appel sans filtre unit&eacute;:&nbsp;[<strong>(#RAINETTE_INFOS{#GET{lieu}, longitude, #GET{service}})</strong>]</li>
<li>Latitude, appel avec filtre unit&eacute;:&nbsp;[<strong>(#RAINETTE_INFOS{#GET{lieu}, latitude, #GET{service}}|rainette_afficher_unite{angle, -1, #GET{service}})</strong>]</li>
<li>Appel sans type d'info pr&eacute;cis&eacute;e, on renvoie le tableau s&eacute;rialis&eacute;:&nbsp;[<strong>(#RAINETTE_INFOS{#GET{lieu}, '', #GET{service}})</strong>]</li>
<li>Appel sans argument, on renvoie une chaine vide:&nbsp;[<strong>(#RAINETTE_INFOS)</strong>]</li>
<a name="conditions" href="#"></a>
<div class="clearfix">
<h3 class="h3">Utilisation du mod&eacute;le <strong>rainette_conditions</strong></h3>
[(#MODELE{rainette_conditions,lieu=#GET{lieu},sous_modele=conditions_tempsreel, service=#GET{service}})]
[<div class="clearfix">
<br />
<h3 class="h3">Affichage debug du tableau des conditions</h3>
(#GET{lieu}|rainette_debug_afficher_cache{conditions, #GET{service}})
<a name="previsions" href="#"></a>
<div class="clearfix">
<div class="clearfix">
<h3 class="h3">Utilisation du mod&eacute;le <strong>rainette_previsions</strong>, pour les 5 jours suivants le jour courant (premier_jour=1, nombre_jours=5)</h3>
[(#MODELE{rainette_previsions,lieu=#GET{lieu},premier_jour=1,nombre_jours=5,sous_modele=previsions_24h, service=#GET{service}})]
<div class="clearfix">
[(#MODELE{rainette_previsions,lieu=#GET{lieu},premier_jour=1,nombre_jours=5,sous_modele=previsions_24h_table, service=#GET{service}})]
<div class="clearfix">
<h3 class="h3">Utilisation du mod&eacute;le <strong>rainette_previsions</strong>, pour du jour courant au maximum des pr&eacute;visions (premier_jour=0)</h3>
[(#MODELE{rainette_previsions,lieu=#GET{lieu},premier_jour=0,sous_modele=previsions_24h, service=#GET{service}})]
[<div class="clearfix">
<h3 class="h3">Affichage debug du tableau des pr&eacute;visions 24h</h3>
<p>Seul le jour suivant le jour courant est affich&eacute; \(index \[1\] du sous-tableau \[donnees\]\). La p&eacute;riodicit&eacute; utilis&eacute;e est celle par d&eacute;faut pour le service concern&eacute;.</p>
<br />
(#GET{lieu}|rainette_debug_afficher_cache{previsions, #GET{service}})
<div class="clearfix">
<h3 class="h3">Utilisation du mod&eacute;le <strong>rainette_previsions 12h</strong>, pour le jour courant et le lendemain (premier_jour=0, nombre_jours=2)</h3>
[(#MODELE{rainette_previsions,lieu=#GET{lieu},premier_jour=0,nombre_jours=2,sous_modele=previsions_12h, service=#GET{service}})]
<a name="comparaison" href="#"></a>
<p>L&eacute;gende du tableau :</p>
<li><strong><del>API</del></strong>&nbsp;: indique que la donn&eacute;e ne fait pas partie des informations fournies par le service</li>
<li><strong>Indisponible</strong>&nbsp;: indique que la donn&eacute;e est fournie par le service mais indisponible pour le moment</li>
<li><strong>Pr&eacute;visions</strong>&nbsp;: les donn&eacute;es affich&eacute;es correspondent &agrave; celles de demain</li>
<div class="clearfix">
<br />
#SET{donnees, #GET{mode}|rainette_debug_comparer_services{#GET{jeu}}}
<h2 class="h2">3 - ETAT D'EXECUTION DES SERVICES</h2>
<a name="execution" href="#"></a>
<div class="clearfix">
#SET{execution, #VAL|rainette_debug_afficher_execution}
#INCLURE{fond=demo/inc-afficher_execution, execution=#GET{execution}}
<h2 class="h2">4. - LANGUES SPIP NON INTEGREES</h2>
<a name="langues" href="#"></a>
<div class="clearfix">
[(#VAL|rainette_debug_verifier_langue_manquante|sinon{'Aucune langue SPIP manque'})]
<div class="notice">
Le service [(#GET{service}|rainette_afficher_service) ]n'est pas correctement param&eacute;m&eacute;tr&eacute;.
</div> <!--content-->
</div> <!--wrapper-->
<div id="navigation">
</div> <!--navigation-->
<div id="extra">
<div class="menu" id="services">
<h2 class="h2">M&eacute;t&eacute;o d'un service</h2>
<p>Choisissez un service pour afficher les mod&egrave;les informations, conditions et pr&eacute;visions (1.1, 1.2, 1.3)</p>
<ul class="menu-items">
<BOUCLE_services(DATA) {source table, #VAL{tableau}|rainette_lister_services{#EVAL{true}, #EVAL{true}}}>
[<li class="item">
(#SELF|parametre_url{service, #CLE}
<div class="menu" id="modes">
<h2 class="h2">Comparaison des services</h2>
<p>Choisissez un mode pour comparer les donn&eacute;es fournies par chaque service (2.0)</p>
<ul class="menu-items">
<BOUCLE_modes(DATA) {source table, #LISTE{infos, conditions, previsions}}>
[<li class="item">
(#SELF|parametre_url{mode, #VALEUR}
<div class="menu" id="configuration">
<h2 class="h2">Configuration des services</h2>
<p>Choisissez un service pour vous rendre sur sa page de configuration</p>
<ul class="menu-items">
<BOUCLE_configurations(DATA) {source table, #VAL{tableau}|rainette_lister_services}>
[<li class="item">
(#URL_ECRIRE{configurer_rainette}|parametre_url{service, #CLE}
</div> <!--extra-->
<div id="footer">
<p>Pour appeler la page de demo:</p>
<li><strong>http://monsite/spip.php?page=demo/rainette</strong> (Paris par d&eacute;faut) ou</li>
<li><strong>http://monsite/spip.php?page=demo/rainette&amp;ville=FRXXnnnn&amp;service=xxx</strong> pour pr&eacute;ciser la ville voire le service</li>
</div> <!--footer-->
</div> <!--container-->

@ -1,76 +0,0 @@
* Ce fichier contient les fonctions de service nécessitées par le plugin Cache Factory.
if (!defined('_ECRIRE_INC_VERSION')) {
* Renvoie la configuration spécifique des caches de Rainette.
* @param string $plugin Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier ou
* un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
* @return array Tableau de la configuration des types de cache du plugin.
function rainette_cache_configurer(string $plugin) : array {
// Initialisation du tableau de configuration avec les valeurs par défaut du plugin Cache.
$configuration = [
'meteo' => [
'racine' => '_DIR_VAR',
'sous_dossier' => true,
'nom_obligatoire' => ['lieu', 'donnees', 'langage'],
'nom_facultatif' => ['unite'],
'extension' => '.txt',
'securisation' => false,
'serialisation' => true,
'separateur' => '_',
'conservation' => 3600 * 24
return $configuration;
* Effectue le chargement du formulaire de vidage des caches de type `meteo` du plugin.
* L'intérêt est de permette le rangement des caches par service.
* @uses rainette_lister_services()
* @uses cache_repertorier()
* @param string $plugin Identifiant qui permet de distinguer le module appelant qui peut-être un plugin comme le noiZetier
* ou un script. Pour un plugin, le plus pertinent est d'utiliser le préfixe.
* @param array $valeurs Tableau des valeurs du formulaire à compléter
* @param array $options Tableau d'options qui peut être fourni par un plugin utilisateur uniquement si celui-ci fait appel
* au formulaire. La page cache_vider de Cache Factory n'utilise pas ce paramètre.
* Le tableau est passé à la fonction de service de chargement du formulaire uniquement.
* @param array $configuration Configuration complète des caches du type meteo du plugin utilisateur lue à partir de la meta de stockage.
* @return array Tableau des caches de type meteo.
function rainette_meteo_cache_formulaire_charger(string $plugin, array $valeurs, array $options, array $configuration) : array {
// On constitue la liste des services requis par l'appel
$services = rainette_lister_services('tableau', false);
// On récupère les caches et leur description pour donner un maximum d'explication sur le contenu.
foreach ($services as $_service => $_infos) {
// On récupère les caches du service
$filtres = ['sous_dossier' => $_service];
$caches = cache_repertorier('rainette', 'meteo', $filtres);
// Si il existe des caches pour le service on stocke les informations recueillies
if ($caches) {
$complement_titre = $_infos['actif']
? _T('rainette:service_actif')
: _T('rainette:service_inactif');
$valeurs['_caches']['meteo'][$_service]['titre'] = "{$_infos['nom']} ({$complement_titre})";
$valeurs['_caches']['meteo'][$_service]['liste'] = $caches;
return $valeurs;

@ -1,156 +0,0 @@
<div class="formulaire_spip formulaire_configurer formulaire_#FORM">
<h3 class="titrem"><:rainette:titre_form_configuration:></h3>
[<p class="reponse_formulaire reponse_formulaire_ok">(#ENV*{message_ok})</p>]
[<p class="reponse_formulaire reponse_formulaire_erreur">(#ENV*{message_erreur})</p>]
<form method="post" action="#ENV{action}"><div>
[(#REM) <!-- Configuration de la clé d'inscription si requise --> ]
<div class="editer-groupe">
#SET{type_cle, obligatoire}
[(#SET{url, [<a class="spip_out" rel="noreferrer noopener"[ href="(#ENV{_configuration/enregistrement/lien})"] target="_blank">(#ENV{_configuration/enregistrement/titre})</a>]})]
[(#SET{explication, #VAL{rainette:explication_configurer_cle_}
[(#SAISIE{input, inscription,
<div class="editer-groupe">
[(#REM) <!-- Configuration du système d'unité à utiliser pour les données météo --> ]
#SET{disable_unite, ''}
[(#ENV{service}|=={meteoconcept}|oui)#SET{disable_unite, s}]
[(#SAISIE{radio, unite,
data=#ARRAY{m, <:rainette:label_unite_metrique:>, s, <:rainette:label_unite_standard:>},
[(#REM) <!-- Configuration du système d'icônes à utiliser (sauf pour meteoconcept qui est limité à la France) --> ]
[(#SAISIE{radio, condition,
[(#REM) <!-- Configuration du thème d'icônes distant à utiliser pour le service --> ]
[(#SAISIE{radio, theme,
[(#REM) <!-- Configuration du thème d'icônes local à utiliser pour le service --> ]
[(#SAISIE{radio, theme_local,
[(#REM) <!-- Configuration du thème d'icônes local du service weather à utiliser pour le service --> ]
[(#SAISIE{radio, theme_weather,
[(#SET{url, [<a class="spip_out" rel="noreferrer noopener"[ href="(#ENV{_configuration/offres/lien})"] target="_blank">(#ENV{_configuration/offres/titre})</a>]})]
[(#SET{gratuite, oui})]
[(#ENV{_configuration/offres/gratuite}|non)#SET{gratuite, non}]
[<p>(#VAL{rainette:explication_utilisation_gratuite_}|concat{#GET{gratuite}}|_T{#ARRAY{url, #GET{url}}})</p>]
<BOUCLE_compteurs(DATA) {source table, #ENV{_configuration/offres/limites}}>
<td>[<strong>#ENV{_utilisation/compteurs/#CLE}</strong> / (#VALEUR)]</td>
[(#SET{url, [<a class="spip_out" rel="noreferrer noopener"[ href="(#ENV{_configuration/termes/lien})"] target="_blank">(#ENV{_configuration/termes/titre})</a>]})]
<br /><:rainette:explication_credit_page{url=#GET{url}}:>
<input type="hidden" name="_meta_casier" value="#ENV{_meta_casier}" />
<p class="boutons">
<input type="submit" name="_cfg_ok" class="submit" value="<:bouton_valider:>" />
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery("input[name='condition']").change(function() {
if (jQuery("input[name='condition']:checked").val() == ['(#ENV{service})']) {
} else if (jQuery("input[name='condition']:checked").val() == 'weather') {
} else {

@ -1,77 +0,0 @@
* Gestion du formulaire de configuration du plugin Rainette.
if (!defined('_ECRIRE_INC_VERSION')) {
* On surcharge la fonction de chargement par défaut afin de fournir le service, sa configuration
* et son état d'exécution au formulaire.
* @param string $service Alias du service.
* @return array Tableau des données à charger par le formulaire.
function formulaires_configurer_rainette_service_charger(string $service) : array {
// On récupère le service par défaut si besoin
if (!$service) {
$service = rainette_service_defaut();
// Récupération de la configuration générale du service.
$configuration = configuration_service_lire($service, 'service');
// Normalisation de la configuration utilisateur du service afin d'éviter de gérer
// au sein du formulaire des valeurs par défaut.
$valeurs = parametrage_service_normaliser($service, $configuration['defauts']);
// Ajout du service et des éléments utiles de la configuration statique
$valeurs['service'] = $service;
$valeurs['nom'] = $configuration['nom'];
$valeurs['_configuration']['termes'] = $configuration['termes'];
$valeurs['_configuration']['enregistrement'] = $configuration['enregistrement'];
$valeurs['_configuration']['offres'] = $configuration['offres'];
// Ajout des informations d'utilisation du service
$execution = lire_config("rainette_execution/{$service}", []);
$valeurs['_utilisation']['dernier_appel'] = $execution['dernier_appel'] ?? '';
if (isset($execution['compteurs'])) {
$valeurs['_utilisation']['compteurs'] = $execution['compteurs'];
} else {
// On initialise les limites à zéro
$valeurs['_utilisation']['compteurs'] = [];
foreach ($configuration['offres']['limites'] as $_periode => $_limite) {
$valeurs['_utilisation']['compteurs'][$_periode] = 0;
// Gestion des thèmes locaux et distants.
// -- liste des types de thèmes
$valeurs['_themes']['types'] = [
$service => _T('rainette:label_icone_natif'),
"{$service}_local" => _T('rainette:label_icone_local'),
'weather' => _T('rainette:label_icone_weather')
// -- Présence de chaque type de thème pour le service concerné
$valeurs['_themes']['icone_api'] = !in_array($service, ['accuweather', 'meteoconcept']);
$valeurs['_themes']['distants'] = rainette_lister_themes($service, 'api');
$valeurs['_themes']['locaux'] = rainette_lister_themes($service);
$valeurs['_themes']['weather'] = $service != 'weather'
? rainette_lister_themes('weather')
: [];
// -- Construction du disable pour chaque choix de type de thème
$themes_disabled = $valeurs['_themes']['icone_api'] ? '' : $service;
$themes_disabled .= $valeurs['_themes']['locaux'] ? '' : ($themes_disabled ? ',' : '') . "{$service}_local";
$themes_disabled .= $valeurs['_themes']['weather'] ? '' : ($themes_disabled ? ',' : '') . 'weather';
$valeurs['_themes']['disabled'] = $themes_disabled;
// On positionne le meta casier car la fonction de recensement automatique n'est plus appelée ni ne pourrait
// fonctionner avec un hidden dont la valeur est dynamique (utilisation d'une variable d'environnement #ENV).
$valeurs['_meta_casier'] = "rainette/{$service}";
return $valeurs;

@ -1 +0,0 @@

Binary file not shown.


Width:  |  Height:  |  Size: 885 B

Binary file not shown.


Width:  |  Height:  |  Size: 1.5 KiB

@ -1,312 +0,0 @@
* Ce fichier contient la fonction standard de chargement et fourniture des données météo.
* Elle s'applique à tous les services et à tous les types de données.
if (!defined('_ECRIRE_INC_VERSION')) {
* Renvoyer le contenu du fichier cache des données météos correspondant au lieu et au type de données choisis
* après l'avoir éventuellement mis à jour.
* Si le fichier cache est obsolète ou absent, on le crée après avoir chargé puis phrasé le flux XML ou JSON
* et stocké les données collectées et transcodées dans un tableau standardisé. L'appelant doit s'assurer que la
* périodicité est compatible avec le service; cette fonction ne retourne donc que des erreurs de chargement.
* @uses rainette_service_defaut()
* @uses service_est_indisponible()
* @uses erreur_normaliser_extras()
* @uses configuration_service_lire()
* @uses parametrage_service_normaliser()
* @uses cache_normaliser()
* @uses cache_est_valide()
* @uses requete_autorisee()
* @uses meteo_normaliser()
* @uses indice2risque_uv()
* @uses cache_ecrire()
* @uses cache_lire()
* @param string $lieu Le lieu concerné par la méteo exprimé selon les critères requis par le service.
* @param null|string $mode Le type de données météorologiques demandé :
* - `conditions`, la valeur par défaut
* - `previsions`
* - `infos`
* @param null|int $periodicite La périodicité horaire des prévisions :
* - `24`, les prévisions de la journée
* - `12`, les prévisions du jour et de la nuit
* - `6`, les prévisions de la journée par période de 6h
* - `3`, les prévisions de la journée par période de 3h
* - `1`, les prévisions de la journée pour chaque heure
* - `0`, pour les modes `conditions` et `infos`
* @param null|string $service Le nom abrégé du service :
* - `owm` pour OpenWeather, la valeur par défaut car elle propose un plan gratuit
* - `weatherbit` pour
* - `weatheapi` pour WeatherAPI
* - `accuweather` pour AccuWeather
* - `wwo` pour World Weather Online
* - `meteoconcept` pour Meteo-Concept
* @throws Exception
* @return array Le contenu du fichier cache contenant les données à jour demandées.
function inc_meteo_charger_dist(string $lieu, ?string $mode = 'conditions', ?int $periodicite = 0, ?string $service = '') : array {
// Initialisation du tableau de sortie.
$tableau = [];
// Traitement des cas ou les arguments sont vides (ce qui est différent de non passés à l'appel)
// On considère à ce stade que la cohérence entre le mode, la périodicité et le service (qui selon ne supporte
// pas toutes les périodicités) est déjà assurée et n'est donc pas à tester.
if (!$mode) {
$mode = 'conditions';
$periodicite = 0;
if (!$service) {
$service = rainette_service_defaut();
// On vérifie d'abord si le service est connu et actif car sinon il est inutile de continuer.
// -- on initialise le bloc d'erreur
$erreur = [
'type' => '',
'service' => [
'code' => '',
'message' => ''
// -- on vérifie le service qui renvoie un type d'erreur ou vide sinon.
if ($erreur['type'] = service_est_indisponible($service)) {
// Service nok :
// -----------
// On construit le tableau directement sans passer par un cache.
$tableau = [
'donnees' => [],
'extras' => erreur_normaliser_extras($erreur, $lieu, $mode, $periodicite, $service)
} else {
// Service ok :
// ----------
// En fonction du service, on inclut le fichier d'API.
// Le principe est que chaque service propose la même liste de fonctions d'interface dans un fichier unique.
// Acquérir la configuration statique du service (periode, format, données...)
$configuration = configuration_service_lire($service, $mode);
// Acquérir la configuration dynamique du service (celle modifiable par l'utilisateur via
// le formulaire et stockée en BDD dans la table spip_meta) et la merger avec la configuration statique.
// Cependant, celle-ci pouvant être incomplète on la complète par les valeurs par défaut quand
// cela est nécessaire.
$configuration_utilisateur = parametrage_service_normaliser($service, $configuration['defauts']);
// Concaténer l'ensemble des configurations.
$configuration = array_merge($configuration, $configuration_utilisateur);
// Si on a demandé le mode 'previsions' sans préciser la periodicité horaire des données, il faut prendre l'intervalle
// par défaut configuré pour le service.
if (
($mode === 'previsions')
and !$periodicite
) {
$periodicite = $configuration['previsions']['periodicite_defaut'];
// Construire le tableau identifiant le cache
$cache = cache_normaliser($lieu, $mode, $periodicite, $configuration);
// Mise à jour du cache avec les nouvelles données météo si:
// - le fichier cache n'existe pas
// - la période de validité du cache est échue
if (!$fichier_cache = cache_est_valide('rainette', 'meteo', $cache)) {
// Construire l'url de la requête
$urler = "{$service}_service2url";
$url = $urler($lieu, $mode, $periodicite, $configuration);
// Acquérir le flux XML ou JSON dans un tableau si les limites du service ne sont pas atteintes
// et traiter les cas d'erreurs du plugin ou du service.
if (!requete_autorisee($configuration['offres']['limites'], $service)) {
// La requête n'est pas autorisée parce qu'elle excède les limitations d'utilisation du service.
// On renvoie une erreur pour prévenir les utilisateurs.
$erreur['type'] = 'limite_service';
} else {
$flux = requeter($url, $configuration, $service);
if (!empty($flux['erreur'])) {
// Erreur lors du traitement de la requête due à l'URL ou à la conversion en XML ou JSON.
// Cette erreur n'est pas retournée par le service.
$erreur['type'] = $flux['erreur'];
} else {
// On teste une erreur d'acquisition renvoyée par le service. Pour tous les services, une cle de base
// est explicitement utilisée pour distinguer les erreurs; sa présence permet d'identifier un cas d'erreur.
$configuration_erreur = configuration_service_lire($service, 'erreurs');
$flux_erreur = $flux;
if (!empty($configuration_erreur['cle_base'])) {
$flux_erreur = table_valeur($flux, implode('/', $configuration_erreur['cle_base']), null);
// On normalise le flux en utilisant le mode d'erreur pour vérifier si on obtient bien une erreur.
$erreur_service = meteo_normaliser($configuration_erreur, 'erreurs', $flux_erreur, -1);
$verifier = "{$service}_erreur_verifier";
if ($verifier($erreur_service)) {
// Une erreur est renvoyée par le service, on formate l'erreur correctement.
$erreur['type'] = 'reponse_service';
$erreur['service'] = array_merge($erreur['service'], $erreur_service);
} else {
// On se positionne sur le niveau de base du flux des données où commence le tableau des données météorologiques.
if (!empty($configuration['cle_base'])) {
$flux = table_valeur($flux, implode('/', $configuration['cle_base']), null);
if (empty($flux)) {
// Pas d'erreur retournée par le service mais aucune donnée fournie. Ce cas est peut-être impossible
// mais on le traite tout de même par sécurité avec un type particulier.
$erreur['type'] = 'aucune_donnee';
} else {
// En mode prévisions, le niveau de base est un tableau de n éléments, chaque élément étant un tableau contenant
// les données météorologiques d'un jour à venir ([0] => jour0[], [1] => jour1[]...).
// En mode infos ou conditions, on a directement accès aux données météorologiques (jour[]).
// Pour réaliser un traitement standard, on transforme donc le jour[] en un tableau d'un seul élément ([0] => jour[])
// qui pourra être traité comme celui des prévisions.
if (
($mode === 'conditions')
or ($mode === 'infos')
) {
$flux = [$flux];
// Convertir le flux en tableau standard pour la mise en cache. Ce traitement se déroule en
// 3 étapes :
// -1- initialisation du tableau standard à partir uniquement des données reçues du service
// -2- complément du tableau avec les données propres à chaque service
// -3- complément du tableau avec les données communes à tous les services
foreach ($flux as $_index_jour => $_flux_jour) {
// Pour les prévisions, certains services proposent les flux heure non pas en index numérique
// mais en index alpha comme 'day' ou 'night'.
// Pour ces services, il est nécessaire de réorganiser le flux jour pour que les flux heure
// soient adressables et numériques.
$arranger = "{$service}_flux2{$mode}";
if (function_exists($arranger)) {
$_flux_jour = $arranger($_flux_jour, $periodicite, $configuration);
// Pour les informations et les conditions les données récupérées concernent toute la même "période".
// Par contre, pour les prévisions on distingue 2 type de données :
// - celles du jour indépendamment de la période horaire
// - celles correspondant à une période horaire choisie (24, 12, 6, 3, 1)
// Ces données sont stockées à un index horaire de 0 à n qui représente la période horaire.
// Pour avoir un traitement identique pour les deux types de données on considère que l'index horaire
// des données jour est égal à -1.
// On crée donc le tableau des index correspondant au mode choisi et on boucle dessus.
$periodes_horaires = [-1];
if ($periodicite) {
for ($i = 0; $i < (24 / $periodicite); $i++) {
$periodes_horaires[] = $i;
// On détermine le flux heure en fonction du service. Ce flux heure coincide avec le flux jour dans
// la majeure partie des cas
$flux_heure = $_flux_jour;
if (
(count($periodes_horaires) > 1)
and !empty($configuration['cle_heure'])
) {
$flux_heure = table_valeur($_flux_jour, implode('/', $configuration['cle_heure']), null);
// On boucle sur chaque période horaire pour remplir le tableau complet.
foreach ($periodes_horaires as $_periode) {
// 1- Initialiser le tableau normalisé des informations à partir des données brutes
// fournies par le service.
// Suivant la période il faut prendre le flux jour ou le flux heure. On calcule donc le flux heure
// quand c'est nécessaire.
$flux_a_normaliser = ($_periode === -1)
? $_flux_jour
: ($configuration['structure_heure'] ? $flux_heure[$_periode] : $flux_heure);
$donnees = meteo_normaliser($configuration, $mode, $flux_a_normaliser, $_periode);
if ($donnees) {
// 2- Compléments spécifiques au service et au mode.
// Si ces compléments sont inutiles, la fonction n'existe pas
$completer = "{$service}_complement2{$mode}";
if (function_exists($completer)) {
$donnees = $mode === 'previsions'
? $completer($donnees, $configuration, $_periode)
: $completer($donnees, $configuration);
// 3- Compléments standard communs à tous les services
// Calcul du risque uv à partir de l'indice uv si celui-ci est fourni
if (
and is_float($donnees['indice_uv'])
) {
$donnees['risque_uv'] = indice2risque_uv($donnees['indice_uv']);
// Ajout du bloc à l'index en cours
if ($_periode === -1) {
$tableau[$_index_jour] = $donnees;
} else {
$tableau[$_index_jour]['heure'][$_periode] = $donnees;
// 4- Compléments standard à tous les services et tous les modes
$extras = erreur_normaliser_extras($erreur, $lieu, $mode, $periodicite, $service, $configuration);
// On range les données et les extras dans un tableau associatif à deux entrées ('donnees', 'extras')
if ($tableau) {
// Pour les modes "conditions" et "infos" l'ensemble des données météo est accessible sous
// l'index 'donnees'. Il faut donc supprimer l'index 0 provenant du traitement commun avec
// les prévisions.
// Pour les prévisions l'index 0 à n désigne le jour, il faut donc le conserver
$tableau = [
'donnees' => ($mode != 'previsions' ? array_shift($tableau) : $tableau),
'extras' => $extras
} else {
// Traitement des erreurs de flux. On positionne toujours les bloc extra contenant l'erreur,
// le bloc des données qui est mis à tableau vide dans ce cas à l'index 1.
$tableau = [
'donnees' => [],
'extras' => $extras
// Pipeline de fin de chargement des données météo. Peut-être utilisé :
// -- pour effectuer des traitements annexes à partir des données météo (archivage, par exemple)
// -- pour ajouter ou modifier des données au tableau (la modification n'est pas conseillée cependant)
$tableau = pipeline(
'args' => ['lieu' => $lieu, 'mode' => $mode, 'service' => $service],
'data' => $tableau
// Mise à jour du cache
cache_ecrire('rainette', 'meteo', $cache, $tableau);
} else {
// Lecture des données du fichier cache valide
$tableau = cache_lire('rainette', 'meteo', $fichier_cache);
return $tableau;

@ -1,211 +0,0 @@
* Ce fichier contient les fonctions de conversion entre unités, en particulier, les conversions du système métrique
* vers le système impérial US.
if (!defined('_ECRIRE_INC_VERSION')) {
* Lister les 16 directions abrégées en anglais ainsi que la direction variable.
* @return array Liste des directions abrégées.
function lister_directions() : array {
static $liste_directions = [
0 => 'N',
1 => 'NNE',
2 => 'NE',
3 => 'ENE',
4 => 'E',
5 => 'ESE',
6 => 'SE',
7 => 'SSE',
8 => 'S',
9 => 'SSW',
10 => 'SW',
11 => 'WSW',
12 => 'W',
13 => 'WNW',
14 => 'NW',
15 => 'NNW',
16 => 'N',
17 => 'V'
return $liste_directions;
* Convertit un angle en degré en une direction sur 16 valeurs.
* @param int $angle Angle du vent exprimé en degrés.
* @return string Direction du vent en abrégée anglais standard selon 16 directions.
function angle2direction(int $angle) : string {
static $liste_directions = [];
if (!$liste_directions) {
$liste_directions = lister_directions();
$direction = $liste_directions[round($angle / 22.5) % 16];
return $direction;
* Convertit un indice UV normalisé en une chaine correspondant à un niveau de risque.
* @param int $indice_uv Entier représentant l'indice UV
* @return string Chaine représentant le risque lié à l'indice UV. Cette chaine permet de calculer
* l'item de langue du risque dans la langue requise.
function indice2risque_uv(int $indice_uv) : string {
$risque_uv = '';
if (is_float($indice_uv)) {
if ($indice_uv >= 11) {
$risque_uv = 'extreme';
} elseif ($indice_uv >= 8) {
$risque_uv = 'tres_eleve';
} elseif ($indice_uv >= 6) {
$risque_uv = 'eleve';
} elseif ($indice_uv >= 3) {
$risque_uv = 'modere';
} elseif ($indice_uv >= 0) {
$risque_uv = 'faible';
return $risque_uv;
* Convertit des kilomètres en miles.
* @param float $kilometre La valeur réelle en kilomètres.
* @return float La valeur réelle correspondante convertie en miles
function kilometre2mile(float $kilometre) : float {
return 0.6215 * $kilometre;
* Convertit des miles en kilomètres.
* @param float $miles La valeur réelle en miles.
* @return float La valeur réelle correspondante convertie en kilomètres
function mile2kilometre(float $miles) : float {
return $miles / 0.6215;
* Convertit des températures celsius en farenheit.
* @param int $celsius La valeur réelle en degrés celsius.
* @return float La valeur réelle correspondante convertie en farenheit.
function celsius2farenheit(int $celsius) : float {
return $celsius * 9 / 5 + 32;
* Convertit des températures celsius en farenheit.
* @param int $farenheit La valeur réelle en degrés celsius.
* @return float La valeur réelle correspondante convertie en farenheit.
function farenheit2celsius(int $farenheit) : float {
return ($farenheit - 32) * 5 / 9;
* Convertit des millimètres en pouces.
* @param float $millimetre La valeur réelle en millimètres
* @return float La valeur réelle correspondante convertie en pouces.
function millimetre2inch(float $millimetre) : float {
return $millimetre / 25.4;
* Convertit des pressions millibar en pouces.
* @param float $millibar La valeur réelle en millibars
* @return float La valeur réelle correspondante convertie en pouces.
function millibar2inch(float $millibar) : float {
return $millibar / 33.86;
* Calcule la température ressentie (refroidissement éolien) en degrés celsius.
* Le calcul n'a de sens que pour des températures réelles supérieures à -50°C et inférieures à 10°C.
* Au-delà de ces valeurs, la fonction renvoie la température réelle fournie en entrée.
* @param float $temperature Température réelle mesurée en celsius.
* @param float $vitesse_vent Vitesse du vent en kilomètre par heure.
* @param null|string $unite Système d'unité métrique (`m`, défaut) ou impérial (`s`)
* @return float Température ressentie arrondie en entier et exprimée en degrés celsius.
function temperature2ressenti(float $temperature, float $vitesse_vent, ?string $unite = 'm') : float {
// On convertit en système métrique pour effectuer le calcul
if ($unite !== 'm') {
$temperature = farenheit2celsius($temperature);
$vitesse_vent = mile2kilometre($vitesse_vent);
// Calcul du refroidissement éollien en système métrique
if (($temperature >= -50) and ($temperature <= 10)) {
if ($vitesse_vent > 4.8) {
$ressenti = 13.12 + 0.6215 * $temperature + (0.3965 * $temperature - 11.37) * pow($vitesse_vent, 0.16);
} else {
$ressenti = $temperature + 0.2 * (0.1345 * $temperature - 1.59) * $vitesse_vent;
$ressenti = round($ressenti, 0);
} else {
$ressenti = $temperature;
// Si le système impérial est demandé, on convertit la température
if ($unite !== 'm') {
$ressenti = celsius2farenheit($ressenti);
return $ressenti;
* Convertit en kilomètres une valeur en mètres.
* @param int $metre La valeur entière en mètres
* @return float La valeur correspondante convertie en kilomètres.