source: spip-zone/_plugins_/rainette/trunk/rainette_fonctions.php @ 108251

Last change on this file since 108251 was 108251, checked in by eric@…, 19 months ago

Quelques corrections et modifications pour accueillir le plugin de gestion des thèmes.

File size: 15.1 KB
Line 
1<?php
2
3if (!defined('_ECRIRE_INC_VERSION')) {
4        return;
5}
6
7if (!defined('_RAINETTE_ICONES_GRANDE_TAILLE')) {
8        define('_RAINETTE_ICONES_GRANDE_TAILLE', 110);
9}
10if (!defined('_RAINETTE_ICONES_PETITE_TAILLE')) {
11        define('_RAINETTE_ICONES_PETITE_TAILLE', 28);
12}
13
14// Balises du plugin utilisables dans les squelettes et modèles
15/**
16 * @param $p
17 *
18 * @return mixed
19 */
20function balise_RAINETTE_INFOS($p) {
21
22        $lieu = interprete_argument_balise(1, $p);
23        $lieu = isset($lieu) ? str_replace('\'', '"', $lieu) : '""';
24        $type_info = interprete_argument_balise(2, $p);
25        $type_info = isset($type_info) ? str_replace('\'', '"', $type_info) : '""';
26        $service = interprete_argument_balise(3, $p);
27        $service = isset($service) ? str_replace('\'', '"', $service) : '"weather"';
28
29        $p->code = 'calculer_infos(' . $lieu . ', ' . $type_info . ', ' . $service . ')';
30        $p->interdire_scripts = false;
31
32        return $p;
33}
34
35/**
36 * @param string $lieu
37 * @param string $type
38 * @param string $service
39 *
40 * @return mixed
41 */
42function calculer_infos($lieu, $type, $service) {
43
44        // Initialisation du retour
45        $info = '';
46
47        // Traitement des cas ou les arguments sont vides
48        if ($lieu) {
49                if (!$service) {
50                        $service = 'weather';
51                }
52
53                // Récupération des informations sur le lieu
54                $charger = charger_fonction('meteo_charger', 'inc');
55                $nom_cache = $charger($lieu, 'infos', 0, $service);
56                lire_fichier($nom_cache, $contenu_cache);
57                if (!isset($type) or !$type) {
58                        $info = $contenu_cache;
59                } else {
60                        $tableau = unserialize($contenu_cache);
61                        if (isset($tableau['donnees'][strtolower($type)])) {
62                                $info = $tableau['donnees'][strtolower($type)];
63                        }
64                }
65        }
66
67        return $info;
68}
69
70/**
71 * Affiche l'icône correspondant au code météo fourni.
72 *
73 * @api
74 * @filtre
75 *
76 * @param array  $icone
77 * @param string $taille
78 *
79 * @return string
80 */
81function rainette_afficher_icone($icone, $taille = 'petit') {
82
83        // Initialisation de la source de la balise img avec le fichier icone.
84        $source = $icone['source'];
85
86        // On retaille si nécessaire l'image pour qu'elle soit toujours de la même taille (grande ou petite).
87        list($largeur, $hauteur) = @getimagesize($source);
88        include_spip('filtres/images_transforme');
89        $taille_defaut = ($taille == 'petit') ? _RAINETTE_ICONES_PETITE_TAILLE : _RAINETTE_ICONES_GRANDE_TAILLE;
90        if (($largeur < $taille_defaut) or ($hauteur < $taille_defaut)) {
91                // Image plus petite que celle par défaut :
92                // --> Il faut insérer et recadrer l'image dans une image plus grande à la taille par défaut
93                $source = extraire_attribut(image_recadre($source, $taille_defaut, $taille_defaut, 'center', 'transparent'), 'src');
94        } elseif (($largeur > $taille_defaut) or ($hauteur > $taille_defaut)) {
95                // Image plus grande que celle par défaut :
96                // --> Il faut réduire l'image à la taille par défaut
97                $source = extraire_attribut(image_reduire($source, $taille_defaut), 'src');
98        }
99
100        // On construit la balise img
101        $texte = $icone['code'];
102        $balise_img = "<img src=\"${source}\" alt=\"${texte}\" title=\"${texte}\" width=\"${taille_defaut}\" height=\"${taille_defaut}\" />";
103
104        return $balise_img;
105}
106
107/**
108 *
109 * @package    RAINETTE/AFFICHAGE
110 * @api
111 * @filtre
112 *
113 * @param string|int $resume
114 *
115 * @return string
116 */
117function rainette_afficher_resume($resume) {
118
119        if (is_numeric($resume)) {
120                // On utilise l'option de _T permettant de savoir si un item existe ou pas
121                $texte = _T('rainette:meteo_' . $resume, array(), array('force' => false));
122                if (!$texte) {
123                        $texte = _T('rainette:meteo_na') . " ($resume)";
124                }
125        } else {
126                $texte = $resume ? $resume : _T('rainette:meteo_na');
127        }
128
129        return ucfirst($texte);
130}
131
132/**
133 * Conversion d'une indication de direction en une chaine traduite pour
134 * l'affichage dans les modèles.
135 *
136 * @package    RAINETTE/AFFICHAGE
137 * @api
138 * @filtre
139 *
140 * @param mixed $direction
141 *        La direction soit sous forme d'une valeur numérique entre 0 et 360, soit sous forme
142 *        d'une chaine. Certains services utilisent la chaine "V" pour indiquer une direction
143 *        variable.
144 *
145 * @return string
146 *        La chaine traduite indiquant la direction du vent.
147 */
148function rainette_afficher_direction($direction) {
149
150        include_spip('inc/rainette_convertir');
151        $direction_abregee = angle2direction($direction);
152
153        if ($direction_abregee) {
154                $direction_texte = _T("rainette:direction_${direction_abregee}");
155        } else {
156                $direction_texte = _T('rainette:valeur_indeterminee');
157        }
158
159        return $direction_texte;
160}
161
162/**
163 * Affiche la tendance de pression selon la méthode demandée (texte en clair, symbole de flèche ou
164 * icone).
165 *
166 * @package    RAINETTE/AFFICHAGE
167 * @api
168 * @filtre
169 *
170 * @param string $tendance_en
171 *              Texte anglais représentant la tendance et récupérée par le service.
172 * @param string $methode
173 *              Methode d'affichage de la tendance qui prend les valeurs:
174 *              - `texte`   : pour afficher un texte en clair décrivant la tendance (méthode par défaut).
175 *              - `symbole` : pour afficher un symbole de flèche (1 caractère) décrivant la tendance.
176 *
177 * @return string
178 */
179function rainette_afficher_tendance($tendance_en, $methode = 'texte') {
180
181        $tendance = '';
182
183        // Certains textes sont composés de plusieurs mots comme "falling rapidly".
184        // On en fait un texte unique en remplaçant les espaces par des underscores.
185        $tendance_en = str_replace(' ', '_', trim($tendance_en));
186
187        if (($tendance_en) and ($texte = _T("rainette:tendance_texte_$tendance_en", array(), array('force' => false)))) {
188                if ($methode == 'texte') {
189                        $tendance = $texte;
190                } else {
191                        $tendance = _T("rainette:tendance_symbole_$tendance_en");
192                }
193        }
194
195        return $tendance;
196}
197
198/**
199 * Affiche toute donnée météorologique au format numérique avec son unité.
200 *
201 * @package    RAINETTE/AFFICHAGE
202 * @api
203 * @filtre
204 *
205 * @param int/float $valeur
206 *              La valeur à afficher
207 * @param string    $type_donnee
208 *      Type de données à afficher parmi 'temperature', 'pourcentage', 'angle', 'pression',
209 *      'distance', 'vitesse', 'population', 'precipitation'.
210 * @param int       $precision
211 *      Nombre de décimales à afficher pour les réels uniquement ou -1 pour utiliser le défaut.
212 * @param string        $service
213 *
214 * @return string
215 *      La chaine calculée ou le texte désignant une valeur indéterminée ou vide si la valeur est null.
216 */
217function rainette_afficher_unite($valeur, $type_donnee = '', $precision = -1, $service = 'weather') {
218
219        static $precision_defaut = array(
220                'temperature'   => 0,
221                'pression'      => 1,
222                'distance'      => 1,
223                'angle'         => 0,
224                'pourcentage'   => 0,
225                'population'    => 0,
226                'precipitation' => 1,
227                'vitesse'       => 0,
228                'indice'        => 0
229        );
230
231        if (!$service) {
232                $service = 'weather';
233        }
234        include_spip('inc/config');
235        $unite = lire_config("rainette/${service}/unite", 'm');
236
237        // On distingue la valeur null qui indique que la donnée météo n'est pas fournie par le service avec
238        // la valeur '' qui indique que la valeur n'est pas disponible temporairement
239        // Dans le cas null on n'affiche pas la valeur, dans le cas '' on affiche la non disponibilité
240        if ($valeur === null) {
241                $valeur_affichee = '';
242        } else {
243                $valeur_affichee = _T('rainette:valeur_indeterminee');
244                if ($valeur !== '') {
245                        // Détermination de l'arrondi si la donnée est stockée sous format réel
246                        if (array_key_exists($type_donnee, $precision_defaut)) {
247                                $precision = ($precision < 0) ? $precision_defaut[$type_donnee] : $precision;
248                                $valeur = round($valeur, $precision);
249                        }
250
251                        // Construction de la valeur affichée en fonction de son type. Un indice ne possède pas d'unité.
252                        $valeur_affichee = strval($valeur);
253                        if ($type_donnee != 'indice') {
254                                $suffixe = ($type_donnee == 'population')
255                                        ? ''
256                                        : (($unite == 'm') ? 'metrique' : 'standard');
257                                $espace = in_array($type_donnee, array('temperature', 'pourcentage', 'angle')) ? '' : '&nbsp;';
258                                $item = 'rainette:unite_' . $type_donnee . ($suffixe ? '_' . $suffixe : '');
259                                $valeur_affichee .= $espace . _T($item);
260                        }
261                }
262        }
263
264        return $valeur_affichee;
265}
266
267
268/**
269 * @param string $mode
270 *
271 * @return array|string
272 */
273function rainette_lister_services($mode = 'tableau') {
274
275        $services = array();
276
277        // On lit les fichiers php dans répertoire services/ du plugin sachant ce répertoire
278        // contient exclusivement les api de chaque service dans un fichier unique appelé
279        // alias_du_service.php
280        if ($fichiers_api = glob(_DIR_PLUGIN_RAINETTE . '/services/*.php')) {
281                foreach ($fichiers_api as $_fichier) {
282                        // On détermine l'alias du service
283                        $service = strtolower(basename($_fichier, '.php'));
284
285                        // Acquérir la configuration statique du service.
286                        include_spip("services/${service}");
287                        $configurer = "${service}_service2configuration";
288                        $configuration = $configurer('service');
289
290                        $services[$service] = $configuration['nom'];
291                }
292        }
293
294        // Par défaut la liste est fournie comme un tableau.
295        // Si le mode demandé est 'liste' on renvoie une chaîne énumérée des alias de service séparée par des virgules.
296        if ($mode == 'liste') {
297                $services = implode(',', array_keys($services));
298        }
299
300        return $services;
301}
302
303
304/**
305 * @param string $mode
306 * @param int    $periodicite
307 *
308 * @return array
309 */
310function rainette_lister_modeles($mode = 'conditions', $periodicite = 24) {
311
312        $modeles = array();
313
314        // On lit les modèles suivant le mode choisi dans l'ensemble du site.
315        // Ceux-ci sont toujours de la forme:
316        // -- conditions_<complement>,
317        // -- previsions_<periodicite>h_<complement>,
318        // -- infos_<complement>.
319        if (($mode == 'conditions') or ($mode == 'infos')) {
320                $pattern = "${mode}.*\\.html$";
321        } else {
322                $pattern = "${mode}_${periodicite}h.*\\.html$";
323        }
324        if ($fichiers = find_all_in_path("modeles/", $pattern)) {
325                foreach ($fichiers as $_fichier) {
326                        $modeles[] = strtolower(basename($_fichier, '.html'));
327                }
328        }
329
330        return $modeles;
331}
332
333
334/**
335 * @param string $service
336 * @param string $source
337 *
338 * @return array
339 */
340function rainette_lister_themes($service, $source = 'local') {
341
342        $themes = array();
343
344        // Certains services proposent des thèmes d'icones accessibles via l'API.
345        // C'est le cas de wunderground.
346        if (strtolower($source) == 'api') {
347                if ($service == 'wunderground') {
348                        $cles = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k');
349                        foreach ($cles as $_cle) {
350                                $themes[$_cle] = _T("rainette:label_theme_wunderground_${_cle}");
351                        }
352                }
353        } else {
354                // Les thèmes de Rainette sont toujours stockés dans l'arborescence themes/$service.
355                // Chaque thème a un alias qui correspond à son dossier et un titre pour l'affichage.
356                // On recherche les sous-dossiers themes/$service présents dans le path.
357                include_spip('inc/utils');
358                include_spip('inc/rainette_normaliser');
359                foreach (creer_chemin() as $_chemin) {
360                        $dossier_service = $_chemin . icone_local_normaliser('', $service);
361                        if (@is_dir($dossier_service)) {
362                                if ($dossiers_theme = glob($dossier_service . '/*', GLOB_ONLYDIR)) {
363                                        foreach ($dossiers_theme as $_theme) {
364                                                $theme = strtolower(basename($_theme));
365                                                // On ne garde que le premier dossier de même nom.
366                                                if (!isset($themes[$theme])) {
367                                                        $themes[$theme] = $theme;
368                                                }
369                                        }
370                                }
371                        }
372                }
373
374        }
375
376        return $themes;
377}
378
379
380/**
381 * @param string $lieu
382 * @param string $mode
383 * @param string $modele
384 * @param string $service
385 * @param array  $options
386 *
387 * @return array|string
388 */
389function rainette_coasser($lieu, $mode = 'conditions', $modele = 'conditions_tempsreel', $service = 'weather', $options = array()) {
390
391        // Initialisation du tableau des données météorologiques
392        $tableau = array();
393        include_spip('inc/rainette_normaliser');
394
395        // Détermination de la périodicité en fonction du mode et du modèle demandés
396        $periodicite = 0;
397        $erreur = '';
398        if ($mode == 'previsions') {
399                // Identification de la périodicité à partir du nom du modèle. Cela évite une configuration compliquée.
400                if (preg_match(',_(1|12|24)h,is', $modele, $match)) {
401                        $type_modele = intval($match[1]);
402
403                        // On verifie que la périodicité demandée explicitement dans l'appel du modèle est ok
404                        if (isset($options['periodicite'])) {
405                                $periodicite_explicite = intval($options['periodicite']);
406                                if (periodicite_est_compatible($type_modele, $periodicite_explicite)) {
407                                        $periodicite = $periodicite_explicite;
408                                } else {
409                                        $erreur = 'modele_periodicite';
410                                }
411                        } else {
412                                // Dans ce cas, il faut choisir une périodicité en fonction du type du modèle et du service.
413                                $periodicite = periodicite_determiner($type_modele, $service);
414                                if (!$periodicite) {
415                                        $erreur = 'modele_service';
416                                }
417                        }
418                } else {
419                        // On ne connait pas le type du modèle, donc sa compatibilité.
420                        // Si la périodicité est passée en argument on l'utilise sans se poser de question.
421                        // Sinon c'est une erreur car on ne sait pas quelle périodicité est requise
422                        if (isset($options['periodicite'])) {
423                                $periodicite = intval($options['periodicite']);
424                        } else {
425                                $erreur = 'modele_inutilisable';
426                        }
427                }
428        }
429
430        if ($erreur) {
431                // Acquérir la configuration statique du service (periode, format, données...)
432                include_spip("services/${service}");
433                $configurer = "${service}_service2configuration";
434                $configuration = $configurer($mode);
435
436                // On prépare un contexte extras pour traiter les erreurs du modèle de façon standard comme celles
437                // renvoyée par le chargement des données.
438                $extras['credits'] = $configuration['credits'];
439                $extras['config'] = array_merge(
440                        parametrage_normaliser($service, $configuration['defauts']),
441                        array('source' => configuration_donnees_normaliser($mode, $configuration['donnees'])),
442                        array('nom_service' => $configuration['nom'])
443                );
444                $extras['lieu'] = $lieu;
445                $extras['mode'] = $mode;
446                $extras['periodicite_cache'] = $periodicite;
447                $extras['service'] = $service;
448                $extras['erreur'] = array(
449                        'type' => $erreur,
450                        'service' => array(
451                                'code' => '',
452                                'message' => ''
453                        )
454                );
455        } else {
456                // Récupération du tableau des données météo
457                $charger = charger_fonction('meteo_charger', 'inc');
458                $nom_cache = $charger($lieu, $mode, $periodicite, $service);
459                lire_fichier($nom_cache, $contenu_cache);
460                $tableau = unserialize($contenu_cache);
461
462                // Séparation des données communes liées au service et au mode et des données météorologiques
463                $extras = $tableau['extras'];
464                $erreur = $extras['erreur']['type'];
465
466                if (!$erreur and ($mode == 'previsions')) {
467                        // Adaptation des données en fonction de la demande et de la périodicité modèle-cache
468                        $nb_index = count($tableau['donnees']);
469
470                        $jour1 = 0;
471                        if (isset($options['premier_jour'])) {
472                                $jour1 = intval($options['premier_jour']) < $nb_index
473                                        ? intval($options['premier_jour'])
474                                        : $nb_index -1;
475                        }
476
477                        $nb_jours = $nb_index - $jour1;
478                        if (isset($options['nombre_jours'])) {
479                                $nb_jours = ($jour1 + intval($options['nombre_jours']) <= $nb_index)
480                                        ? intval($options['nombre_jours'])
481                                        : $nb_index - $jour1;
482                        }
483
484                        $tableau['premier_jour'] = $jour1;
485                        $tableau['nombre_jours'] = $nb_jours;
486                }
487        }
488
489        // Affichage du message d'erreur ou des données
490        if ($erreur) {
491                $extras['erreur']['texte'] = erreur_formater_texte($extras['erreur'], $lieu, $mode, $modele, $service, $tableau['extras']['config']['nom_service']);
492                $texte = recuperer_fond('modeles/erreur', $extras);
493        } else {
494                // Appel du modèle avec le contexte complet
495                $texte = recuperer_fond("modeles/$modele", $tableau);
496        }
497
498        return $texte;
499}
500
501include_spip('inc/rainette_debusquer');
Note: See TracBrowser for help on using the repository browser.