source: spip-zone/_plugins_/Association/Associaspip/association_options.php @ 65682

Last change on this file since 65682 was 65682, checked in by gildas.cotomale@…, 7 years ago

correction dan r

File size: 72.1 KB
Line 
1<?php
2/***************************************************************************\
3 *  Associaspip, extension de SPIP pour gestion d'associations
4 *
5 * @copyright Copyright (c) 2007 Bernard Blazin & Francois de Montlivault
6 * @copyright Copyright (c) 2010 Emmanuel Saint-James
7 *
8 *  @license http://opensource.org/licenses/gpl-license.php GNU Public License
9\***************************************************************************/
10
11
12if (!defined('_ECRIRE_INC_VERSION'))
13        return;
14
15
16/*****************************************
17 * Initialisations
18**/
19
20/**
21 * @global array $GLOBALS['association_liste_des_statuts']
22 * @name $association_liste_des_statuts
23 */
24$GLOBALS['association_liste_des_statuts'] =
25  array('sorti','prospect','ok','echu','relance'); // Le premier element indique un ancien membre
26
27/**
28 * @global array $GLOBALS['association_styles_des_statuts']
29 * @name $association_styles_des_statuts
30 */
31$GLOBALS['association_styles_des_statuts'] = array(
32        'echu' => 'impair',
33        'ok' => 'valide',
34        'prospect' => 'prospect',
35        'relance' => 'pair',
36        'sorti' => 'sortie'
37);
38
39/**
40 * @var const _DIR_PLUGIN_ASSOCIATION_ICONES
41 *   Repertoire de base des images (icones/logos/etc) d'Associaspip
42 */
43define('_DIR_PLUGIN_ASSOCIATION_ICONES', _DIR_PLUGIN_ASSOCIATION.'img_pack/');
44
45/**
46 * @global array $GLOBALS['spip_pipeline']['modules_asso']
47 * @name $association_modules
48 */
49if ( !isset($GLOBALS['spip_pipeline']['modules_asso']) )
50        $GLOBALS['spip_pipeline']['modules_asso'] = ''; // definir ce pipeline, sans ecraser sa valeur s'il existe
51
52
53/*****************************************
54 * @defgroup association_bouton
55 * Affichage HTML : boutons d'action dans les listing
56 *
57** @{ */
58
59/**
60 * boutons d'action (si page de script indiquee) generique
61 *
62 * @param string $texte
63 *   libelle du bouton
64 * @param string $image
65 *   nom du fichier de l'icone du bouton
66 * @param string $script
67 *   nom du fichier de traitement appele par le bouton (dans un lien "?exec=...")
68 * @param string $exec_args
69 *   autres parametres (outre le nom du script) passes a l'URL
70 * @param string $img_attrs
71 *   autres attributs passes a la balise affichant l'image
72 * @return string $res
73 *   code HTML du bouton
74 *
75 * @todo voir s'il est possible d'utiliser plutot la fonction bouton_action($libelle, $url, $class="", $confirm="", $title="") definie dans /ecrire/inc/filtres.php
76 */
77function association_bouton_faire($texte, $image, $script='', $exec_args='', $img_attrs='')
78{
79        $res = ($script ? '<a href="'.generer_url_ecrire($script, $exec_args).'">' : '' );
80        $res .= '<img src="'._DIR_PLUGIN_ASSOCIATION_ICONES.$image.'" alt="';
81        $res .= ($texte ? _T('asso:'.$texte).'" title="'._T('asso:'.$texte) : ' ' );
82        $res .= '" '.$img_attrs.' />';
83        $res .= ($script?'</a>':'');
84        return $res;
85}
86
87/**
88 * @name association_bouton_<agir>
89 * cas specifique de :
90 *
91 * @param string $objet
92 *   nom de l'objet pour lequel on genere le bouton : c'est ce nom, prefixe
93 *   d'un <mot> selon une convention, qui correspond au fichier d'execution
94 *   appele par le lien du bouton
95 * @param int|string $args
96 *   identifiant de l'objet (le nom du parametre est alors "id")
97 *   ou chaine des parametres passes a l'URL
98 * @param string $tag
99 *   balise-HTML encadrante (doit fonctionner par paire ouvrante et fermante) ;
100 *   "TD" par defaut car dans Associaspip un tel bouton est genere dans une cellule de tableau
101 * @return string $res
102 *   code HTML du bouton
103 */
104//@{
105
106/**
107 * bouton de vue non modifiable ou apercu
108 * <mot> = voir_
109 */
110function association_bouton_afficher($objet, $args='', $tag='td')
111{
112        $res = ($tag?"<$tag class='action'>":'');
113        $res .= association_bouton_faire('bouton_voir', 'voir-12.png', "$objet", is_numeric($args)?"id=$args":$args, 'width="12" height="12" alt="&#x2380;"');
114        $res .= ($tag?"</$tag>":'');
115        return $res;
116}
117
118/**
119 * bouton d'edition (modification)
120 * <mot> = edit_
121 */
122function association_bouton_modifier($objet, $args='', $tag='td')
123{
124        $res = ($tag?"<$tag class='action'>":'');
125        $res .= association_bouton_faire('bouton_modifier', 'edit-12.gif', "edit_$objet", is_numeric($args)?"id=$args":$args, 'width="12" height="12" alt="&#x2380;"');
126        $res .= ($tag?"</$tag>":'');
127        return $res;
128}
129
130/**
131 * bouton d'effacement (suppression)
132 * <mot> = suppr_
133 */
134function association_bouton_supprimer($objet, $args='', $tag='td')
135{
136        $res = ($tag?"<$tag class='action'>":'');
137        $res .= association_bouton_faire('bouton_supprimer', 'suppr-12.gif', "suppr_$objet", is_numeric($args)?"id=$args":$args, 'width="12" height="12" alt="&#x2327;"'); // 8 pluriel contre 3 singulier
138        $res .= ($tag?"</$tag>":'');
139        return $res;
140}
141
142//@}
143
144/** @} */
145
146
147/*****************************************
148 * @defgroup association_calculer
149 * Affichage HTML dans les listing d'une chaine calculee selon la configuration
150 *
151** @{ */
152
153/**
154 * Affichage d'un nom complet (de membre) suivant la configuration du plugin (i.e. champs geres ou non)
155 *
156 * @param string $civilite
157 *   Civilite (M./Mme/Mle) ou titre (Dr./Pr./Mgr/Gle/etc.)
158 * @param string $prenom
159 *   Prenom(s)
160 * @param string $nom
161 *   Nom de famille
162 * @param string $html_tag
163 *   Indique la balise-HTML (paire ouvrante/fermante) servant a grouper le
164 *   resultat. Sa presence (rien par defaut) indique d'appliquer le micro-
165 *   formatage du groupe.
166 * @return string $res
167 *   Chaine du nom complet du membre, micro-formate ou non.
168 */
169function association_calculer_nom_membre($civilite, $prenom, $nom, $html_tag='')
170{
171        $res = '';
172        if ($html_tag) {
173                $res = '<'.$html_tag.' class="'. (($civilite || $prenom)?'n':'fn') .'">';
174        }
175        if ($GLOBALS['association_metas']['civilite'] && $civilite) {
176                $res .= ($html_tag?'<span class="honorific-prefix">':'') .$civilite. ($html_tag?'</span>':'') .' ';
177        }
178        if ($GLOBALS['association_metas']['prenom'] && $prenom) {
179                $res .= ($html_tag?'<span class="given-name">':'') .$prenom. ($html_tag?'</span>':'') .' ';
180        }
181        if ($nom) {
182                $res .= ($html_tag?'<span class="family-name">':'') .$nom. ($html_tag?'</span>':'') .' ';
183        }
184        if ($html_tag) {
185                $res .= '</'.$html_tag.'>';
186        }
187        return $res;
188}
189
190/**
191 * Affichage du nom avec le lien vers la page correspondante
192 *
193 * En fait c'est pour les modules dons/ventes/activites/prets ou l'acteur (donateur/acheteur/inscrit/emprunteur)
194 * peut etre un membre/auteur (son id_acteur est alors renseigne) mais pas
195 * forcement son nom (qui peut etre different)
196 * ou peut etre une personne exterieure a l'association (on a juste le nom alors
197 * obligatoire)
198 *
199 * @param string $nom
200 *   Nom complet affiche
201 * @param int $id
202 *   ID de l'objet lie
203 * @param string $type
204 *   Raccourci utilise pour faire le lien
205 *   Par defaut : "membre"
206 * @param string $html_tag
207 *   Balise-HTML (paire ouvrante/fermante) encadrante
208 * @return string $res
209 *   Lien interne SPIP
210 */
211function association_calculer_lien_nomid($nom, $id, $type='membre', $html_tag='')
212{
213        $res = '';
214        if ($html_tag) {
215                $res = '<'.$html_tag.' class="fn">';
216        }
217        if ($id) {
218                $res .= '[';
219        }
220        $res .= $nom;
221        if ($id) {
222                $res .= "->$type$id]";
223        }
224        if ($html_tag) {
225                $res .= '</'.$html_tag.'>';
226        }
227        return propre($res);
228}
229
230/** @} */
231
232
233/*****************************************
234 * @defgroup association_formater
235 * Affichage HTML d'une chaine localisee et micro-formatee.
236 * La chaine initiale est (essentiellement) issue de la base de donnees apres
237 * passage par un @ref association_recuperer si necessaire.
238 *
239 * @note association_formater_<quoi> s'appelait association_<quoi>fr ;
240 * "fr" initialement pour FRanciser puis est devenu synonyme de FoRmat
241 *
242** @{ */
243
244/**
245 *  Affichage de date localisee et micro-formatee
246 *
247 * @param string $iso_date
248 *   Date au format ISO-8601
249 *   http://fr.wikipedia.org/wiki/ISO_8601#Date_et_heure
250 * @param string $css_class
251 *   Classe(s) CSS (separees par un espace) a rajouter
252 *   Normalement : dtstart|dtend
253 * @param string $html_tag
254 *   Balise-HTML (paire ouvrante/fermante) encadrante
255 *   Par defaut : "abbr"
256 *   http://www.alsacreations.com/tuto/lire/1222-microformats-design-patterns.html#datetime-design-pattern
257 *   Desactiver (chaine vide) pour ne pas micro-formater
258 * @return string $res
259 *   Date formatee
260 */
261function association_formater_date($iso_date, $css_class='', $htm_tag='abbr')
262{
263        $res = '';
264        if ($html_tag)
265                $res = "<$html_tag ". ($css_class?"class='$css_class' ":'') ."title='$iso_date'>";
266        $res .= affdate_base($iso_date, 'entier'); // on fait appel a la fonction centrale des filtres SPIP... comme ca c'est traduit et formate dans les langues supportees ! si on prefere les mois en chiffres et non en lettre, y a qu'a changer les chaines de langue date_mois_XX
267        if ($html_tag)
268                $res .= ($html_tag?"</$htm_tag>":'');
269        return $res;
270}
271
272/**
273 * Affichage de nombre localise
274 *
275 * @param float $nombre
276 *   Valeur numerique au format informatique standard
277 * @param int $decimales
278 *   Nombre de decimales affichees.
279 *   Par defaut : 2
280 * @param string $l10n
281 *   Code ISO-639 de la langue voulue
282 *   Par defaut : on tente de detecter la langue du navigateur sinon celle du site
283 * @return string $res
284 *   Nombre formatee
285 *
286 * @note Perfectible... Avis aux contributeurs motives...
287 */
288function association_formater_nombre($nombre, $decimales=2, $l10n='')
289{
290        // recuperer le code des parametres regionnaux a utiliser
291        // dans un premier temps, on essaye d'utiliser la langue puisque SPIP gere
292        // bien cela et offre la possibilite d'en faire plus avec
293        //  http://programmer.spip.org/Forcer-la-langue-selon-le-visiteur
294        // Comme ce n'est pas suffisant (le code de localisation est de la forme
295        // langue-pays ou langue_PAYS en utilisant les codes ISO), et recuperer le
296        // pays n'est pas simple sans faire appel a l'IP-geolocalisation
297        // http://stackoverflow.com/questions/2156231/how-do-you-detect-a-website-visitors-country-specifically-us-or-not
298        // Ni SPIP ni PHP n'offrant de moyen "simple" d'arriver a nos fin bah...
299        if (!$l10n) { // pas de localae specifiee
300                $l10n = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
301                if (!$l10n) { // pas specifie par le navigateur non plus ?
302                        $l10n = array('french', 'fr_FR', 'fr_FR@euro', 'fr_FR.iso88591', 'fr_FR.iso885915@euro', 'fr_FR.utf8', 'fr_FR.utf8@euro'); // alors on s'impose...
303                } else { // si specifie, on va transformer en tableau http://www.thefutureoftheweb.com/blog/use-accept-language-header
304                        preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $l10n, $lang_parse);
305                        if (count($lang_parse[1])) { // creer la liste locale=>preference
306                                $langues = array_combine($lang_parse[1], $lang_parse[4]);
307                                foreach ($langues as $langue => $taux) { // pour les taux de preferences non specifies, mettre a 100%
308                                        if ($taux==='')
309                                                $langues[$langue] = 1;
310                                }
311                                arsort($langues, SORT_NUMERIC); // ordonne par taux de preferences
312                                $l10n = array_keys($langues); // on recupere la liste des langues triees
313                        }
314
315                }
316        }
317        // formater selon la langue choisie/recuperee
318        // http://stackoverflow.com/a/437642
319        setlocale(LC_NUMERIC, $l10n);
320        $locale = localeconv();
321    return number_format(floatval($nombre), $decimales, $locale['decimal_point'], $locale['thousands_sep']);
322}
323
324/**
325 * Affichage de duree localisee et micro-formatee
326 *
327 * @param int|string $nombre
328 *   Valeur numerique de la duree.
329 * @param string $unite
330 *   Lettre indiquant le type de duree affiche : Y|M|W|D|H
331 *   respectivement pour annee|mois|semaine|jour|heures
332 *   Noter qu'il est possible d'utiliser les equivalents francais : A|S|J
333 *   Noter aussi qu'on peut avoir en prime T (horaire seule) ou I (date),
334 *   et dans ce cas ce n'est un nombre entier qui est utilise mais une chaine du temps au format ISO
335 * @param string $html_tag
336 *   Balise-HTML (paire ouvrante/fermante) encadrante
337 *   Par defaut : "abbr" avec la classe "duration"
338 *   http://www.alsacreations.com/tuto/lire/1222-microformats-design-patterns.html#abbr-design-pattern
339 *   Desactiver (chaine vide) pour ne pas micro-formater
340 * @return string $res
341 *   Duree formatee
342 *
343 * @note les cas de minutes/secondes doivent etre specifie comme des heures au format ISO...
344 */
345function association_formater_duree($nombre, $unite='', $htm_tag='abbr')
346{
347        $frmt_h = ''; // format human-readable
348        $frmt_m = 'P'; // format machine-parsable
349        switch(strtoupper($unite)) { // http://ufxtract.com/testsuite/documentation/iso-duration.htm
350                case 'Y' : // year
351                case 'A' : // annee
352                        $nombre = intval($nombre);
353                        $frmt_m .= $nombre.'Y';
354                        $valeur = association_formater_nombre($nombre,0);
355                        $unite = ($nombre<=1) ? _T('local:an') : _T('local:ans');
356                        break;
357                case 'M' : // month/mois
358                        $nombre = intval($nombre);
359                        $frmt_m .= $nombre.'M';
360                        $valeur = association_formater_nombre($nombre,0);
361                        $unite = ($nombre<=1) ? _T('spip:date_un_mois') : _T('spip:date_mois');
362                        break;
363                case 'W' : // week
364                case 'S' : // semaine
365                        $nombre = intval($nombre);
366                        $frmt_m .= $nombre.'W';
367                        $valeur = association_formater_nombre($nombre,0);
368                        $unite = ($nombre<=1) ? _T('spip:date_une_semaine') : _T('spip:date_semaines');
369                        break;
370                case 'D' : // day
371                case 'J' : // jour
372                        $nombre = intval($nombre);
373                        $frmt_m .= $nombre.'D';
374                        $valeur = association_formater_nombre($nombre,0);
375                        $unite = ($nombre<=1) ? _T('local:jour') : _T('spip:date_jours');
376                        break;
377                case 'H' : // hour/heure
378                        $frmt_m .= 'T'.str_replace('00M', '',  str_replace(':','H',$nombre.':00').'M' );
379                        $valeur = association_formater_nombre($nombre,0);
380                        if (intval($nombre)>1)
381                                $unite = _T('spip:date_heures');
382                        elseif (is_numeric($nombre))
383                                $unite = _T('spip:date_une_heure');
384                        elseif (strstr($nombre,'0:00'))
385                                $unite = _T('spip:date_une_minute');
386                        else {
387                                $nombre = explode(':',$nombre);
388                                $frmt_h = _T('spip:date_fmt_heures_minutes', array('h'=>$nombre[0],'m'=>$nombre[1]));
389                        }
390                        break;
391                case 'T' : // (full) ISO Time : no check...
392                        $frmt_m .= 'T'.str_replace( array('HM','HS','MS','00H','00M'), array('H','H','M'), preg_replace('m:m','M',preg_replace('h:h','H',$nombre,1),1).'S' );
393                        $nombre = explode(':',$nombre,2);
394                        if ($nombre[0]>24) { // http://dev.mysql.com/doc/refman/4.1/en/time.html
395                                $nombre['-1'] = intval($nombre[0]/24);
396                                $nombre[0] = $nombre[0]%24;
397                        }
398                        switch($nombre['-1']) { // nombre de jours
399                                case 0:
400                                case '':
401                                        $frmt_h = '';
402                                        break;
403                                case 1:
404                                        $frmt_h = _T('duree_temps', array('nombre'=>1,'unite'=>_T('local:jour')));
405                                        break;
406                                default:
407                                        $frmt_h =  _T('duree_temps', array('nombre'=>association_formater_nombre($nommbre['-1'],0),'unite'=>_T('spip:date_jours')));
408                                        break;
409                        }
410                        if ($nombre[0])
411                                $frmt_h .= ', ';
412                        switch($nombre[0]) { // nombre d'heures
413                                case 0:
414                                        $frmt_h .= '';
415                                        break;
416                                case 1:
417                                        $frmt_h .= _T('duree_temps', array('nombre'=>1,'unite'=>_T('spip:date_une_heure')));
418                                        break;
419                                default:
420                                        $frmt_h .= _T('duree_temps', array('nombre'=>association_formater_nombre($nombre[0],0),'unite'=>_T('spip:date_heures')));
421                                        break;
422                        }
423                        if ($nombre[1])
424                                $frmt_h .= ', ';
425                        switch($nombre[1]) { // nombre de minutes
426                                case 0:
427                                        $frmt_h .= '';
428                                        break;
429                                case 1:
430                                        $frmt_h .= _T('duree_temps', array('nombre'=>1,'unite'=>_T('spip:date_une_minute')));
431                                        break;
432                                default:
433                                        $frmt_h .= _T('duree_temps', array('nombre'=>association_formater_nombre($nombre[1],0),'unite'=>_T('spip:date_minutes')));
434                                        break;
435                        }
436                        if ($nombre[2])
437                                $frmt_h .= ', ';
438                        switch($nombre[2]) { // nombre de secondes
439                                case 0:
440                                        $frmt_h .= '';
441                                        break;
442                                case 1:
443                                        $frmt_h .= _T('duree_temps', array('nombre'=>1,'unite'=>_T('spip:date_une_seconde')));
444                                        break;
445                                default:
446                                        $frmt_h .= _T('duree_temps', array('nombre'=>association_formater_nombre($nombre[2],0),'unite'=>_T('spip:date_secondes')));
447                                        break;
448                        }
449                        $frmt_h .= '. ';
450                        break;
451                case 'I' : // (full) ISO DateTime or Date : no check !!!
452                default :
453                        $frmt_m .= $nombre;
454                        $nombre = explode('T',$nombre,2);
455                        $ladate = explode(':',$nombre[0]);
456                        switch($ladate[0]) { // nombre d'annee
457                                case 0:
458                                case '':
459                                        $frmt_h = '';
460                                        break;
461                                case 1:
462                                        $frmt_h = _T('duree_temps', array('nombre'=>1,'unite'=>_T('local:an')));
463                                        break;
464                                default:
465                                        $frmt_h =  _T('duree_temps', array('nombre'=>association_formater_nombre($ladate[0],0),'unite'=>_T('local:ans')));
466                                        break;
467                        }
468                        if ($ladate[1])
469                                $frmt_h .= ', ';
470                        switch($ladate[1]) { // nombre de mois
471                                case 0:
472                                        $frmt_h .= '';
473                                        break;
474                                case 1:
475                                        $frmt_h .= _T('duree_temps', array('nombre'=>1,'unite'=>_T('spip:date_un_mois')));
476                                        break;
477                                default:
478                                        $frmt_h .= _T('duree_temps', array('nombre'=>association_formater_nombre($ladate[1],0),'unite'=>_T('spip:date_mois')));
479                                        break;
480                        }
481                        if ($ladate[2])
482                                $frmt_h .= ', ';
483                        switch($ladate[2]) { // nombre de jours
484                                case 0:
485                                        $frmt_h .= '';
486                                        break;
487                                case 1:
488                                        $frmt_h .= _T('duree_temps', array('nombre'=>1,'unite'=>_T('local:jour')));
489                                        break;
490                                default:
491                                        $frmt_h .= _T('duree_temps', array('nombre'=>association_formater_nombre($ladate[2],0),'unite'=>_T('spip:date_jours')));
492                                        break;
493                        }
494                        if (count($lheure))
495                                $frmt_h .= ', ';
496                        $lheure = explode(':',$nombre[1]);
497                        switch($lheure[0]) { // nombre d'heures
498                                case 0:
499                                        $frmt_h .= '';
500                                        break;
501                                case 1:
502                                        $frmt_h .= _T('duree_temps', array('nombre'=>1,'unite'=>_T('spip:date_une_heure')));
503                                        break;
504                                default:
505                                        $frmt_h .=  _T('duree_temps', array('nombre'=>association_formater_nombre($lheure[0],0),'unite'=>_T('spip:date_heures')));
506                                        break;
507                        }
508                        if ($lheure[1])
509                                $frmt_h .= ', ';
510                        switch($lheure[1]) { // nombre d'heures
511                                case 0:
512                                        $frmt_h .= '';
513                                        break;
514                                case 1:
515                                        $frmt_h .= _T('duree_temps', array('nombre'=>1,'unite'=>_T('spip:date_une_minute')));
516                                        break;
517                                default:
518                                        $frmt_h .=  _T('duree_temps', array('nombre'=>association_formater_nombre($lheure[1],0),'unite'=>_T('spip:date_minutes')));
519                                        break;
520                        }
521                        if ($lheure[2])
522                                $frmt_h .= ', ';
523                        switch($lheure[2]) { // nombre d'heures
524                                case 0:
525                                        $frmt_h = '';
526                                        break;
527                                case 1:
528                                        $frmt_h = _T('duree_temps', array('nombre'=>1,'unite'=>_T('spip:date_une_seconde')));
529                                        break;
530                                default:
531                                        $frmt_h =  _T('duree_temps', array('nombre'=>association_formater_nombre($lheure[2],0),'unite'=>_T('spip:date_secondes')));
532                                        break;
533                        }
534                        $frmt_h .= '. ';
535                        break;
536        }
537        if (!$frmt_h)
538                $frmt_h = _T('asso:duree_temps', array('nombre'=>$valeur, 'unite'=>$unite) );
539        return $html_tag ? "<$htm_tag class='duration' title='". htmlspecialchars($frmt_m, ENT_QUOTES, $GLOBALS['meta']['charset']). "'>$frmt_h</$htm_tag>" : $frmt_h;
540}
541
542/**
543 * Affichage de prix (montant et devise) localisee et micro-formatee
544 *
545 * @param float|int $montant
546 *   Montant (valeur chiffree) correspondant au prix
547 * @param string $devise_code
548 *   Trigramme representant le code ISO-4217 de la devise
549 *   http://fr.wikipedia.org/wiki/ISO_4217
550 *   Par defaut : la code defini dans le fichier de langues, sinon EUR
551 * @param string $devise_symb
552 *   Symbole ou nom generique abrege de la devise
553 *   Par defaut : le symbole defini dans le fichier de langues si defini, sinon le code.
554 * @param string $html_span
555 *   Balise-HTML (paire ouvrante/fermante) encadrant l'ensemble
556 *   Par defaut : "span" avec les classes "money price"
557 *   http://www.alsacreations.com/tuto/lire/1222-microformats-design-patterns.html#value-class-pattern
558 *   Desactiver (chaine vide) pour ne pas micro-formater
559 * @param string $html_abbr
560 *   Balise-HTML (paire ouvrante/fermante) encadrant chaque sous-partie
561 *   Par defaut : "abbr" avec la classe "duration"
562 * @return string $res
563 *   Duree formatee
564 *
565 * @note On n'utilise pas la fontcion PHP money_format() --qui ne fonctionne pas
566 * sous Windows-- car on veut micro-formater avec une devise fixee par la
567 * configuration (en fait les chaines de langue) du plugin
568 */
569function association_formater_prix($montant, $devise_code='', $devise_symb='', $htm_span='span', $htm_abbr='abbr')
570{
571        $res = '';
572        if ($html_span)
573                $res .= "<$htm_span class='money price'>"; // pour la reference est "price" <http://microformats.org/wiki/hproduct> (reconnu par les moteurs de recherche), mais "money" <http://microformats.org/wiki/currency-brainstorming> est d'usage courant aussi
574        $montant = ($html_abbr?"<$htm_abbr class='amount' title='$montant'>":'') . association_formater_nombre($montant) . ($html_abbr?"</$htm_abbr>":'');
575        if ( !$devise_code ) {
576                $devise_code = _T('asso:devise_code_iso');
577                if ( !$devise_code )
578                        $devise_code = 'EUR';
579                $devise_symb = _T('asso:devise_symbole');
580        }
581        if ( !$devise_symb ) {
582                if ( function_exists('formater_devise') ) // plugin "Devise" est actif
583                        $devis_symp = formater_devise($devise_code, '%N');
584                else
585                        $devise_symb = $devise_code;
586        }
587        $devise = ($html_abbr ? "<$htm_abbr class='currency' title='". htmlspecialchars($devise_code, ENT_QUOTES, $GLOBALS['meta']['charset']) .'\'>' : '') . $devise_symb . ($html_abbr?"</$htm_abbr>" :'');
588        $res .= _T('asso:devise_montant', array('montant'=>$montant, 'devise'=>$devise) );
589        return $html_span ? "$res</$htm_span>" : $res;
590}
591
592/**
593 * Affichage d'un texte formate
594 *
595 * @param string $texte
596 *   Le texte brut initial
597 * @param string $filtre
598 *   Filtre SPIP a appliquer au texte
599 * @param array $params
600 *   Liste des parametres du filtre
601 * @return string $res
602 *   Texte formate
603 * @note
604 *   http://spipistrelle.clinamen.org/spip.php?article16
605 */
606function association_formater_texte($texte, $filtre='', $params=array() )
607{
608        if ( !is_array($params) )
609                $params = array($params);
610        $ok = array_unshift($params, $texte);
611        return $filtre?call_user_func_array($filtre, $params):$texte;
612}
613
614/**
615 * Affiche une puce de couleur
616 *
617 * @param string $statut
618 *   Valeur du "statut" a iconifier
619 * @param string $icone
620 *   Nom (couleur) de la puce parmis celles disponibles : orange, rouge, vert, poubelle
621 * @param bool $acote
622 *   Indique si la legende est placee a cote de l'icone (vrai, par defaut) ou dedans (faux)
623 * @return string
624 *   Dessin et texte
625 */
626function association_formater_puce($statut, $icone,  $acote=TRUE)
627{
628        return $acote ? association_bouton_faire('', 'puce-'.$icone.'.gif', '', '', '').' '._T("asso:$statut") : association_bouton_faire($statut, 'puce-'.$icone.'.gif', '', '', '') ; // c'est comme un bouton... mais n'a pas d'action
629}
630
631/** @} */
632
633
634/*****************************************
635 * @defgroup association_recuperer
636 * Transforme un champ de formulaire en vue de son insertion en base de donnees.
637 * S'utilise donc sur un champ passe par le @ref association_verifier correspondant.
638 * Assure donc un bon enregistrement et la restitution par le @ref association_formater correspondant.
639 *
640 * @param string $valeur
641 *   Nom a recuperer (par GET ou POST ou Cookie) ...ou la valeur directement
642 * @param bool $req
643 *   Indique s'il s'agit du nom (vrai --par defaut) ou pas (faux, donc la valeur)
644 *
645** @{ */
646
647/**
648 * @return string $valeur
649 *   Date au format ISO
650 */
651function association_recuperer_date($valeur, $req=false)
652{
653        if ($valeur!='') {
654                $valeur = preg_replace('/\D/', '-', ($req?_request($valeur):$valeur), 2); // la limitation a 2 separateurs permet de ne transformer que la partie "date" s'il s'agit d'un "datetime" par exemple.
655        }
656        return $valeur;
657}
658
659/**
660 * @return float $valeur
661 *   Nombre decimal
662 */
663function association_recuperer_montant($valeur, $req=false)
664{
665        if ($valeur!='') {
666                $valeur = str_replace(' ', '', ($req?_request($valeur):$valeur) ); // suppprime les espaces separateurs de milliers
667                $valeur = str_replace(',', '.', $valeur); // convertit les , en .
668                $valeur = floatval($valeur);
669        } else
670                $valeur = 0.0;
671        return $valeur;
672}
673
674/** @} */
675
676
677/*****************************************
678 * @defgroup association_verifier
679 * Verification du format de la valeur d'un champ de formulaire.
680 * Permet d'appeler @ref association_recupere equivalent sur ce champ...
681 *
682 * @param string $valeur
683 *   Nom a recuperer (par GET ou POST ou Cookie) ...ou la valeur directement
684 * @param bool $rex
685 *   Indique si la verification est plus lache (vrai) ou pas (faux --par defaut)
686 *   [le nom de la variable signifie "RElaXed check"]
687 * @param bool $req
688 *   Indique s'il s'agit du nom (vrai --par defaut) ou pas (faux, donc la valeur)
689 *   [le nom de la variable signifie "by REQuest"]
690 * @return string
691 *   Message d'erreur... (donc chaine vide si OK)
692 *
693** @{ */
694
695/**
696 * S'assurer que la valeur saisie est une chaine de date valide
697 */
698function association_verifier_date($valeur, $rex=FALSE, $req=TRUE)
699{
700        $date = $req ? _request($valeur) : $valeur;
701        if ( $rex && ($date=='0000-00-00' || !$date) )
702                return '';
703        if (!preg_match('/^\d{4}\D\d{2}\D\d{2}$/', $date)) // annee sur 4 chiffres ; mois sur 2 chiffres ; jour sur 2 chiffres ; separateur est caractere non numerique quelconque...
704#       if (!preg_match('/^\d{4}\D(\d|1[0-2])\D([1-9]|0[1-9]|[12]\d|3[01])$/', $date)) // annee sur 4 chiffres ; mois sur 1 ou 2 chiffres entre 1 et 12 ; jour sur 1 ou 2 chiffres eentre 1 et 31 ; separateur est n'importe quel caractere ne representant pas un chiffre arabe de la notation decimale standard...
705                return _T('asso:erreur_format_date', array('date'=>$date) ); // ...c'est un petit plus non documente (la documentation et le message d'erreur stipulent AAAA-MM-JJ : mois et jours toujours sur deux chiffres avec donc zero avant si inferieur a 10, et separateur est tiret)
706        list($annee, $mois, $jour) = preg_split('/\D/', $date);
707        if (!checkdate($mois, $jour, $annee)) // la date doit etre valide : pas de 30 fevrier ou de 31 novembre par exemple.
708                return _T('asso:erreur_valeur_date', array('date'=>$date) );
709        return '';
710}
711
712/**
713 * S'assurer que la valeur saisie est un flottant positif
714 */
715function association_verifier_montant($valeur, $req=TRUE)
716{
717        if (association_recuperer_montant($valeur,$req)<0)
718                return _T('asso:erreur_montant');
719        else
720                return '';
721}
722
723/**
724 * S'assurer que l'entier saisie correspond bien a un id_auteur
725 * de la table spip_asso_membres (par defaut) ou spip_auteurs (si on elargi a tous
726 * --ceci permet d'editer des membres effaces tant qu'ils sont references par SPIP)
727 */
728function association_verifier_membre($valeur, $rex=FALSE, $req=TRUE)
729{
730        $id_auteur = intval($req?_request($valeur):$valeur);
731        if ($id_auteur) {
732                if ( sql_countsel('spip_'.($rex?'auteurs':'asso_membres'), "id_auteur=$id_auteur")==0 ) {
733                        return _T('asso:erreur_id_adherent');
734                }
735        } else
736                return '';
737}
738
739/** @} */
740
741
742/*****************************************
743 * @defgroup association_selectionner
744 * Selecteur HTML (liste deroulante) servant a filtrer le listing affiche en milieu de page
745 *
746 * @param int $sel
747 *   ID selectionne : conserve la valeur selectionnee
748 * @param string $exec
749 *   Nom du fichier de l'espace prive auquel le formulaire sera soumis.
750 *   Si present, le formulaire complet (balise-HTML "FORM") est genere.
751 *   Si absent (par defaut), seul le selecteur (et le code supplementaire fourni
752 *   par $plus) est(sont) renvoye(s).
753 * @param string $plus
754 *   Source HTML rajoute a la suite.
755 *   (utile si on genere tout le formulaire avec des champs caches)
756 * @return string $res
757 *   Code HTML du selecteur (ou du formulaire complet si $exec est indique)
758 *
759** @{ */
760
761/**
762 * Selecteur d'exercice comptable
763 */
764function association_selectionner_exercice($sel='', $exec='', $plus='')
765{
766    $res = '<select name ="exercice" onchange="form.submit()">';
767#    $res .= '<option value="0" ';
768#    if (!$exercice) {
769#               $res .= ' selected="selected"';
770#    }
771#    $res .= '>'. _L("choisir l'exercice ?") .'</option>';
772    $sql = sql_select('id_exercice, intitule', 'spip_asso_exercices','', 'intitule DESC');
773    while ($val = sql_fetch($sql)) {
774                $res .= '<option value="'.$val['id_exercice'].'" ';
775                if ( $sel==$val['id_exercice'] ) {
776                        $res .= ' selected="selected"';
777                }
778                $res .= '>'.$val['intitule'].'</option>';
779    }
780    $res .= '</select>'.$plus;
781    return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
782}
783
784/**
785 * Selecteur de destination comptable
786 */
787function association_selectionner_destination($sel='', $exec='', $plus='')
788{
789    $res = '<select name ="destination" onchange="form.submit()">';
790    $res .= '<option value="0" ';
791    if ( !$sel) {
792                $res .= ' selected="selected"';
793    }
794    $res .= '>'. _T('asso:toutes_destinations') .'</option>';
795    $intitule_destinations = array();
796    $sql = sql_select('id_destination, intitule', 'spip_asso_destination','', 'intitule DESC');
797    while ($val = sql_fetch($sql)) {
798                $res .= '<option value="'.$val['id_destination'].'" ';
799                if ( $sel==$val['id_destination'] ) {
800                        $res .= ' selected="selected"';
801                }
802                $res .= '>'.$val['intitule'].'</option>';
803    }
804    $res .= '</select>'.$plus;
805    if ($GLOBALS['association_metas']['destinations']){
806                return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
807        } else {
808                return '';
809        }
810}
811
812/**
813 * Selecteur de grouoe de membres
814 */
815function association_selectionner_groupe($sel='', $exec='', $plus='')
816{
817    $qGroupes = sql_select('nom, id_groupe', 'spip_asso_groupes', 'id_groupe>=100', '', 'nom');  // on ne prend en consideration que les groupe d'id >= 100, les autres sont reserves a la gestion des autorisations
818    if ( $qGroupes && sql_count($qGroupes) ) { // ne proposer que s'il y a des groupes definis
819                $res = '<select name="groupe" onchange="form.submit()">';
820                $res .= '<option value="">'._T('asso:tous_les_groupes').'</option>';
821                while ($groupe = sql_fetch($qGroupes)) {
822                        $res .= '<option value="'.$groupe['id_groupe'].'"';
823                        if ( $sel==$groupe['id_groupe'] )
824                                $res .= ' selected="selected"';
825                        $res .= '>'.$groupe['nom'].'</option>';
826                }
827                $res .= '</select>'.$plus;
828                return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
829        } else {
830                return '';
831        }
832}
833
834/**
835 * Selecteur de statut de membres
836 */
837function association_selectionner_statut($sel='', $exec='', $plus='')
838{
839    $res = '<select name="statut_interne" onchange="form.submit()">';
840    $res .= '<option value="%"'. (($sel=='defaut' || $sel=='%')?' selected="selected"':'') .'>'._T('asso:entete_tous').'</option>';
841    foreach ($GLOBALS['association_liste_des_statuts'] as $statut) {
842                $res .= '<option value="'.$statut.'"';
843                if ( $sel==$statut )
844                        $res .= ' selected="selected"';
845                $res .= '> '._T('asso:adherent_entete_statut_'.$statut).'</option>';
846        }
847        $res .= '</select>'.$plus;
848    return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
849}
850
851/**
852 * Zone de saisie de numero de membre
853 */
854function association_selectionner_id($sel='', $exec='', $plus='')
855{
856    $res = '<input type="text" name="id" onfocus=\'this.value=""\' size="5"  value="'. ($sel?$sel:_T('asso:entete_id')) .'" />'.$plus;
857    return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
858}
859
860/**
861 * Selecteur d'annee parmi celles disponibles dans une table donnee
862 *
863 * @param string $annee
864 *   Annee selectionnee. (annee courante par defaut)
865 * @param string $dtable
866 *   Nom (sans prefixe) de la table concernee
867 * @param string $dchamp
868 *   Nom (sans prefixe "date_") du champ contenant les annees recherchees
869 *
870 */
871function association_selectionner_annee($annee='', $dtable, $dchamp, $exec='', $plus='')
872{
873    if ($exec) {
874                $res = '<form method="post" action="'. generer_url_ecrire($exec) .'"><div>';
875                $res .= '<input type="hidden" name="exec" value="'.$exec.'" />';
876    } else {
877                $res = '';
878    }
879    $pager = '';
880    $res .= '<select name ="annee" onchange="form.submit()">';
881    $an_max = sql_getfetsel("MAX(DATE_FORMAT(date_$dchamp, '%Y')) AS an_max", "spip_$dtable", '');
882    $an_min = sql_getfetsel("MIN(DATE_FORMAT(date_$dchamp, '%Y')) AS an_min", "spip_$dtable", '');
883    if ( $annee>$an_max || $annee<$an_min ) { // a l'initialisation, l'annee courante est mise si rien n'est indique... or si l'annee n'est pas disponible dans la liste deroulante on est mal positionne et le changement de valeur n'est pas top
884                $res .= '<option value="'.$annee.'" selected="selected">'.$annee.'</option>';
885
886        }
887    $sql = sql_select("DATE_FORMAT(date_$dchamp, '%Y') AS annee", "spip_$dtable",'', 'annee DESC', 'annee');
888    while ($val = sql_fetch($sql)) {
889                $res .= '<option value="'.$val['annee'].'"';
890                if ($annee==$val['annee']) {
891                        $res .= ' selected="selected"';
892                        $pager .= "\n<strong>$val[annee]</strong>";
893                } else {
894                        $pager .= ' <a href="'. generer_url_ecrire($exec, '&annee='.$val['annee']) .'">'.$val['annee']."</a>\n";
895                }
896                $res .= '>'.$val['annee'].'</option>';
897    }
898    $res .= '</select>'.$plus;
899    if ($exec) {
900                $res .= '<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>';
901                $res .= '</div></form>';
902    }
903    return $res;
904}
905
906/**
907 * Selecteur de destinations comptables
908 */
909function association_selectionner_destinations($sel='', $exec='', $plus='')
910{
911    $res = '<select name ="destination[]" multiple="multiple" onchange="form.submit()">';
912    $res .= '<option value="0" ';
913    if ( !(array_search(0, $sel)===FALSE) ) {
914                $res .= ' selected="selected"';
915    }
916    $res .= '>'. _T('asso:toutes_destinations') .'</option><option disabled="disabled">--------</option>';
917    $intitule_destinations = array();
918    $sql = sql_select('id_destination, intitule', 'spip_asso_destination','', 'intitule DESC');
919    while ($val = sql_fetch($sql)) {
920                $res .= '<option value="'.$val['id_destination'].'" ';
921                if ( !(array_search($val['id_destination'], $sel)===FALSE) ) {
922                        $res .= ' selected="selected"';
923                }
924                $intitule_destinations[$val['id_destination']] = $val['intitule'];
925    }
926    $res .= '</select>'.$plus;
927    if ($GLOBALS['association_metas']['destinations']){
928                return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
929        } else {
930                return FALSE;
931        }
932}
933
934/** @} */
935
936
937/*****************************************
938 * @defgroup generer_url
939 * Raccourcis
940 *
941 * Les tables ayant deux prefixes ("spip_asso_"),
942 * le raccourci "x" implique de declarer le raccourci "asso_x"
943 *
944** @{ */
945
946function generer_url_asso_don($id, $param='', $ancre='') {
947        return  generer_url_ecrire('edit_don', 'id='.intval($id));
948}
949function generer_url_don($id, $param='', $ancre='') {
950        return  array('asso_don', $id);
951}
952
953function generer_url_asso_membre($id, $param='', $ancre='') {
954        return  generer_url_ecrire('adherent', 'id='.intval($id));
955}
956function generer_url_membre($id, $param='', $ancre='') {
957        return  array('asso_membre', $id);
958}
959
960function generer_url_asso_vente($id, $param='', $ancre='') {
961        return  generer_url_ecrire('edit_vente', 'id='.intval($id));
962}
963function generer_url_vente($id, $param='', $ancre='') {
964        return  array('asso_vente', $id);
965}
966
967function generer_url_asso_ressource($id, $param='', $ancre='') {
968        return  generer_url_ecrire('edit_ressource', 'id='.intval($id));
969}
970function generer_url_ressource($id, $param='', $ancre='') {
971        return  array('asso_ressource', $id);
972}
973
974function generer_url_asso_activite($id, $param='', $ancre='') {
975        return  generer_url_ecrire('voir_activite', 'id='.intval($id));
976}
977function generer_url_activite($id, $param='', $ancre='') {
978        return  array('asso_activite', $id);
979}
980
981/** @} */
982
983
984/*****************************************
985 * @defgroup instituer_
986 *
987 * @param array $auteur
988 * @return string
989 *
990** @{ */
991
992function instituer_adherent_ici($auteur=array()){
993        $instituer_adherent = charger_fonction('instituer_adherent', 'inc');
994        return $instituer_adherent($auteur);
995}
996
997function instituer_statut_interne_ici($auteur=array()){
998        $instituer_statut_interne = charger_fonction('instituer_statut_interne', 'inc');
999        return $instituer_statut_interne($auteur);
1000}
1001
1002/** @} */
1003
1004
1005/*****************************************
1006 * @defgroup association_totauxinfos
1007 * Informations de synthese, sur un objet, destinees a etre presente dans le bloc
1008 * d'infos contextuel debutant la colonne de gauche
1009 *
1010** @{ */
1011
1012/**
1013 * Rappels sur l'objet dans le bloc infos
1014 *
1015 * C'est un resume ou une petite presentation de l'objet en cours
1016 * d'edition/lecture : ces informations permettent de situer le contexte de la
1017 * page et n'apparaissent pas dans le bloc central !
1018 *
1019 * @param string $titre
1020 *   Titre affiche en gros dans le bloc.
1021 * @param string $type
1022 *   Nom du raccourci, affiche au dessus du titre.
1023 * @param int $id
1024 *   ID de l'objet, affiche au dessus du titre
1025 * @param array $DesLignes
1026 *   Tableau des lignes supplementaires a rajouter dans le bloc, sous la forme :
1027 *   chaine_de_langue_du_titre (sans prefixe) => texte contenu/explication associe.
1028 * @param string $PrefixeLangue
1029 *   Prefixe de langue associe aux chaines de langue des titres de lignes.
1030 *   Par defaut : asso
1031 * @param string $ObjetEtendu
1032 *   Nom de l'objet etendu dont on desire afficher les lignes des champs rajoutes par "Interface Champs Extras 2".
1033 *   Par defaut : rien
1034 * @return string $res
1035 *
1036 * @note
1037 *   Ce n'est pas redondant d'avoir a la fois $type et $ObjetEtendu qui peuvent
1038 *   avoir des valeurs differentes comme on peut le voir dans exec/adherent.php et exec/inscrits_activite.php !
1039 */
1040function association_totauxinfos_intro($titre, $type='', $id=0, $DesLignes=array(), $PrefixeLangue='asso', $ObjetEtendu='')
1041{
1042        $res = '';
1043        if ($type) {
1044                $res .= '<div style="text-align: center" class="verdana1 spip_x-small">'. _T('asso:titre_num', array('titre'=>_T("local:$type"), 'num'=>$id) ) .'</div>'; // presentation propre a Associaspip qui complete par un autre titre (voir ci-apres). Dans un SPIP traditionnel on aurait plutot : $res .= '<div style="font-weight: bold; text-align: center" class="verdana1 spip_xx-small">'. _T("$PrefixeLangue:$type") .'<br /><span class="spip_xx-large">'.$id.'</span></div>';
1045        }
1046        $res .= '<div style="text-align: center" class="verdana1 spip_medium">'.$titre.'</div>';
1047        if ( count($DesLignes) OR $ObjetEtendu )
1048                $res .= '<dl class="verdana1 spip_xx-small">';
1049        foreach ($DesLignes as $dt=>$dd) {
1050                $res .= '<dt>'. _T("$PrefixeLangue:$dt") .'</dt><dd>'. propre($dd) .'</dd>'; // propre() encadre dans P... Cette presentation est propre a Associaspip. Habituellement on a : $res .= "<div class='$dt'><strong>". _T("$PrefixeLangue:$dt") ."</strong> $dd</div>";
1051        }
1052        if ($ObjetEtendu) {
1053                $champsExtras = association_trouver_iextras($ObjetEtendu, $id); // on recupere les champs extras crees manuellement (i.e. via l'interface d'edition du prive, pas ceux rajoutes par les plugins !)
1054                if ( count($champsExtras) ) {
1055                        foreach ($champsExtras as $champExtra) {
1056                                $res .= '<dt>'. $champExtra[0] .'</dt>';
1057                                $res .= '<dd>'. $champExtra[1] .'</dd>';
1058/*
1059                                if ( strstr($champExtra[1], '<div')===0 ) { // c'est dans un "DIV" superflu
1060                                        $res .= substr_replace( substr_replace($chamExtra[1], '</dd>', strrpos($chamExtra[1],'</div>'), 6), 'dd', 1, 3);
1061                                } else {
1062                                        $res .= '<dd>'. $champExtra[0] .'</dd>';
1063                                }
1064*/
1065                                $res .= '<!--dd>'. $champExtra[2] .'</dd-->'; // comparaison de controle
1066                        }
1067                }
1068        }
1069        if ( count($DesLignes) OR $ObjetEtendu )
1070                $res .= '</dl>';
1071        return $res;
1072}
1073
1074/**
1075 * Tableau presentant les chiffres de synthese de la statistique descriptive
1076 *
1077 * @param string $legende
1078 *   Titre du tableau
1079 * @param string $sql_table_asso
1080 *   La table du plugin (sans prefixe "spip_asso") sur laquelle va porter les statistique.
1081 * @param array $sql_champs
1082 *   'chaine_de_langue' (sans prefixe) => "liste, des, champs, sur, laquelle, calculer, les statistiques"
1083 * @param string $sql_criteres
1084 *   Critere(s) de selection/restriction SQL des lignes (sinon toutes)
1085 * @param int $decimales_significatives
1086 *   Nombre de decimales affichees
1087 * @param bool $avec_extrema
1088 *   Indique s'il faut afficher (vrai) ou non (faux) les valeurs extremes.
1089 *   http://fr.wikipedia.org/wiki/Crit%C3%A8res_de_position#Valeur_maximum_et_valeur_minimum
1090 *   Par defaut : non, car le tableau deborde de ce petit cadre.
1091 * @return string $res
1092 *   Table HTML avec pour chaque ligne ($sql_champs) :
1093 *   - le nom attribue au groupe de champs
1094 *   - la moyenne arithmetique <http://fr.wikipedia.org/wiki/Moyenne#Moyenne_arithm.C3.A9tique>
1095 *   - l'ecart-type <http://fr.wikipedia.org/wiki/Dispersion_statistique#.C3.89cart_type>
1096 *   - ainsi que les extrema si on le desire
1097 */
1098function association_totauxinfos_stats($legende='', $sql_table_asso, $sql_champs, $sql_criteres='1=1',$decimales_significatives=1, $avec_extrema=false)
1099{
1100        if (!is_array($sql_champs) || !$sql_table_asso)
1101                return FALSE;
1102        $res = '<table width="100%" class="asso_infos">';
1103        $res .= '<caption>'. _T('asso:totaux_moyens', array('de_par'=>_T("local:$legende"))) .'</caption><thead>';
1104        $res .= '<tr class="row_first"> <th>&nbsp;</th>';
1105        $res .= '<th title="'. _T('entete_stats_moy') .'">x&#772</th>'; // X <span style="font-size:75%;">X</span>&#772 <span style="text-decoration:overline;">X</span> X<span style="position:relative; bottom:1.0ex; letter-spacing:-1.2ex; right:1.0ex">&ndash;</span> x<span style="position:relative; bottom:1.0ex; letter-spacing:-1.2ex; right:1.0ex">&macr;</span>
1106        $res .= '<th title="'. _T('entete_stats_mea') .'">&sigma;</th>'; // σ &sigma; &#963; &#x3C3;
1107        if ($avec_extrema) {
1108                $res .= '<th title="'. _T('entete_stats_min') .'">[&lt;</th>';
1109                $res .= '<th title="'. _T('entete_stats_max') .'">&gt;]</th>';
1110        }
1111        $res .= '</tr>';
1112        $res .= '</thead><tbody>';
1113        $compteur = 0;
1114        foreach ($sql_champs as $libelle=>$champs) {
1115                $stats = sql_fetsel("AVG($champs) AS valMoy, STDDEV($champs) AS ekrTyp, MIN($champs) AS valMin, MAX($champs) AS valMax ", "spip_asso_$sql_table_asso", $sql_criteres);
1116                $res .= '<tr class="'. ($compteur%2?'row_odd':'row_even') .'">';
1117                $res .= '<td class"text">'. _T('asso:'.(is_numeric($libelle)?$champs:$libelle)) .'</td>';
1118                $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['valMoy'],$decimales_significatives) .'</td>';
1119                $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['ekrTyp'],$decimales_significatives) .'</td>';
1120                if ($avec_extrema) {
1121                        $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['valMin'],$decimales_significatives) .'</td>';
1122                        $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['valMax'],$decimales_significatives) .'</td>';
1123                }
1124                $res .= '</tr>';
1125                $compteur++;
1126        }
1127        $res .= '</tbody></table>';
1128        return $res;
1129}
1130
1131/**
1132 * Tableau des decomptes statistiques dans le bloc infos
1133 *
1134 * @param string $legende
1135 *   Complement du titre du tableau
1136 * @param array $lignes
1137 *   'classe_unique_css_de_la_ligne' => array( 'chaine_de_langue', effectif_occurence)
1138 * @param int $decimales_significatives
1139 *   Nombre de decimales affichees
1140 * @return string $res
1141 *   Table HTML de deux colonnes et une ligne par paire libelle/effectif
1142 *   puis une ligne totalisant les effectifs s'il y a plus d'une ligne.
1143 *
1144 * @note
1145 *   Les classes CSS sont utilisees comme cle des tables parce-qu'il ne doit y en avoir qu'une par ligne.
1146 */
1147function association_totauxinfos_effectifs($legende='', $lignes, $decimales_significatives=0)
1148{
1149        if (!is_array($lignes) )
1150                return FALSE;
1151        $nombre = $nombre_total = 0;
1152        $res = '<table width="100%" class="asso_infos">';
1153        $res .= '<caption>'. _T('asso:totaux_nombres', array('de_par'=>_T("local:$legende"))) .'</caption><tbody>';
1154        foreach ($lignes as $classe_css=>$params) {
1155                $res .= '<tr class="'.$classe_css.'">';
1156                $res .= '<td class"text">'._T('asso:'.$params[0]).'</td>';
1157                $res .= '<td class="' .($decimales_significatives?'decimal':'integer') .'">'. association_formater_nombre($params[1],$decimales_significatives) .'</td>';
1158                $nombre_total += $params[1];
1159                $res .= '</tr>';
1160        }
1161        $res .= '</tbody>';
1162        if (count($lignes)>1) {
1163                $res .= '<tfoot>';
1164                $res .= '<tr><th class="text">'._T('asso:liste_nombre_total').'</th>';
1165                $res .= '<th class="' .($decimales_significatives?'decimal':'integer') .'">'. association_formater_nombre($nombre_total,$decimales_significatives) .'</th></tr>';
1166                $res .= '</tfoot>';
1167        }
1168        return $res.'</table>';
1169}
1170
1171/**
1172 * Tableau des totaux comptables
1173 *
1174 * @param string $legende
1175 *   Complement du titre du tableau
1176 * @param float $somme_recettes
1177 *   Total des recettes
1178 * @param float $somme_depenses
1179 *   Total des depenses
1180 * @return string $res
1181 *   Table HTML presentant les recettes (sur une ligne) et les depenses (sur une autre ligne), puis le solde (sur une derniere ligne)
1182 *
1183 * @attention
1184 *   Tous ces parametres sont facultatifs, mais un tableau est quand meme genere dans tous les cas !
1185 */
1186function association_totauxinfos_montants($legende='', $somme_recettes=0, $somme_depenses=0)
1187{
1188        $res = '<table width="100%" class="asso_infos">';
1189        $res .= '<caption>'. _T('asso:totaux_montants', array('de_par'=>_T("local:$legende"))) .'</caption><tbody>';
1190#       if ($somme_recettes) {
1191                $res .= '<tr class="impair">'
1192                . '<th class="entree">'. _T('asso:bilan_recettes') .'</th>'
1193                . '<td class="decimal">' .association_formater_prix($somme_recettes). ' </td>'
1194                . '</tr>';
1195#       }
1196#       if ($somme_depenses) {
1197                $res .= '<tr class="pair">'
1198                . '<th class="sortie">'. _T('asso:bilan_depenses') .'</th>'
1199                . '<td class="decimal">'.association_formater_prix($somme_depenses) .'</td>'
1200                . '</tr>';
1201#       }
1202        if ($somme_recettes && $somme_depenses) {
1203                $solde = $somme_recettes-$somme_depenses;
1204                $res .= '<tr class="'.($solde>0?'impair':'pair').'">'
1205                . '<th class="solde">'. _T('asso:bilan_solde') .'</th>'
1206                . '<td class="decimal">'.association_formater_prix($solde).'</td>'
1207                . '</tr>';
1208        }
1209        return $res.'</tbody></table>';
1210}
1211
1212/** @} */
1213
1214
1215/*****************************************
1216 * @defgroup association_bloc
1217 *
1218 *
1219** @{ */
1220
1221/**
1222 * Boite d'infos sur un objet (colonne gauche)
1223 *
1224 *
1225 * @note
1226 *   Une certaine similitude avec http://programmer.spip.org/boite_infos :)
1227  */
1228function association_bloc_infosgauche($TitreObjet, $NumObjet, $DesLignes=array(), $PrefixeLangue='asso', $ObjetEtendu='')
1229{
1230        $res = debut_boite_info(true);
1231        $res .= association_totauxinfos_intro($TitreObjet, $TitreObjet, $NumObjet, $DesLignes, $PrefixeLangu, $ObjetEtendu);
1232        $res .= association_date_du_jour();
1233        $res .= fin_boite_info(true);
1234        return $res;
1235}
1236
1237/**
1238 * Demande de confirmation dans la suppression d'un objet
1239 *
1240 * @param string $type
1241 *   Type d'objet a supprimer
1242 * @param int $id
1243 *   ID de l'objet a supprimer
1244 * @param string $retour
1245 *   Nom du fichier d'action vers lequel le formulaire sera redirige, sans le prefixe "supprimer_".
1246 *   Par defaut, quand rien n'est indique, c'est l'objet suffixe de "s" qui est utilise
1247 */
1248function association_bloc_suppression($type, $id, $retour='')
1249{
1250        $res = '<p><strong>'. _T('asso:vous_aller_effacer', array('quoi'=>'<i>'._T('asso:objet_num',array('objet'=>$type,'num'=>$id)).'</i>') ) .'</strong></p>';
1251        $res .= '<p class="boutons"><input type="submit" value="'._T('asso:bouton_confirmer').'" /></p>';
1252        echo redirige_action_post("supprimer_{$type}s", $id, ($retour?$retour:$type.'s'), '', $res);
1253
1254}
1255
1256/**
1257 * Bloc (tableau en ligne) d'affinage (filtrage) des resultats dans les pages principales... (ici il s'agit de la navigation au sein des donnees tabulaires --un grand listing-- d'un module...)
1258 *
1259 * @param array $liste_filtres
1260 *   Filtres natifs du plugin (identifiant prefixe de "association_selectionner_") :
1261 *   'identifiant_du_filtre'=>array('liste','des','parametres')
1262 * @param string $exec
1263 *   Nom du fichier "exec" auquel le formulaire sera soumis
1264 * @param string|array $supplements
1265 *   Utilisation d'autres filtres ou code supplementaire a rajourer a la fin
1266 *   - Chaine HTML a rajouter
1267 *   - Tableau des 'identifiant_filtre'=>"code HTML du filtre" a rajouter
1268 * @param bool $td
1269 *   Indique s'il faut generer un tableau (vrai, par defaut) ou une liste (faux)
1270 * @return string $res
1271 *   Form-HTML des filtres
1272 * @note
1273 *   Ici il s'agit d'un vrai formulaire qui influe sur les donnees affichees
1274 *   et non sur la fonctionnalite en cours (onglet), contrairement aux apparences
1275 *   (le passage de parametre se faisant par l'URL, celle-ci change)
1276 *   http://comments.gmane.org/gmane.comp.web.spip.devel/61824
1277 */
1278function association_bloc_filtres($liste_filtres, $exec='', $supplements='', $td=TRUE)
1279{
1280        $res = '<form method="get" action="'. ($exec?generer_url_ecrire($exec):'') .'">';
1281        if ($exec)
1282                $res .= "\n<input type='hidden' name='exec' value='$exec' />";
1283        $res .= "\n<". ($td?'table width="100%"':'ul') .' class="asso_tablo_filtres">'. ($td?'<tr>':'');
1284        foreach($liste_filtres as $filtre_selection =>$params) {
1285                $res .= ($td?'<td':'<li') ." class='filtre_$filtre_selection'>". call_user_func_array("association_selectionner_$filtre_selection", (is_array($params)?$params:array($params)) ) . ($td?'</td>':'</li>');
1286        }
1287        if ( is_array($supplements) ) {
1288                foreach ($supplements as $nom => $supplement) {
1289                        $res .= ($td?'<td':'<li') ." class='filtre_$nom'>$supplement</". ($td?'td>':'li>');
1290                }
1291        } else {
1292                $res .= $supplements;
1293        }
1294        $res .= ($td?'<td':'<li') . ' class="boutons"><noscript><input type="submit" value="'. _T('asso:bouton_lister') .'" /></noscript></td>' . ($td?'</td>':'</li>');
1295        return $res. ($td?'</tr></table':'</ul>') .">\n</form>\n";
1296}
1297
1298/**
1299 * Boite affichant le formulaire pour genere le PDF de la/le liste/tableau
1300 *
1301 * @param string $objet
1302 *   Nom de l'objet : il s'agit imperativement d'un objet du plugin,
1303 *   correspondant a une table avec le nom de l'objet suffixe de "s" et prefixe
1304 *   de "spip_asso" (cela exclu quand meme les tables du plugin qui n'ont pas de
1305 *   "s" final !)
1306 * @param string $params
1307 * @param string $prefixeLibelle
1308 *   Prefixe rajoute au nom du champ pour former la chaine de langue (dont le
1309 *   nommage est systematise dans "Associaspip")
1310 * @param array $champsExclus
1311 *   Liste (seules les valeurs du tableau sont prises en compte) des champs a ne
1312 *   pas prendre en compte : tous les autres champs de la table sont recuperes
1313 *   (mais seuls les champs geres par "Associaspip" et "Interface Champs Extras 2"
1314 *   seront affiches/proposes dans le formulaire, d'ou pas d'exclu par defaut)
1315 * @param bool $coords
1316 *   Indique s'il faut (vrai) prendre en compte ou pas (faux) le plugin "Coordonnees"
1317 * @return string $res
1318 *   Form HTML complet dans un cadre. Ce formulaire sera traite par l'exec de
1319 *   l'objet prefixe de "pdf_"
1320 */
1321function association_bloc_listepdf($objet, $params=array(), $prefixeLibelle='', $champsExclus=array(), $coords=true)
1322{
1323        $res = '';
1324        if (test_plugin_actif('FPDF')) { // liste
1325                $res .= debut_cadre_enfonce('',true);
1326                $res .= '<h3>'. _T('plugins_vue_liste') .'</h3>';
1327                $res .= '<div class="formulaire_spip formulaire_asso_liste_'.$objet.'s">';
1328                $champsExtras = association_trouver_iextras("asso_$objet");
1329                $frm = '<ul><li class="edit_champs">';
1330                $desc_table = charger_fonction('trouver_table', 'base'); // http://doc.spip.org/@description_table deprecier donc preferer http://programmer.spip.net/trouver_table,620
1331                $champsPresents = $desc_table("spip_asso_${objet}s");
1332                foreach ($champsPresents['field'] as $k => $v) { // donner le menu des choix
1333                        if ( !in_array($k, $champsExclus) ) { // affichable/selectionnable (champ ayant un libelle declare et connu)
1334                                $lang_clef = $prefixeLibelle.$k;
1335                                $lang_texte = _T('asso:'.$lang_clef);
1336                                if ( $lang_clef!=str_replace(' ', '_', $lang_texte) ) { // champ natif du plugin
1337                                        $frm .= "<div class='choix'><input type='checkbox' name='champs[$k]' id='liste_${objet}s_$k' /><label for='liste_${objet}s_$k'>$lang_texte</label></div>";
1338                                } elseif( array_key_exists($k,$champsExtras) ) { // champs rajoute via cextra
1339                                        $frm .= "<div class='choix'><input type='checkbox' name='champs[$k]' id='liste_${objet}s_$k' /><label for='liste_${objet}s_$k'>$champsExtras[$k]</label></div>";
1340                                }
1341                        }
1342                }
1343                if ($coords) {
1344                        $frm .= '<div class="choix"><input type="checkbox" name="champs[email]" id="liste_'.$objet.'s_email" /><label for="liste_'.$objet.'_s_email">'. _T('asso:adherent_libelle_email') .'</label></div>'; // on ajoute aussi l'adresse electronique principale (table spip_auteurs ou spip_emails)
1345                        if (test_plugin_actif('COORDONNEES')) {
1346                                $frm .= '<div class="choix"><input type="checkbox" name="champs[adresse]" id="liste_'.$objet.'_s_adresse" /><label for="liste_'.$objet.'_s_adresse">'. _T('coordonnees:adresses') .'</label></div>'; // on ajoute aussi l'adresse postale (table spip_adresses)
1347                                $frm .= '<div class="choix"><input type="checkbox" name="champs[telephone]" id="liste_'.$objet.'_s_telephone" /><label for="liste_'.$objet.'_s_telephone">'. _T('coordonnees:numeros') .'</label></div>'; // on ajoute aussi le numero de telephone (table spip_numeros)
1348                        }
1349                }
1350                foreach ($params as $k => $v) { // on fait suivre les autres parametres dont la liste des auteurs a afficher
1351                        $frm .= '<input type="hidden" name="'.$k.'" value="'. htmlspecialchars($v, ENT_QUOTES, $GLOBALS['meta']['charset']) .'" />'; // http://stackoverflow.com/questions/46483/htmlentities-vs-htmlspecialchars
1352                }
1353                $frm .= '</li></ul>';
1354                $frm .= '<p class="boutons"><input type="submit" value="'. _T('asso:bouton_imprimer') .'" /></p>';
1355                $res .= generer_form_ecrire("pdf_${objet}s", $frm, '', '');
1356                $res .= '</div>';
1357                $res .= fin_cadre_enfonce(true);
1358        }
1359
1360        return $res;
1361}
1362
1363/**
1364 * Listing sous forme de tableau HTML
1365 *
1366 * @param array $requete_sql
1367 *   Liste des parametres de "sql_select()"
1368 *   http://doc.spip.org/@sql_select
1369 *   http://programmer.spip.net/sql_select,569
1370 * @param array $presentation
1371 *   Tableau decrivant les donnees affichees :
1372 *   'nom_ou_alias_du_champ' => array('chaine_de:langue_du_libelle_d_entete', 'nom_du_format', 'parametre1', ...)
1373 *   Le nom du format est celui de la fonction de formatage du meme nom prefixee de association_formater_
1374 * @param array $boutons
1375 *   array('bouton', 'parametre1', ...)
1376 *   Le nom du type de bouton est celui de la fonction d'action du meme nom prefixee de association_bouton_
1377 * @param string $cle1
1378 *   Nom (ou alias) de la colonne cle primaire,
1379 * @param array $extra
1380 *   Liste de classes supplemetaires appliquees alternativement aux lignes ;
1381 *   Ou tableau des valeur=>classe supplementaires appliquees aux lignes presentant la valeur
1382 * @param string $cle2
1383 *   Nom (ou alias) de la colonne dont les valeurs servent de cle de classe
1384 * @param int $selection
1385 *   ID de la cle primaire selectionnee
1386 * @return string $res
1387 *   Table-HTML listant les donnees formatees
1388 */
1389function association_bloc_listehtml($requete_sql, $presentation, $boutons=array(), $cle1='', $extra=array(), $cle2='', $selection=0 )
1390{
1391        if ( !is_array($requete_sql) || count($requete_sql)<2 )
1392                return '';
1393        $table = ($requete_sql[1] ? $requete_sql[1] : ($requete_sql['table'] ? $requete_sql['table'] : ($requete_sql['from']?$requete_sql['from']:$requete_sql['tables']) ) ) ; // on recupere la partie "FROM" de la requete SQL...
1394        $table = substr_replace(trim( is_array($table)?$table[0]:$table ), '', 0, 5); //  on supprime le prefixe "spip_" de la 1ere table (normalement la principale...)
1395        $spc_pos = strpos($table, ' '); // requete avec alias (" AS ") ou jointure de plusieurs tables ( " JOIN ")
1396        $table = substr($table, 0, $spc_pos?$spc_pos:strlen($table) ); // on recupere jusqu'au premier espace (donc le vrai nom de la 1ere table) sinon la fin.
1397        $res =  '<table width="100%" class="asso_tablo" id="liste_'.$table.'">';
1398        $res .= "\n<thead>\n<tr>";
1399        foreach ($presentation as &$param) {
1400                $entete = array_shift($param);
1401                $res .= '<th>'. _T((strpos($entete,':') ? '' : 'asso:').$entete) .'</th>';
1402        }
1403        if ( count($boutons) ) {
1404                $res .= '<th colspan="'. count($boutons) .'" class="actions">'. _T('asso:entete_actions') .'</th>';
1405        }
1406        $res .= "</tr>\n</thead><tbody>";
1407        $nbr_lignes = 0;
1408        $reponse_sql = call_user_func_array('sql_select', $requete_sql);
1409        while ($data = sql_fetch($reponse_sql)) {
1410                $res .= '<tr'. ($cle1?' id="'.$data[$cle1].'"':'') .'>';
1411                foreach ($presentation as $champ=>$params) {
1412                        $format = array_shift($params);
1413                        switch ($format) {
1414                                case 'date' :
1415                                case 'heure' :
1416                                        $classes = 'date';
1417                                        break;
1418                                case 'duree' :
1419                                case 'nombre' :
1420                                case 'prix' :
1421                                        $classes = 'decimal';
1422                                        break;
1423                                case 'entier' :
1424                                        $classes = 'integer';
1425                                        $format = 'nombre'; $params = array(0);
1426                                        break;
1427                                case 'texte' : // ajouter : propre()
1428                                default :
1429                                        $classes = 'text';
1430                                        break;
1431                        }
1432                        if ( is_array($extra) && $nbr_couleurs=count($extra) ) { // on a bien un tableau de classes supplementaires
1433                                if ( $cle2 ) { // lignes colorees selon les valeurs d'un champ
1434                                        $classes .= ' '.$extra[$data[$cle2]];
1435                                } else { // simple alternance de couleurs
1436                                        $nbr_lignes++;
1437                                        $classes .= ' '.$extra[$nbr_lignes%$nbr_couleurs];
1438                                }
1439                        } elseif ( $extra ) { // classe supplementaire appliquee inconditionnellement
1440                                $classes .= " $extra";
1441                        }
1442                        if ( $data[$cle1]==$selection )
1443                                $classes .= ' surligne';
1444                        $ok = array_unshift($params,$data[$champ]);
1445                        $res .= '<td class="'.$classes.'">'. call_user_func_array("association_formater_$format", $params) .'</td>';
1446                }
1447                foreach ($boutons as $params) {
1448                        $type = array_shift($params);
1449                        foreach ($params as &$param) {
1450                                $param = str_replace('$$', $data[$cle1], $param);
1451                        }
1452                        $res .= call_user_func_array("association_bouton_$type", $params);
1453                }
1454                $res .= "</tr>\n";
1455        }
1456        return $res."</tbody>\n</table>\n";
1457}
1458
1459/** @} */
1460
1461
1462/*****************************************
1463 * @defgroup sql_asso1
1464 * Extension de l'API SQL pour Associaspip (operations qui reviennent souvent)
1465 *
1466 * @param string $table
1467 *   Le nom de l'objet : correspond a la table sans prefixe "spip_asso" et sans le "s" final
1468 * @param int $id
1469 *   ID de la ligne a recuperer
1470 * @param bool $pluriel
1471 *   Indique qu'il s'agit d'une table avec (vrai, par defaut) ou sans (faux) un
1472 *   suffixe "s". Mis a FALSE, permet de traiter le cas des tables _plan|destination|destination_op !
1473 *
1474** @{ */
1475
1476/**
1477 * Recupere dans une chaine un champ d'une table spip_asso_XXs pour un enregistrement identifie par son id_XX
1478 *
1479 * @param string $champ
1480 *   Nom du champ recherche
1481 * @return string
1482 *   Valeur du champ recherche
1483 *
1484 * @note Conversion d'anciennes fonctions :
1485 * - exercice_intitule($exo) <=> sql_asso1champ('exercice', $exo, 'intitule')
1486 * - exercice_date_debut($exercice) <=> sql_asso1champ('exercice', $exercice, 'debut')
1487 * - exercice_date_fin($exercice) <=> sql_asso1champ('exercice', $exercice, 'fin')
1488 */
1489function sql_asso1champ($table, $id, $champ, $pluriel=TRUE)
1490{
1491        return sql_getfetsel($champ, "spip_asso_$table".($pluriel?'s':''), "id_$table=".intval($id));
1492}
1493
1494/**
1495 * Recupere dans un tableau associatif un enregistrement d'une table spip_asso_XX identifie par son id_XX
1496 *
1497 * @return array
1498 *   Tableau des champs sous forme : 'nom_du_champ'=>"contenu du champ"
1499 */
1500function sql_asso1ligne($table, $id, $pluriel=TRUE)
1501{
1502        return sql_fetsel('*', "spip_asso_$table".($pluriel?'s':''), "id_$table=".intval($id));
1503}
1504
1505/** @} */
1506
1507
1508/*****************************************
1509 * @defgroup divers
1510 * Inclassables
1511 *
1512** @{ */
1513
1514/**
1515 * Cree le critere SQL Where portant sur le champ "statut_interne"
1516 *
1517 * Pour l'instant, appele uniquement dans exec/adherents.php vers la ligne 25
1518 */
1519function request_statut_interne()
1520{
1521        $statut_interne = _request('statut_interne');
1522        if (in_array($statut_interne, $GLOBALS['association_liste_des_statuts'] ))
1523                return 'statut_interne='. sql_quote($statut_interne);
1524        elseif ($statut_interne=='tous')
1525                return "statut_interne LIKE '%'";
1526        else {
1527                set_request('statut_interne', 'defaut');
1528                $a = $GLOBALS['association_liste_des_statuts'];
1529                array_shift($a);
1530                return sql_in('statut_interne', $a);
1531        }
1532}
1533
1534/**
1535 * Affichage du message indiquant la date
1536 *
1537 * @param bool $heure
1538 *   Indique s'il faut afficher (vrai) ou pas (faux, par defaut) l'heure.
1539 * @return string $res
1540 */
1541function association_date_du_jour($heure=false)
1542{
1543        $ladate = affdate_jourcourt(date('d/m/Y'));
1544        $hr = ($heure?date('H'):'');
1545        $mn = ($heure?date('i'):'');
1546        $res = '<p class="'. ($heure?'datetime':'date');
1547        $res .= '" title="'. date('Y-m-d') . ($heure?"T$hr:$mn":'');
1548        $lheure = ($heure? _T('spip:date_fmt_heures_minutes', array('h'=>$hr,'m'=>$mn)) :'');
1549        $res .= '">'.( $heure ? _T('asso:date_du_jour_heure', array('date'=>$ladate)) : _T('asso:date_du_jour',array('date'=>$ladate,'time'=>$lheure)) ).'</p>';
1550        return $res;
1551}
1552
1553/**
1554 * Injection de "association.css" dans le "header" de l'espace prive
1555 * @param string $flux
1556 * @return string $c
1557 */
1558function association_header_prive($flux)
1559{
1560        $c = direction_css(find_in_path('association.css'));
1561        return "$flux\n<link rel='stylesheet' type='text/css' href='$c' />";
1562}
1563
1564/**
1565 * Filtre pour "afficher" ou "cacher" un bloc div
1566 *
1567 * Utilise dans le formulaire cvt "editer_asso_comptes.html"
1568 *
1569 * @param string $type_operation
1570 * @param string $list_operation
1571 * @return string $res
1572 */
1573function affichage_div($type_operation, $list_operation)
1574{
1575        if(strpos($list_operation, '-')) {
1576                $operations = explode('-', $list_operation);
1577                $res = 'cachediv';
1578                for($i=0;$i<count($operations);$i++) {
1579                        $operation = $GLOBALS['association_metas']['classe_'.$operations[$i]];
1580                        if($type_operation===$operation) {
1581                                $res = '';
1582                                break;
1583                        }
1584                }
1585        } else {
1586                $res = ($type_operation===$GLOBALS['association_metas']['classe_'.$list_operation])?'':'cachediv';
1587        }
1588        return $res;
1589}
1590
1591/**
1592 * ??
1593 *
1594 * @param string $texte
1595 * @param string $avant
1596 * @param string $apres
1597 * @return string
1598 */
1599function encadre($texte,$avant='[',$apres=']')
1600{
1601    return ($texte=='')?'':$avant.$texte.$apres;
1602}
1603
1604/**
1605 * Pour construire des menu avec SELECTED
1606 *
1607 * @param string $varaut
1608 *   La valeur de l'option
1609 * @param string $variable
1610 *   La variable (passee par valeur) contenant la selection courante
1611 * @param mixed $option
1612 *   Quand cette variable est definie, indique de renvoyer un code partiel.
1613 *   Par defaut c'est le code complet de l' Option HTML qui est retourne
1614 * @return string
1615 *   Option de select HTML
1616 *
1617 * @note
1618 *   Utilise dans inc/instituer_statut_interne.php et inc/instituer_adherent.php
1619 */
1620function association_mySel($varaut, $variable, $option=NULL)
1621{
1622        if ( function_exists('mySel') ) //@ http://doc.spip.org/@mySel
1623                return mySel($varaut, $variable, $option);
1624        // la fonction mySel n'existe plus en SPIP 3 donc on la recree
1625        $res = ' value="'.$varaut.'"'. (($variable==$varaut) ? ' selected="selected"' : '');
1626        return  (!isset($option) ? $res : "<option$res>$option</option>\n");
1627}
1628
1629/**
1630 * Recupere la liste des champs extras manuellement rajoutes a un objet
1631 *
1632 * @param string $ObjetEtendu
1633 *   Nom de l'objet dont on veut recuperer les champs etendus
1634 * @param int $id
1635 *   ID de l'objet dont il veut recuperer aussi les donnees
1636 *   Par defaut : aucun (i.e. 0)
1637 * @return array $champsExtrasVoulus
1638 *   - si on ne veut pas de donnee :
1639 *     'nom_de_la_colonne'=>"Libelle du champ"
1640 *   - si on veut aussi les donnees :
1641 *     'nom_de_la_colonne'=>array( "Libelle du champ", "Donnee formatee", "Donnee brute SQL")
1642 */
1643function association_trouver_iextras($ObjetEtendu, $id=0)
1644{
1645        $champsExtrasVoulus = array();
1646        if (test_plugin_actif('IEXTRAS')) { // le plugin "Interfaces pour ChampsExtras2" est installe et active : on peut donc utiliser les methodes/fonctions natives...
1647                include_spip('inc/iextras'); // charger les fonctions de l'interface/gestionnaire (ce fichier charge les methode du core/API)
1648                if ($id)
1649                        include_spip('cextras_pipelines'); // pour eviter le "Fatal error : Call to undefined function cextras_enum()" en recuperant un fond utilisant les enum...
1650                $ChampsExtrasGeres = iextras_get_extras_par_table(); // C'est un tableau des differents "objets etendus" (i.e. tables principaux SPIP sans prefixe et au singulier -- par exemple la table 'spip_asso_membres' correspond a l'objet 'asso_membre') comme cle.
1651                foreach ($ChampsExtrasGeres[$ObjetEtendu] as $ChampExtraRang => $ChampExtraInfos ) { // Pour chaque objet, le tableau a une entree texte de cle "id_objet" et autant d'entrees tableau de cles numerotees automatiquement (a partir de 0) qu'il y a de champs extras definis.
1652                        if ( is_array($ChampExtraInfos) ) { // Chaque champ extra defini est un tableau avec les cle=>type suivants : "table"=>string, "champ"=>string, "label"=>string, "precisions"=>string, "obligatoire"=>string, "verifier"=>bool, "verifier_options"=>array, "rechercher"=>string, "enum"=>string, "type"=>string, "sql"=>string, "traitements"=>string, "saisie_externe"=>bool, "saisie_parametres"]=>array("explication"=>string, "attention"=>string, "class"=> string, "li_class"]=>string,)
1653                                $label = _TT($ChampExtraInfos['label']); // _TT est defini dans cextras_balises.php
1654                                if ( $id ) {
1655                                        $desc_table = charger_fonction('trouver_table', 'base');
1656                                        $champs = $desc_table("spip_$ChampExtraInfos[table]s");
1657                                        $datum_raw = sql_getfetsel($ChampExtraInfos['champ'], "spip_$ChampExtraInfos[table]s", $champs['key']['PRIMARY KEY'].'='.intval($id) ); // on recupere les donnees... (il faut que la table ait le nom de l'objet et le suffixe "s" :-S)
1658                                        $datum_parsed = recuperer_fond('extra-vues/'.$ChampExtraInfos['type'], array (
1659                                                'champ_extra' => $ChampExtraInfos['champ'],
1660                                                'label_extra' => '', // normalement : _TT($ChampExtraInfos['label']), avec la chaine vide on aura juste "<strong></strong> " a virer...
1661                                                'valeur_extra' => $ChampExtraInfos['traitement']?$ChampExtraInfos['traitement']($datum_raw):$datum_raw,
1662                                                'enum_extra' => $ChampExtraInfos['enum'], // parametre indispensable pour les champs de type "option"/"radio"/"case" http://forum.spip.net/fr_245942.html#forum245980
1663                                        )); // resultat du pipeline "affiche_contenu_objet" altere (prive du libelle du champ qui est envoye separement)
1664                                        $champsExtrasVoulus[$ChampExtraInfos['champ']] = array( $label, str_ireplace('<strong></strong>', '', $datum_parsed), $datum_raw );
1665                                } else {
1666                                        $champsExtrasVoulus[$ChampExtraInfos['champ']] = $label;
1667                                }
1668                        }
1669                }
1670        } else { // le plugin "Interfaces pour ChampsExtras2" n'est pas actif :-S Mais peut-etre a-t-il ete installe ?
1671                $ChampsExtrasGeres = @unserialize(str_replace('O:10:"ChampExtra"', 'a', $GLOBALS['meta']['iextras'])); // "iextras (interface)" stocke la liste des champs geres dans un meta. Ce meta est un tableau d'objets "ChampExtra" (un par champ extra) manipules par "cextras (core)". On converti chaque objet en tableau
1672                if ( !is_array($ChampsExtrasGeres) )
1673                        return array(); // fin : ChampsExtras2 non installe ou pas d'objet etendu.
1674                $TT = function_exists('_T_ou_typo') ? '_T_ou_typo' : '_T' ; // Noter que les <multi>...</multi> et <:xx:> sont aussi traites par propre() et typo() :  http://contrib.spip.net/PointsEntreeIncTexte
1675                foreach ($ChampsExtrasGeres as $ChampExtra) { // Chaque champ extra defini est un tableau avec les cle=>type suivants (les cles commencant par "_" initialisent des methodes de meme nom sans le prefixe) : "table"=>string, "champ"=>string, "label"=>string, "precisions"=>string, "obligatoire"=>string, "verifier"=>bool, "verifier_options"=>array, "rechercher"=>string, "enum"=>string, "type"=>string, "sql"=>string, "traitements"=>string, "_id"=>string, "_type"=>string, "_objet"=>string, "_table_sql"=>string, "saisie_externe"=>bool, "saisie_parametres"]=>array("explication"=>string, "attention"=>string, "class"=> string, "li_class"]=>string,)
1676                        if ($ChampExtra['table']==$ObjetEtendu) // c'est un champ extra de la 'table' ou du '_type' d'objet qui nous interesse
1677                                $label = $TT($ChampExtra['label']);
1678                                if ( $id ) {
1679                                        $datum_raw = sql_getfetsel($ChampExtra['champ'], $ChampExtra[_table_sql], "id__$ChampExtra[_type]=".intval($id) ); // on recupere les donnees... (il faut que l'identifiant soit l'objet prefixe de "id_" :-S)
1680                                        switch ( $ChampExtra['type'] ) { // Comme on n'est pas certain de pouvoir trouver "inc/iextra.php" et "inc/cextra.php" on a des chance que foire par moment. On va donc gerer les cas courants manuellement.
1681                                                case 'case' : // "<select type='checkbox' .../>..."
1682                                                case 'option' : // "<select ...>...</select>"
1683                                                case 'radio' : // "<select type='radio' .../>..."
1684                                                        $valeurs = array();
1685                                                        $enum = explode("\r\n", $ChampExtra['enum']);
1686                                                        foreach ($enum as $pair) {
1687                                                                list($key, $value) = explode(',', $pair, 1);
1688                                                                $valeurs[$key] = $value;
1689                                                        }
1690                                                        $datum_parsed = $ChampExtra['traitement']?$ChampExtra['traitement']($valeurs[$datum_raw]):$valeurs[$datum_raw];
1691                                                        break;
1692                                                case 'oui_non' :
1693                                                        $datum_parsed = _T("item:$datum_raw");
1694                                                        break;
1695//                                              case 'asso_activite' :
1696                                                case 'asso_categorie' :
1697                                                case 'asso_compte' :
1698//                                              case 'asso_don' :
1699                                                case 'asso_exercice' :
1700                                                case 'asso_membre' :
1701                                                case 'asso_ressource' :
1702//                                              case 'asso_vente' :
1703                                                        $raccourci = substr($ChampExtra['type'], 4); // on vire le prefixe "asso_"
1704                                                        if ( $ChampExtra['traitement'] )
1705                                                                $datum_parsed = $ChampExtra['traitement']('[->'.$raccourci.$datum_raw.']');
1706                                                        else { // il faut une requete de plus
1707                                                                switch ($raccourci) { // $valeur prend ici le champ SQL contenant la valeur desiree.
1708//                                                                      case 'activite' :
1709                                                                        case 'categorie' :
1710                                                                                $valeur = 'libelle';
1711                                                                                break;
1712                                                                        case 'compte' :
1713                                                                                $valeur = 'justification';
1714                                                                                break;
1715//                                                                      case 'don' :
1716                                                                        case 'exercice' :
1717                                                                                $valeur = 'intitule';
1718                                                                                break;
1719                                                                        case 'membre' :
1720                                                                                $valeur = 'nom_famille'; // il faudrait "concatener" : nom_famille, prenom, sexe ; le tout en fonction des metas... mais http://sql.1keydata.com/fr/sql-concatener.php
1721                                                                                break;
1722                                                                        case 'ressource' :
1723                                                                                $valeur = 'intitule';
1724                                                                                break;
1725//                                                                      case 'vente' :
1726                                                                        default :
1727                                                                                $valeur = 'titre'; // sauf coincidence heurese, on devrait avoir une erreur...
1728                                                                                break;
1729                                                                }
1730                                                                $datum_parsed = sql_getfetsel($valeur, "spip_$ChampExtra[type]s", 'id_'.($raccourci=='membre'?'auteur':$raccourci).'='.intval($datum_raw) ); // on recupere la donnee grace a la cle etrangere... (il faut que la table soit suffixee de "s" et que l'identifiant soit l'objet prefixe de "id_" :-S)
1731                                                        }
1732                                                        break;
1733                                                case 'article' :
1734                                                case 'auteur' :
1735                                                case 'breve' :
1736                                                case 'document' :
1737                                                case 'evenement' :
1738                                                case 'rubrique' :
1739                                                case 'site' :
1740                                                        if ( $ChampExtra['traitement'] )
1741                                                                $datum_parsed = $ChampExtra['traitement']('[->'.$ChampExtra['type'].$datum_raw.']');
1742                                                        else { // il faut une requete de plus
1743                                                                $datum_parsed = sql_getfetsel($ChampExtra['type']=='auteur'?'nom':'titre', "spip_$ChampExtra[type]s", "id_$ChampExtra[type]=".intval($datum_raw) );
1744                                                        }
1745                                                        break;
1746                                                case 'auteurs' :
1747                                                        if ( $ChampExtra['traitement'] ) {
1748                                                                $valeurs = explode($datum_raw, ',');
1749                                                                foreach ($valeurs as $rang=>$valeur)
1750                                                                        $valeurs[$rang] = '[->auteur'.$valeurs[$rang].']';
1751                                                                $datum_parsed = implode(';', $valeurs);
1752                                                        } else { // il faut une requete de plus
1753                                                                $valeurs = sql_fetchall('nom', "spip_auteurs", "id_auteur IN (".sql_quote($datum_raw).')' );
1754                                                                $datum_parsed = implode(';', $valeurs);
1755                                                        }
1756                                                        break;
1757                                                case 'bloc' : // "<textarea...>...</textarea>"
1758                                                case 'ligne' : // "<input type='text' .../>"
1759                                                default :
1760                                                        $ChampExtra['traitement']?$ChampExtra['traitement']($datum_raw):$datum_raw;
1761                                        }
1762                                        $champsExtrasVoulus[$ChampExtra['champ']] = array( $label, $print, $datum );
1763                                } else {
1764                                        $champsExtrasVoulus[$ChampExtra['champ']] = $label;
1765                                }
1766                }
1767        }
1768        return $champsExtrasVoulus;
1769}
1770
1771/** @} */
1772
1773
1774// pour executer les squelettes comportant la balise Meta
1775include_spip('balise/meta');
1776
1777// charger les metas donnees
1778$inc_meta = charger_fonction('meta', 'inc'); // inc_version l'a deja chargee
1779$inc_meta('association_metas');
1780
1781// pouvoir utiliser les fonctions de coordonnees comme filtre
1782if (test_plugin_actif('COORDONNEES')) {
1783        include_spip('inc/association_coordonnees');
1784}
1785
1786
1787?>
Note: See TracBrowser for help on using the repository browser.