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

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

suite refactoring et corrections

File size: 72.7 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|array $icone
620 *   Nom (couleur) de la puce parmis celles disponibles : orange, rouge, vert, poubelle...
621 *   Tableau associant chaque statut a un nom de puce...
622 * @param bool $acote
623 *   Indique si la legende est placee a cote de l'icone (vrai, par defaut) ou dedans (faux)
624 * @return string
625 *   Dessin et texte
626 */
627function association_formater_puce($statut, $icone,  $acote=TRUE)
628{
629        if ( is_array($icone) )
630                $icone = $icone[$statut];
631        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
632}
633
634/** @} */
635
636
637/*****************************************
638 * @defgroup association_recuperer
639 * Transforme un champ de formulaire en vue de son insertion en base de donnees.
640 * S'utilise donc sur un champ passe par le @ref association_verifier correspondant.
641 * Assure donc un bon enregistrement et la restitution par le @ref association_formater correspondant.
642 *
643 * @param string $valeur
644 *   Nom a recuperer (par GET ou POST ou Cookie) ...ou la valeur directement
645 * @param bool $req
646 *   Indique s'il s'agit du nom (vrai --par defaut) ou pas (faux, donc la valeur)
647 *
648** @{ */
649
650/**
651 * @return string $valeur
652 *   Date au format ISO
653 */
654function association_recuperer_date($valeur, $req=false)
655{
656        if ($valeur!='') {
657                $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.
658        }
659        return $valeur;
660}
661
662/**
663 * @return float $valeur
664 *   Nombre decimal
665 */
666function association_recuperer_montant($valeur, $req=false)
667{
668        if ($valeur!='') {
669                $valeur = str_replace(' ', '', ($req?_request($valeur):$valeur) ); // suppprime les espaces separateurs de milliers
670                $valeur = str_replace(',', '.', $valeur); // convertit les , en .
671                $valeur = floatval($valeur);
672        } else
673                $valeur = 0.0;
674        return $valeur;
675}
676
677/** @} */
678
679
680/*****************************************
681 * @defgroup association_verifier
682 * Verification du format de la valeur d'un champ de formulaire.
683 * Permet d'appeler @ref association_recupere equivalent sur ce champ...
684 *
685 * @param string $valeur
686 *   Nom a recuperer (par GET ou POST ou Cookie) ...ou la valeur directement
687 * @param bool $rex
688 *   Indique si la verification est plus lache (vrai) ou pas (faux --par defaut)
689 *   [le nom de la variable signifie "RElaXed check"]
690 * @param bool $req
691 *   Indique s'il s'agit du nom (vrai --par defaut) ou pas (faux, donc la valeur)
692 *   [le nom de la variable signifie "by REQuest"]
693 * @return string
694 *   Message d'erreur... (donc chaine vide si OK)
695 *
696** @{ */
697
698/**
699 * S'assurer que la valeur saisie est une chaine de date valide
700 */
701function association_verifier_date($valeur, $rex=FALSE, $req=TRUE)
702{
703        $date = $req ? _request($valeur) : $valeur;
704        if ( $rex && ($date=='0000-00-00' || !$date) )
705                return '';
706        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...
707#       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...
708                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)
709        list($annee, $mois, $jour) = preg_split('/\D/', $date);
710        if (!checkdate($mois, $jour, $annee)) // la date doit etre valide : pas de 30 fevrier ou de 31 novembre par exemple.
711                return _T('asso:erreur_valeur_date', array('date'=>$date) );
712        return '';
713}
714
715/**
716 * S'assurer que la valeur saisie est un flottant positif
717 */
718function association_verifier_montant($valeur, $req=TRUE)
719{
720        if (association_recuperer_montant($valeur,$req)<0)
721                return _T('asso:erreur_montant');
722        else
723                return '';
724}
725
726/**
727 * S'assurer que l'entier saisie correspond bien a un id_auteur
728 * de la table spip_asso_membres (par defaut) ou spip_auteurs (si on elargi a tous
729 * --ceci permet d'editer des membres effaces tant qu'ils sont references par SPIP)
730 */
731function association_verifier_membre($valeur, $rex=FALSE, $req=TRUE)
732{
733        $id_auteur = intval($req?_request($valeur):$valeur);
734        if ($id_auteur) {
735                if ( sql_countsel('spip_'.($rex?'auteurs':'asso_membres'), "id_auteur=$id_auteur")==0 ) {
736                        return _T('asso:erreur_id_adherent');
737                }
738        } else
739                return '';
740}
741
742/** @} */
743
744
745/*****************************************
746 * @defgroup association_selectionner
747 * Selecteur HTML (liste deroulante) servant a filtrer le listing affiche en milieu de page
748 *
749 * @param int $sel
750 *   ID selectionne : conserve la valeur selectionnee
751 * @param string $exec
752 *   Nom du fichier de l'espace prive auquel le formulaire sera soumis.
753 *   Si present, le formulaire complet (balise-HTML "FORM") est genere.
754 *   Si absent (par defaut), seul le selecteur (et le code supplementaire fourni
755 *   par $plus) est(sont) renvoye(s).
756 * @param string $plus
757 *   Source HTML rajoute a la suite.
758 *   (utile si on genere tout le formulaire avec des champs caches)
759 * @return string $res
760 *   Code HTML du selecteur (ou du formulaire complet si $exec est indique)
761 *
762** @{ */
763
764/**
765 * Selecteur d'exercice comptable
766 */
767function association_selectionner_exercice($sel='', $exec='', $plus='')
768{
769    $res = '<select name ="exercice" onchange="form.submit()">';
770#    $res .= '<option value="0" ';
771#    if (!$exercice) {
772#               $res .= ' selected="selected"';
773#    }
774#    $res .= '>'. _L("choisir l'exercice ?") .'</option>';
775    $sql = sql_select('id_exercice, intitule', 'spip_asso_exercices','', 'intitule DESC');
776    while ($val = sql_fetch($sql)) {
777                $res .= '<option value="'.$val['id_exercice'].'" ';
778                if ( $sel==$val['id_exercice'] ) {
779                        $res .= ' selected="selected"';
780                }
781                $res .= '>'.$val['intitule'].'</option>';
782    }
783    $res .= '</select>'.$plus;
784    return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
785}
786
787/**
788 * Selecteur de destination comptable
789 */
790function association_selectionner_destination($sel='', $exec='', $plus='')
791{
792    $res = '<select name ="destination" onchange="form.submit()">';
793    $res .= '<option value="0" ';
794    if ( !$sel) {
795                $res .= ' selected="selected"';
796    }
797    $res .= '>'. _T('asso:toutes_destinations') .'</option>';
798    $intitule_destinations = array();
799    $sql = sql_select('id_destination, intitule', 'spip_asso_destination','', 'intitule DESC');
800    while ($val = sql_fetch($sql)) {
801                $res .= '<option value="'.$val['id_destination'].'" ';
802                if ( $sel==$val['id_destination'] ) {
803                        $res .= ' selected="selected"';
804                }
805                $res .= '>'.$val['intitule'].'</option>';
806    }
807    $res .= '</select>'.$plus;
808    if ($GLOBALS['association_metas']['destinations']){
809                return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
810        } else {
811                return '';
812        }
813}
814
815/**
816 * Selecteur de grouoe de membres
817 */
818function association_selectionner_groupe($sel='', $exec='', $plus='')
819{
820    $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
821    if ( $qGroupes && sql_count($qGroupes) ) { // ne proposer que s'il y a des groupes definis
822                $res = '<select name="groupe" onchange="form.submit()">';
823                $res .= '<option value="">'._T('asso:tous_les_groupes').'</option>';
824                while ($groupe = sql_fetch($qGroupes)) {
825                        $res .= '<option value="'.$groupe['id_groupe'].'"';
826                        if ( $sel==$groupe['id_groupe'] )
827                                $res .= ' selected="selected"';
828                        $res .= '>'.$groupe['nom'].'</option>';
829                }
830                $res .= '</select>'.$plus;
831                return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
832        } else {
833                return '';
834        }
835}
836
837/**
838 * Selecteur de statut de membres
839 */
840function association_selectionner_statut($sel='', $exec='', $plus='')
841{
842    $res = '<select name="statut_interne" onchange="form.submit()">';
843    $res .= '<option value="%"'. (($sel=='defaut' || $sel=='%')?' selected="selected"':'') .'>'._T('asso:entete_tous').'</option>';
844    foreach ($GLOBALS['association_liste_des_statuts'] as $statut) {
845                $res .= '<option value="'.$statut.'"';
846                if ( $sel==$statut )
847                        $res .= ' selected="selected"';
848                $res .= '> '._T('asso:adherent_entete_statut_'.$statut).'</option>';
849        }
850        $res .= '</select>'.$plus;
851    return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
852}
853
854/**
855 * Zone de saisie de numero de membre
856 */
857function association_selectionner_id($sel='', $exec='', $plus='')
858{
859    $res = '<input type="text" name="id" onfocus=\'this.value=""\' size="5"  value="'. ($sel?$sel:_T('asso:entete_id')) .'" />'.$plus;
860    return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
861}
862
863/**
864 * Selecteur d'annee parmi celles disponibles dans une table donnee
865 *
866 * @param string $annee
867 *   Annee selectionnee. (annee courante par defaut)
868 * @param string $dtable
869 *   Nom (sans prefixe) de la table concernee
870 * @param string $dchamp
871 *   Nom (sans prefixe "date_") du champ contenant les annees recherchees
872 *
873 */
874function association_selectionner_annee($annee='', $dtable, $dchamp, $exec='', $plus='')
875{
876    if ($exec) {
877                $res = '<form method="post" action="'. generer_url_ecrire($exec) .'"><div>';
878                $res .= '<input type="hidden" name="exec" value="'.$exec.'" />';
879    } else {
880                $res = '';
881    }
882    $pager = '';
883    $res .= '<select name ="annee" onchange="form.submit()">';
884    $an_max = sql_getfetsel("MAX(DATE_FORMAT(date_$dchamp, '%Y')) AS an_max", "spip_$dtable", '');
885    $an_min = sql_getfetsel("MIN(DATE_FORMAT(date_$dchamp, '%Y')) AS an_min", "spip_$dtable", '');
886    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
887                $res .= '<option value="'.$annee.'" selected="selected">'.$annee.'</option>';
888
889        }
890    $sql = sql_select("DATE_FORMAT(date_$dchamp, '%Y') AS annee", "spip_$dtable",'', 'annee DESC', 'annee');
891    while ($val = sql_fetch($sql)) {
892                $res .= '<option value="'.$val['annee'].'"';
893                if ($annee==$val['annee']) {
894                        $res .= ' selected="selected"';
895                        $pager .= "\n<strong>$val[annee]</strong>";
896                } else {
897                        $pager .= ' <a href="'. generer_url_ecrire($exec, '&annee='.$val['annee']) .'">'.$val['annee']."</a>\n";
898                }
899                $res .= '>'.$val['annee'].'</option>';
900    }
901    $res .= '</select>'.$plus;
902    if ($exec) {
903                $res .= '<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>';
904                $res .= '</div></form>';
905    }
906    return $res;
907}
908
909/**
910 * Selecteur de destinations comptables
911 */
912function association_selectionner_destinations($sel='', $exec='', $plus='')
913{
914    $res = '<select name ="destination[]" multiple="multiple" onchange="form.submit()">';
915    $res .= '<option value="0" ';
916    if ( !(array_search(0, $sel)===FALSE) ) {
917                $res .= ' selected="selected"';
918    }
919    $res .= '>'. _T('asso:toutes_destinations') .'</option><option disabled="disabled">--------</option>';
920    $intitule_destinations = array();
921    $sql = sql_select('id_destination, intitule', 'spip_asso_destination','', 'intitule DESC');
922    while ($val = sql_fetch($sql)) {
923                $res .= '<option value="'.$val['id_destination'].'" ';
924                if ( !(array_search($val['id_destination'], $sel)===FALSE) ) {
925                        $res .= ' selected="selected"';
926                }
927                $intitule_destinations[$val['id_destination']] = $val['intitule'];
928    }
929    $res .= '</select>'.$plus;
930    if ($GLOBALS['association_metas']['destinations']){
931                return $exec ? generer_form_ecrire($exec, $res.'<noscript><input type="submit" value="'._T('asso:bouton_lister').'" /></noscript>') : $res;
932        } else {
933                return FALSE;
934        }
935}
936
937/** @} */
938
939
940/*****************************************
941 * @defgroup generer_url
942 * Raccourcis
943 *
944 * Les tables ayant deux prefixes ("spip_asso_"),
945 * le raccourci "x" implique de declarer le raccourci "asso_x"
946 *
947** @{ */
948
949function generer_url_asso_don($id, $param='', $ancre='') {
950        return  generer_url_ecrire('edit_don', 'id='.intval($id));
951}
952function generer_url_don($id, $param='', $ancre='') {
953        return  array('asso_don', $id);
954}
955
956function generer_url_asso_membre($id, $param='', $ancre='') {
957        return  generer_url_ecrire('adherent', 'id='.intval($id));
958}
959function generer_url_membre($id, $param='', $ancre='') {
960        return  array('asso_membre', $id);
961}
962
963function generer_url_asso_vente($id, $param='', $ancre='') {
964        return  generer_url_ecrire('edit_vente', 'id='.intval($id));
965}
966function generer_url_vente($id, $param='', $ancre='') {
967        return  array('asso_vente', $id);
968}
969
970function generer_url_asso_ressource($id, $param='', $ancre='') {
971        return  generer_url_ecrire('edit_ressource', 'id='.intval($id));
972}
973function generer_url_ressource($id, $param='', $ancre='') {
974        return  array('asso_ressource', $id);
975}
976
977function generer_url_asso_activite($id, $param='', $ancre='') {
978        return  generer_url_ecrire('voir_activite', 'id='.intval($id));
979}
980function generer_url_activite($id, $param='', $ancre='') {
981        return  array('asso_activite', $id);
982}
983
984/** @} */
985
986
987/*****************************************
988 * @defgroup instituer_
989 *
990 * @param array $auteur
991 * @return string
992 *
993** @{ */
994
995function instituer_adherent_ici($auteur=array()){
996        $instituer_adherent = charger_fonction('instituer_adherent', 'inc');
997        return $instituer_adherent($auteur);
998}
999
1000function instituer_statut_interne_ici($auteur=array()){
1001        $instituer_statut_interne = charger_fonction('instituer_statut_interne', 'inc');
1002        return $instituer_statut_interne($auteur);
1003}
1004
1005/** @} */
1006
1007
1008/*****************************************
1009 * @defgroup association_totauxinfos
1010 * Informations de synthese, sur un objet, destinees a etre presente dans le bloc
1011 * d'infos contextuel debutant la colonne de gauche
1012 *
1013** @{ */
1014
1015/**
1016 * Rappels sur l'objet dans le bloc infos
1017 *
1018 * C'est un resume ou une petite presentation de l'objet en cours
1019 * d'edition/lecture : ces informations permettent de situer le contexte de la
1020 * page et n'apparaissent pas dans le bloc central !
1021 *
1022 * @param string $titre
1023 *   Titre affiche en gros dans le bloc.
1024 * @param string $type
1025 *   Nom du raccourci, affiche au dessus du titre.
1026 * @param int $id
1027 *   ID de l'objet, affiche au dessus du titre
1028 * @param array $DesLignes
1029 *   Tableau des lignes supplementaires a rajouter dans le bloc, sous la forme :
1030 *   chaine_de_langue_du_titre (sans prefixe) => texte contenu/explication associe.
1031 * @param string $PrefixeLangue
1032 *   Prefixe de langue associe aux chaines de langue des titres de lignes.
1033 *   Par defaut : asso
1034 * @param string $ObjetEtendu
1035 *   Nom de l'objet etendu dont on desire afficher les lignes des champs rajoutes par "Interface Champs Extras 2".
1036 *   Par defaut : rien
1037 * @return string $res
1038 *
1039 * @note
1040 *   Ce n'est pas redondant d'avoir a la fois $type et $ObjetEtendu qui peuvent
1041 *   avoir des valeurs differentes comme on peut le voir dans exec/adherent.php et exec/inscrits_activite.php !
1042 */
1043function association_totauxinfos_intro($titre, $type='', $id=0, $DesLignes=array(), $PrefixeLangue='asso', $ObjetEtendu='')
1044{
1045        $res = '';
1046        if ($type) {
1047                $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>';
1048        }
1049        $res .= '<div style="text-align: center" class="verdana1 spip_medium">'.$titre.'</div>';
1050        if ( count($DesLignes) OR $ObjetEtendu )
1051                $res .= '<dl class="verdana1 spip_xx-small">';
1052        foreach ($DesLignes as $dt=>$dd) {
1053                $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>";
1054        }
1055        if ($ObjetEtendu) {
1056                $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 !)
1057                if ( count($champsExtras) ) {
1058                        foreach ($champsExtras as $champExtra) {
1059                                $res .= '<dt>'. $champExtra[0] .'</dt>';
1060                                $res .= '<dd>'. $champExtra[1] .'</dd>';
1061/*
1062                                if ( strstr($champExtra[1], '<div')===0 ) { // c'est dans un "DIV" superflu
1063                                        $res .= substr_replace( substr_replace($chamExtra[1], '</dd>', strrpos($chamExtra[1],'</div>'), 6), 'dd', 1, 3);
1064                                } else {
1065                                        $res .= '<dd>'. $champExtra[0] .'</dd>';
1066                                }
1067*/
1068                                $res .= '<!--dd>'. $champExtra[2] .'</dd-->'; // comparaison de controle
1069                        }
1070                }
1071        }
1072        if ( count($DesLignes) OR $ObjetEtendu )
1073                $res .= '</dl>';
1074        return $res;
1075}
1076
1077/**
1078 * Tableau presentant les chiffres de synthese de la statistique descriptive
1079 *
1080 * @param string $legende
1081 *   Titre du tableau
1082 * @param string $sql_table_asso
1083 *   La table du plugin (sans prefixe "spip_asso") sur laquelle va porter les statistique.
1084 * @param array $sql_champs
1085 *   'chaine_de_langue' (sans prefixe) => "liste, des, champs, sur, laquelle, calculer, les statistiques"
1086 * @param string $sql_criteres
1087 *   Critere(s) de selection/restriction SQL des lignes (sinon toutes)
1088 * @param int $decimales_significatives
1089 *   Nombre de decimales affichees
1090 * @param bool $avec_extrema
1091 *   Indique s'il faut afficher (vrai) ou non (faux) les valeurs extremes.
1092 *   http://fr.wikipedia.org/wiki/Crit%C3%A8res_de_position#Valeur_maximum_et_valeur_minimum
1093 *   Par defaut : non, car le tableau deborde de ce petit cadre.
1094 * @return string $res
1095 *   Table HTML avec pour chaque ligne ($sql_champs) :
1096 *   - le nom attribue au groupe de champs
1097 *   - la moyenne arithmetique <http://fr.wikipedia.org/wiki/Moyenne#Moyenne_arithm.C3.A9tique>
1098 *   - l'ecart-type <http://fr.wikipedia.org/wiki/Dispersion_statistique#.C3.89cart_type>
1099 *   - ainsi que les extrema si on le desire
1100 */
1101function association_totauxinfos_stats($legende='', $sql_table_asso, $sql_champs, $sql_criteres='1=1',$decimales_significatives=1, $avec_extrema=false)
1102{
1103        if (!is_array($sql_champs) || !$sql_table_asso)
1104                return FALSE;
1105        $res = '<table width="100%" class="asso_infos">';
1106        $res .= '<caption>'. _T('asso:totaux_moyens', array('de_par'=>_T("local:$legende"))) .'</caption><thead>';
1107        $res .= '<tr class="row_first"> <th>&nbsp;</th>';
1108        $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>
1109        $res .= '<th title="'. _T('entete_stats_mea') .'">&sigma;</th>'; // σ &sigma; &#963; &#x3C3;
1110        if ($avec_extrema) {
1111                $res .= '<th title="'. _T('entete_stats_min') .'">[&lt;</th>';
1112                $res .= '<th title="'. _T('entete_stats_max') .'">&gt;]</th>';
1113        }
1114        $res .= '</tr>';
1115        $res .= '</thead><tbody>';
1116        $compteur = 0;
1117        foreach ($sql_champs as $libelle=>$champs) {
1118                $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);
1119                $res .= '<tr class="'. ($compteur%2?'row_odd':'row_even') .'">';
1120                $res .= '<td class"text">'. _T('asso:'.(is_numeric($libelle)?$champs:$libelle)) .'</td>';
1121                $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['valMoy'],$decimales_significatives) .'</td>';
1122                $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['ekrTyp'],$decimales_significatives) .'</td>';
1123                if ($avec_extrema) {
1124                        $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['valMin'],$decimales_significatives) .'</td>';
1125                        $res .= '<td class="'.($decimales_significatives?'decimal':'integer').'">'. association_formater_nombre($stats['valMax'],$decimales_significatives) .'</td>';
1126                }
1127                $res .= '</tr>';
1128                $compteur++;
1129        }
1130        $res .= '</tbody></table>';
1131        return $res;
1132}
1133
1134/**
1135 * Tableau des decomptes statistiques dans le bloc infos
1136 *
1137 * @param string $legende
1138 *   Complement du titre du tableau
1139 * @param array $lignes
1140 *   'classe_unique_css_de_la_ligne' => array( 'chaine_de_langue', effectif_occurence)
1141 * @param int $decimales_significatives
1142 *   Nombre de decimales affichees
1143 * @return string $res
1144 *   Table HTML de deux colonnes et une ligne par paire libelle/effectif
1145 *   puis une ligne totalisant les effectifs s'il y a plus d'une ligne.
1146 *
1147 * @note
1148 *   Les classes CSS sont utilisees comme cle des tables parce-qu'il ne doit y en avoir qu'une par ligne.
1149 */
1150function association_totauxinfos_effectifs($legende='', $lignes, $decimales_significatives=0)
1151{
1152        if (!is_array($lignes) )
1153                return FALSE;
1154        $nbr_actuel = $nbr_total = 0;
1155        $res = '<table width="100%" class="asso_infos">';
1156        $res .= '<caption>'. _T('asso:totaux_nombres', array('de_par'=>_T("local:$legende"))) .'</caption><tbody>';
1157        foreach ($lignes as $classe_css=>$params) {
1158                $res .= '<tr class="'.$classe_css.'">';
1159                $res .= '<td class"text">'._T('asso:'.$params[0]).'</td>';
1160                $nbr_actuel = is_array($params[1]) ? call_user_func_array('sql_countsel', $params[1]) : $params[1] ;
1161                $res .= '<td class="' .($decimales_significatives?'decimal':'integer') .'">'. association_formater_nombre($nbr_actuel, $decimales_significatives) .'</td>';
1162                $nbr_total += $nbr_actuel;
1163                $res .= '</tr>';
1164        }
1165        $res .= '</tbody>';
1166        if (count($lignes)>1) {
1167                $res .= '<tfoot>';
1168                $res .= '<tr><th class="text">'._T('asso:liste_nombre_total').'</th>';
1169                $res .= '<th class="' .($decimales_significatives?'decimal':'integer') .'">'. association_formater_nombre($nbr_total, $decimales_significatives) .'</th></tr>';
1170                $res .= '</tfoot>';
1171        }
1172        return $res.'</table>';
1173}
1174
1175/**
1176 * Tableau des totaux comptables
1177 *
1178 * @param string $legende
1179 *   Complement du titre du tableau
1180 * @param float $somme_recettes
1181 *   Total des recettes
1182 * @param float $somme_depenses
1183 *   Total des depenses
1184 * @return string $res
1185 *   Table HTML presentant les recettes (sur une ligne) et les depenses (sur une autre ligne), puis le solde (sur une derniere ligne)
1186 *
1187 * @attention
1188 *   Tous ces parametres sont facultatifs, mais un tableau est quand meme genere dans tous les cas !
1189 */
1190function association_totauxinfos_montants($legende='', $somme_recettes=0, $somme_depenses=0)
1191{
1192        $res = '<table width="100%" class="asso_infos">';
1193        $res .= '<caption>'. _T('asso:totaux_montants', array('de_par'=>_T("local:$legende"))) .'</caption><tbody>';
1194        $recettes = is_array($somme_recettes) ? call_user_func_array('sql_getfetsel', $somme_recettes) : $somme_recettes ;
1195#       if ($recettes) {
1196                $res .= '<tr class="impair">'
1197                . '<th class="entree">'. _T('asso:bilan_recettes') .'</th>'
1198                . '<td class="decimal">' .association_formater_prix($recettes). ' </td>'
1199                . '</tr>';
1200#       }
1201        $depenses = is_array($somme_depenses) ? call_user_func_array('sql_getfetsel', $somme_depenses) : $somme_depenses ;
1202#       if ($depenses) {
1203                $res .= '<tr class="pair">'
1204                . '<th class="sortie">'. _T('asso:bilan_depenses') .'</th>'
1205                . '<td class="decimal">'.association_formater_prix($depenses) .'</td>'
1206                . '</tr>';
1207#       }
1208        if ($recettes && $depenses) {
1209                $solde = $recettes-$depenses;
1210                $res .= '<tr class="'.($solde>0?'impair':'pair').'">'
1211                . '<th class="solde">'. _T('asso:bilan_solde') .'</th>'
1212                . '<td class="decimal">'.association_formater_prix($solde).'</td>'
1213                . '</tr>';
1214        }
1215        return $res.'</tbody></table>';
1216}
1217
1218/** @} */
1219
1220
1221/*****************************************
1222 * @defgroup association_bloc
1223 *
1224 *
1225** @{ */
1226
1227/**
1228 * Boite d'infos sur un objet (colonne gauche)
1229 *
1230 *
1231 * @note
1232 *   Une certaine similitude avec http://programmer.spip.org/boite_infos :)
1233  */
1234function association_bloc_infosgauche($TitreObjet, $NumObjet, $DesLignes=array(), $PrefixeLangue='asso', $ObjetEtendu='')
1235{
1236        $res = debut_boite_info(true);
1237        $res .= association_totauxinfos_intro($TitreObjet, $TitreObjet, $NumObjet, $DesLignes, $PrefixeLangu, $ObjetEtendu);
1238        $res .= association_date_du_jour();
1239        $res .= fin_boite_info(true);
1240        return $res;
1241}
1242
1243/**
1244 * Demande de confirmation dans la suppression d'un objet
1245 *
1246 * @param string $type
1247 *   Type d'objet a supprimer
1248 * @param int $id
1249 *   ID de l'objet a supprimer
1250 * @param string $retour
1251 *   Nom du fichier d'action vers lequel le formulaire sera redirige, sans le prefixe "supprimer_".
1252 *   Par defaut, quand rien n'est indique, c'est l'objet suffixe de "s" qui est utilise
1253 */
1254function association_bloc_suppression($type, $id, $retour='')
1255{
1256        $res = '<p><strong>'. _T('asso:vous_aller_effacer', array('quoi'=>'<i>'._T('asso:objet_num',array('objet'=>$type,'num'=>$id)).'</i>') ) .'</strong></p>';
1257        $res .= '<p class="boutons"><input type="submit" value="'._T('asso:bouton_confirmer').'" /></p>';
1258        echo redirige_action_post("supprimer_{$type}s", $id, ($retour?$retour:$type.'s'), '', $res);
1259
1260}
1261
1262/**
1263 * 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...)
1264 *
1265 * @param array $liste_filtres
1266 *   Filtres natifs du plugin (identifiant prefixe de "association_selectionner_") :
1267 *   'identifiant_du_filtre'=>array('liste','des','parametres')
1268 * @param string $exec
1269 *   Nom du fichier "exec" auquel le formulaire sera soumis
1270 * @param string|array $supplements
1271 *   Utilisation d'autres filtres ou code supplementaire a rajourer a la fin
1272 *   - Chaine HTML a rajouter
1273 *   - Tableau des 'identifiant_filtre'=>"code HTML du filtre" a rajouter
1274 * @param bool $td
1275 *   Indique s'il faut generer un tableau (vrai, par defaut) ou une liste (faux)
1276 * @return string $res
1277 *   Form-HTML des filtres
1278 * @note
1279 *   Ici il s'agit d'un vrai formulaire qui influe sur les donnees affichees
1280 *   et non sur la fonctionnalite en cours (onglet), contrairement aux apparences
1281 *   (le passage de parametre se faisant par l'URL, celle-ci change)
1282 *   http://comments.gmane.org/gmane.comp.web.spip.devel/61824
1283 */
1284function association_bloc_filtres($liste_filtres, $exec='', $supplements='', $td=TRUE)
1285{
1286        $res = '<form method="get" action="'. ($exec?generer_url_ecrire($exec):'') .'">';
1287        if ($exec)
1288                $res .= "\n<input type='hidden' name='exec' value='$exec' />";
1289        $res .= "\n<". ($td?'table width="100%"':'ul') .' class="asso_tablo_filtres">'. ($td?'<tr>':'');
1290        foreach($liste_filtres as $filtre_selection =>$params) {
1291                $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>');
1292        }
1293        if ( is_array($supplements) ) {
1294                foreach ($supplements as $nom => $supplement) {
1295                        $res .= ($td?'<td':'<li') ." class='filtre_$nom'>$supplement</". ($td?'td>':'li>');
1296                }
1297        } else {
1298                $res .= $supplements;
1299        }
1300        $res .= ($td?'<td':'<li') . ' class="boutons"><noscript><input type="submit" value="'. _T('asso:bouton_lister') .'" /></noscript></td>' . ($td?'</td>':'</li>');
1301        return $res. ($td?'</tr></table':'</ul>') .">\n</form>\n";
1302}
1303
1304/**
1305 * Boite affichant le formulaire pour genere le PDF de la/le liste/tableau
1306 *
1307 * @param string $objet
1308 *   Nom de l'objet : il s'agit imperativement d'un objet du plugin,
1309 *   correspondant a une table avec le nom de l'objet suffixe de "s" et prefixe
1310 *   de "spip_asso" (cela exclu quand meme les tables du plugin qui n'ont pas de
1311 *   "s" final !)
1312 * @param string $params
1313 * @param string $prefixeLibelle
1314 *   Prefixe rajoute au nom du champ pour former la chaine de langue (dont le
1315 *   nommage est systematise dans "Associaspip")
1316 * @param array $champsExclus
1317 *   Liste (seules les valeurs du tableau sont prises en compte) des champs a ne
1318 *   pas prendre en compte : tous les autres champs de la table sont recuperes
1319 *   (mais seuls les champs geres par "Associaspip" et "Interface Champs Extras 2"
1320 *   seront affiches/proposes dans le formulaire, d'ou pas d'exclu par defaut)
1321 * @param bool $coords
1322 *   Indique s'il faut (vrai) prendre en compte ou pas (faux) le plugin "Coordonnees"
1323 * @return string $res
1324 *   Form HTML complet dans un cadre. Ce formulaire sera traite par l'exec de
1325 *   l'objet prefixe de "pdf_"
1326 */
1327function association_bloc_listepdf($objet, $params=array(), $prefixeLibelle='', $champsExclus=array(), $coords=true)
1328{
1329        $res = '';
1330        if (test_plugin_actif('FPDF')) { // liste
1331                $res .= debut_cadre_enfonce('',true);
1332                $res .= '<h3>'. _T('plugins_vue_liste') .'</h3>';
1333                $res .= '<div class="formulaire_spip formulaire_asso_liste_'.$objet.'s">';
1334                $champsExtras = association_trouver_iextras("asso_$objet");
1335                $frm = '<ul><li class="edit_champs">';
1336                $desc_table = charger_fonction('trouver_table', 'base'); // http://doc.spip.org/@description_table deprecier donc preferer http://programmer.spip.net/trouver_table,620
1337                $champsPresents = $desc_table("spip_asso_${objet}s");
1338                foreach ($champsPresents['field'] as $k => $v) { // donner le menu des choix
1339                        if ( !in_array($k, $champsExclus) ) { // affichable/selectionnable (champ ayant un libelle declare et connu)
1340                                $lang_clef = $prefixeLibelle.$k;
1341                                $lang_texte = _T('asso:'.$lang_clef);
1342                                if ( $lang_clef!=str_replace(' ', '_', $lang_texte) ) { // champ natif du plugin
1343                                        $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>";
1344                                } elseif( array_key_exists($k,$champsExtras) ) { // champs rajoute via cextra
1345                                        $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>";
1346                                }
1347                        }
1348                }
1349                if ($coords) {
1350                        $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)
1351                        if (test_plugin_actif('COORDONNEES')) {
1352                                $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)
1353                                $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)
1354                        }
1355                }
1356                foreach ($params as $k => $v) { // on fait suivre les autres parametres dont la liste des auteurs a afficher
1357                        $frm .= '<input type="hidden" name="'.$k.'" value="'. htmlspecialchars($v, ENT_QUOTES, $GLOBALS['meta']['charset']) .'" />'; // http://stackoverflow.com/questions/46483/htmlentities-vs-htmlspecialchars
1358                }
1359                $frm .= '</li></ul>';
1360                $frm .= '<p class="boutons"><input type="submit" value="'. _T('asso:bouton_imprimer') .'" /></p>';
1361                $res .= generer_form_ecrire("pdf_${objet}s", $frm, '', '');
1362                $res .= '</div>';
1363                $res .= fin_cadre_enfonce(true);
1364        }
1365
1366        return $res;
1367}
1368
1369/**
1370 * Listing sous forme de tableau HTML
1371 *
1372 * @param array $requete_sql
1373 *   Liste des parametres de "sql_select()"
1374 *   http://doc.spip.org/@sql_select
1375 *   http://programmer.spip.net/sql_select,569
1376 * @param array $presentation
1377 *   Tableau decrivant les donnees affichees :
1378 *   'nom_ou_alias_du_champ' => array('chaine_de:langue_du_libelle_d_entete', 'nom_du_format', 'parametre1', ...)
1379 *   Le nom du format est celui de la fonction de formatage du meme nom prefixee de association_formater_
1380 * @param array $boutons
1381 *   array('bouton', 'parametre1', ...)
1382 *   Le nom du type de bouton est celui de la fonction d'action du meme nom prefixee de association_bouton_
1383 * @param string $cle1
1384 *   Nom (ou alias) de la colonne cle primaire,
1385 * @param array $extra
1386 *   Liste de classes supplemetaires appliquees alternativement aux lignes ;
1387 *   Ou tableau des valeur=>classe supplementaires appliquees aux lignes presentant la valeur
1388 * @param string $cle2
1389 *   Nom (ou alias) de la colonne dont les valeurs servent de cle de classe
1390 * @param int $selection
1391 *   ID de la cle primaire selectionnee
1392 * @return string $res
1393 *   Table-HTML listant les donnees formatees
1394 */
1395function association_bloc_listehtml($requete_sql, $presentation, $boutons=array(), $cle1='', $extra=array(), $cle2='', $selection=0 )
1396{
1397        if ( !is_array($requete_sql) || count($requete_sql)<2 )
1398                return '';
1399        $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...
1400        $table = substr_replace(trim( is_array($table)?$table[0]:$table ), '', 0, 5); //  on supprime le prefixe "spip_" de la 1ere table (normalement la principale...)
1401        $spc_pos = strpos($table, ' '); // requete avec alias (" AS ") ou jointure de plusieurs tables ( " JOIN ")
1402        $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.
1403        $res =  '<table width="100%" class="asso_tablo" id="liste_'.$table.'">';
1404        $res .= "\n<thead>\n<tr>";
1405        foreach ($presentation as &$param) {
1406                $entete = array_shift($param);
1407                $res .= '<th>'. ($entete ? _T((strpos($entete,':') ? '' : 'asso:').$entete) : '&nbsp;' ) .'</th>';
1408        }
1409        if ( count($boutons) ) {
1410                $res .= '<th colspan="'. count($boutons) .'" class="actions">'. _T('asso:entete_actions') .'</th>';
1411        }
1412        $res .= "</tr>\n</thead><tbody>";
1413        $nbr_lignes = 0;
1414        $reponse_sql = call_user_func_array('sql_select', $requete_sql);
1415        while ($data = sql_fetch($reponse_sql)) {
1416                if ( is_array($extra) && $nbr_couleurs=count($extra) ) { // on a bien un tableau de classes supplementaires
1417                        if ( $cle2 ) { // lignes colorees selon les valeurs d'un champ
1418                                $tr_css = $extra[$data[$cle2]];
1419                        } else { // simple alternance de couleurs
1420                                $nbr_lignes++;
1421                                $tr_css = $extra[$nbr_lignes%$nbr_couleurs];
1422                        }
1423                } elseif ( $extra ) { // classe supplementaire appliquee inconditionnellement
1424                                $tr_css = $extra;
1425                }
1426                $res .= '<tr'. ($cle1?' id="'.$data[$cle1].'"':'') . ($tr_css?' class="'.$tr_css.'"':'') .'>';
1427                foreach ($presentation as $champ=>$params) {
1428                        $format = array_shift($params);
1429                        switch ($format) {
1430                                case 'date' :
1431                                case 'heure' :
1432                                        $td_css = 'date';
1433                                        break;
1434                                case 'duree' :
1435                                case 'nombre' :
1436                                case 'prix' :
1437                                        $td_css = 'decimal';
1438                                        break;
1439                                case 'entier' :
1440                                        $td_css = 'integer';
1441                                        $format = 'nombre'; $params = array(0);
1442                                        break;
1443                                case 'puce' :
1444                                case 'logo' :
1445                                        $td_css = 'image';
1446                                        break;
1447                                case 'texte' : // ajouter : propre()
1448                                default :
1449                                        $td_css = 'text';
1450                                        break;
1451                        }
1452                        if ( $data[$cle1]==$selection )
1453                                $classes .= ' surligne';
1454                        $ok = array_unshift($params,$data[$champ]);
1455                        $res .= '<td class="'.$td_css.'">'. call_user_func_array("association_formater_$format", $params) .'</td>';
1456                }
1457                foreach ($boutons as $params) {
1458                        $type = array_shift($params);
1459                        foreach ($params as &$param) {
1460                                $param = str_replace('$$', $data[$cle1], $param);
1461                        }
1462                        $res .= '<td class="action">'. call_user_func_array("association_bouton_$type", $params) .'</td>';
1463                }
1464                $res .= "</tr>\n";
1465        }
1466        return $res."</tbody>\n</table>\n";
1467}
1468
1469/** @} */
1470
1471
1472/*****************************************
1473 * @defgroup sql_asso1
1474 * Extension de l'API SQL pour Associaspip (operations qui reviennent souvent)
1475 *
1476 * @param string $table
1477 *   Le nom de l'objet : correspond a la table sans prefixe "spip_asso" et sans le "s" final
1478 * @param int $id
1479 *   ID de la ligne a recuperer
1480 * @param bool $pluriel
1481 *   Indique qu'il s'agit d'une table avec (vrai, par defaut) ou sans (faux) un
1482 *   suffixe "s". Mis a FALSE, permet de traiter le cas des tables _plan|destination|destination_op !
1483 *
1484** @{ */
1485
1486/**
1487 * Recupere dans une chaine un champ d'une table spip_asso_XXs pour un enregistrement identifie par son id_XX
1488 *
1489 * @param string $champ
1490 *   Nom du champ recherche
1491 * @return string
1492 *   Valeur du champ recherche
1493 *
1494 * @note Conversion d'anciennes fonctions :
1495 * - exercice_intitule($exo) <=> sql_asso1champ('exercice', $exo, 'intitule')
1496 * - exercice_date_debut($exercice) <=> sql_asso1champ('exercice', $exercice, 'debut')
1497 * - exercice_date_fin($exercice) <=> sql_asso1champ('exercice', $exercice, 'fin')
1498 */
1499function sql_asso1champ($table, $id, $champ, $pluriel=TRUE)
1500{
1501        return sql_getfetsel($champ, "spip_asso_$table".($pluriel?'s':''), "id_$table=".intval($id));
1502}
1503
1504/**
1505 * Recupere dans un tableau associatif un enregistrement d'une table spip_asso_XX identifie par son id_XX
1506 *
1507 * @return array
1508 *   Tableau des champs sous forme : 'nom_du_champ'=>"contenu du champ"
1509 */
1510function sql_asso1ligne($table, $id, $pluriel=TRUE)
1511{
1512        return sql_fetsel('*', "spip_asso_$table".($pluriel?'s':''), "id_$table=".intval($id));
1513}
1514
1515/** @} */
1516
1517
1518/*****************************************
1519 * @defgroup divers
1520 * Inclassables
1521 *
1522** @{ */
1523
1524/**
1525 * Cree le critere SQL Where portant sur le champ "statut_interne"
1526 *
1527 * Pour l'instant, appele uniquement dans exec/adherents.php vers la ligne 25
1528 */
1529function request_statut_interne()
1530{
1531        $statut_interne = _request('statut_interne');
1532        if (in_array($statut_interne, $GLOBALS['association_liste_des_statuts'] ))
1533                return 'statut_interne='. sql_quote($statut_interne);
1534        elseif ($statut_interne=='tous')
1535                return "statut_interne LIKE '%'";
1536        else {
1537                set_request('statut_interne', 'defaut');
1538                $a = $GLOBALS['association_liste_des_statuts'];
1539                array_shift($a);
1540                return sql_in('statut_interne', $a);
1541        }
1542}
1543
1544/**
1545 * Affichage du message indiquant la date
1546 *
1547 * @param bool $heure
1548 *   Indique s'il faut afficher (vrai) ou pas (faux, par defaut) l'heure.
1549 * @return string $res
1550 */
1551function association_date_du_jour($heure=false)
1552{
1553        $ladate = affdate_jourcourt(date('d/m/Y'));
1554        $hr = ($heure?date('H'):'');
1555        $mn = ($heure?date('i'):'');
1556        $res = '<p class="'. ($heure?'datetime':'date');
1557        $res .= '" title="'. date('Y-m-d') . ($heure?"T$hr:$mn":'');
1558        $lheure = ($heure? _T('spip:date_fmt_heures_minutes', array('h'=>$hr,'m'=>$mn)) :'');
1559        $res .= '">'.( $heure ? _T('asso:date_du_jour_heure', array('date'=>$ladate)) : _T('asso:date_du_jour',array('date'=>$ladate,'time'=>$lheure)) ).'</p>';
1560        return $res;
1561}
1562
1563/**
1564 * Injection de "association.css" dans le "header" de l'espace prive
1565 * @param string $flux
1566 * @return string $c
1567 */
1568function association_header_prive($flux)
1569{
1570        $c = direction_css(find_in_path('association.css'));
1571        return "$flux\n<link rel='stylesheet' type='text/css' href='$c' />";
1572}
1573
1574/**
1575 * Filtre pour "afficher" ou "cacher" un bloc div
1576 *
1577 * Utilise dans le formulaire cvt "editer_asso_comptes.html"
1578 *
1579 * @param string $type_operation
1580 * @param string $list_operation
1581 * @return string $res
1582 */
1583function affichage_div($type_operation, $list_operation)
1584{
1585        if(strpos($list_operation, '-')) {
1586                $operations = explode('-', $list_operation);
1587                $res = 'cachediv';
1588                for($i=0;$i<count($operations);$i++) {
1589                        $operation = $GLOBALS['association_metas']['classe_'.$operations[$i]];
1590                        if($type_operation===$operation) {
1591                                $res = '';
1592                                break;
1593                        }
1594                }
1595        } else {
1596                $res = ($type_operation===$GLOBALS['association_metas']['classe_'.$list_operation])?'':'cachediv';
1597        }
1598        return $res;
1599}
1600
1601/**
1602 * ??
1603 *
1604 * @param string $texte
1605 * @param string $avant
1606 * @param string $apres
1607 * @return string
1608 */
1609function encadre($texte,$avant='[',$apres=']')
1610{
1611    return ($texte=='')?'':$avant.$texte.$apres;
1612}
1613
1614/**
1615 * Pour construire des menu avec SELECTED
1616 *
1617 * @param string $varaut
1618 *   La valeur de l'option
1619 * @param string $variable
1620 *   La variable (passee par valeur) contenant la selection courante
1621 * @param mixed $option
1622 *   Quand cette variable est definie, indique de renvoyer un code partiel.
1623 *   Par defaut c'est le code complet de l' Option HTML qui est retourne
1624 * @return string
1625 *   Option de select HTML
1626 *
1627 * @note
1628 *   Utilise dans inc/instituer_statut_interne.php et inc/instituer_adherent.php
1629 */
1630function association_mySel($varaut, $variable, $option=NULL)
1631{
1632        if ( function_exists('mySel') ) //@ http://doc.spip.org/@mySel
1633                return mySel($varaut, $variable, $option);
1634        // la fonction mySel n'existe plus en SPIP 3 donc on la recree
1635        $res = ' value="'.$varaut.'"'. (($variable==$varaut) ? ' selected="selected"' : '');
1636        return  (!isset($option) ? $res : "<option$res>$option</option>\n");
1637}
1638
1639/**
1640 * Recupere la liste des champs extras manuellement rajoutes a un objet
1641 *
1642 * @param string $ObjetEtendu
1643 *   Nom de l'objet dont on veut recuperer les champs etendus
1644 * @param int $id
1645 *   ID de l'objet dont il veut recuperer aussi les donnees
1646 *   Par defaut : aucun (i.e. 0)
1647 * @return array $champsExtrasVoulus
1648 *   - si on ne veut pas de donnee :
1649 *     'nom_de_la_colonne'=>"Libelle du champ"
1650 *   - si on veut aussi les donnees :
1651 *     'nom_de_la_colonne'=>array( "Libelle du champ", "Donnee formatee", "Donnee brute SQL")
1652 */
1653function association_trouver_iextras($ObjetEtendu, $id=0)
1654{
1655        $champsExtrasVoulus = array();
1656        if (test_plugin_actif('IEXTRAS')) { // le plugin "Interfaces pour ChampsExtras2" est installe et active : on peut donc utiliser les methodes/fonctions natives...
1657                include_spip('inc/iextras'); // charger les fonctions de l'interface/gestionnaire (ce fichier charge les methode du core/API)
1658                if ($id)
1659                        include_spip('cextras_pipelines'); // pour eviter le "Fatal error : Call to undefined function cextras_enum()" en recuperant un fond utilisant les enum...
1660                $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.
1661                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.
1662                        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,)
1663                                $label = _TT($ChampExtraInfos['label']); // _TT est defini dans cextras_balises.php
1664                                if ( $id ) {
1665                                        $desc_table = charger_fonction('trouver_table', 'base');
1666                                        $champs = $desc_table("spip_$ChampExtraInfos[table]s");
1667                                        $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)
1668                                        $datum_parsed = recuperer_fond('extra-vues/'.$ChampExtraInfos['type'], array (
1669                                                'champ_extra' => $ChampExtraInfos['champ'],
1670                                                'label_extra' => '', // normalement : _TT($ChampExtraInfos['label']), avec la chaine vide on aura juste "<strong></strong> " a virer...
1671                                                'valeur_extra' => $ChampExtraInfos['traitement']?$ChampExtraInfos['traitement']($datum_raw):$datum_raw,
1672                                                'enum_extra' => $ChampExtraInfos['enum'], // parametre indispensable pour les champs de type "option"/"radio"/"case" http://forum.spip.net/fr_245942.html#forum245980
1673                                        )); // resultat du pipeline "affiche_contenu_objet" altere (prive du libelle du champ qui est envoye separement)
1674                                        $champsExtrasVoulus[$ChampExtraInfos['champ']] = array( $label, str_ireplace('<strong></strong>', '', $datum_parsed), $datum_raw );
1675                                } else {
1676                                        $champsExtrasVoulus[$ChampExtraInfos['champ']] = $label;
1677                                }
1678                        }
1679                }
1680        } else { // le plugin "Interfaces pour ChampsExtras2" n'est pas actif :-S Mais peut-etre a-t-il ete installe ?
1681                $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
1682                if ( !is_array($ChampsExtrasGeres) )
1683                        return array(); // fin : ChampsExtras2 non installe ou pas d'objet etendu.
1684                $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
1685                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,)
1686                        if ($ChampExtra['table']==$ObjetEtendu) // c'est un champ extra de la 'table' ou du '_type' d'objet qui nous interesse
1687                                $label = $TT($ChampExtra['label']);
1688                                if ( $id ) {
1689                                        $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)
1690                                        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.
1691                                                case 'case' : // "<select type='checkbox' .../>..."
1692                                                case 'option' : // "<select ...>...</select>"
1693                                                case 'radio' : // "<select type='radio' .../>..."
1694                                                        $valeurs = array();
1695                                                        $enum = explode("\r\n", $ChampExtra['enum']);
1696                                                        foreach ($enum as $pair) {
1697                                                                list($key, $value) = explode(',', $pair, 1);
1698                                                                $valeurs[$key] = $value;
1699                                                        }
1700                                                        $datum_parsed = $ChampExtra['traitement']?$ChampExtra['traitement']($valeurs[$datum_raw]):$valeurs[$datum_raw];
1701                                                        break;
1702                                                case 'oui_non' :
1703                                                        $datum_parsed = _T("item:$datum_raw");
1704                                                        break;
1705//                                              case 'asso_activite' :
1706                                                case 'asso_categorie' :
1707                                                case 'asso_compte' :
1708//                                              case 'asso_don' :
1709                                                case 'asso_exercice' :
1710                                                case 'asso_membre' :
1711                                                case 'asso_ressource' :
1712//                                              case 'asso_vente' :
1713                                                        $raccourci = substr($ChampExtra['type'], 4); // on vire le prefixe "asso_"
1714                                                        if ( $ChampExtra['traitement'] )
1715                                                                $datum_parsed = $ChampExtra['traitement']('[->'.$raccourci.$datum_raw.']');
1716                                                        else { // il faut une requete de plus
1717                                                                switch ($raccourci) { // $valeur prend ici le champ SQL contenant la valeur desiree.
1718//                                                                      case 'activite' :
1719                                                                        case 'categorie' :
1720                                                                                $valeur = 'libelle';
1721                                                                                break;
1722                                                                        case 'compte' :
1723                                                                                $valeur = 'justification';
1724                                                                                break;
1725//                                                                      case 'don' :
1726                                                                        case 'exercice' :
1727                                                                                $valeur = 'intitule';
1728                                                                                break;
1729                                                                        case 'membre' :
1730                                                                                $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
1731                                                                                break;
1732                                                                        case 'ressource' :
1733                                                                                $valeur = 'intitule';
1734                                                                                break;
1735//                                                                      case 'vente' :
1736                                                                        default :
1737                                                                                $valeur = 'titre'; // sauf coincidence heurese, on devrait avoir une erreur...
1738                                                                                break;
1739                                                                }
1740                                                                $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)
1741                                                        }
1742                                                        break;
1743                                                case 'article' :
1744                                                case 'auteur' :
1745                                                case 'breve' :
1746                                                case 'document' :
1747                                                case 'evenement' :
1748                                                case 'rubrique' :
1749                                                case 'site' :
1750                                                        if ( $ChampExtra['traitement'] )
1751                                                                $datum_parsed = $ChampExtra['traitement']('[->'.$ChampExtra['type'].$datum_raw.']');
1752                                                        else { // il faut une requete de plus
1753                                                                $datum_parsed = sql_getfetsel($ChampExtra['type']=='auteur'?'nom':'titre', "spip_$ChampExtra[type]s", "id_$ChampExtra[type]=".intval($datum_raw) );
1754                                                        }
1755                                                        break;
1756                                                case 'auteurs' :
1757                                                        if ( $ChampExtra['traitement'] ) {
1758                                                                $valeurs = explode($datum_raw, ',');
1759                                                                foreach ($valeurs as $rang=>$valeur)
1760                                                                        $valeurs[$rang] = '[->auteur'.$valeurs[$rang].']';
1761                                                                $datum_parsed = implode(';', $valeurs);
1762                                                        } else { // il faut une requete de plus
1763                                                                $valeurs = sql_fetchall('nom', "spip_auteurs", "id_auteur IN (".sql_quote($datum_raw).')' );
1764                                                                $datum_parsed = implode(';', $valeurs);
1765                                                        }
1766                                                        break;
1767                                                case 'bloc' : // "<textarea...>...</textarea>"
1768                                                case 'ligne' : // "<input type='text' .../>"
1769                                                default :
1770                                                        $ChampExtra['traitement']?$ChampExtra['traitement']($datum_raw):$datum_raw;
1771                                        }
1772                                        $champsExtrasVoulus[$ChampExtra['champ']] = array( $label, $print, $datum );
1773                                } else {
1774                                        $champsExtrasVoulus[$ChampExtra['champ']] = $label;
1775                                }
1776                }
1777        }
1778        return $champsExtrasVoulus;
1779}
1780
1781/** @} */
1782
1783
1784// pour executer les squelettes comportant la balise Meta
1785include_spip('balise/meta');
1786
1787// charger les metas donnees
1788$inc_meta = charger_fonction('meta', 'inc'); // inc_version l'a deja chargee
1789$inc_meta('association_metas');
1790
1791// pouvoir utiliser les fonctions de coordonnees comme filtre
1792if (test_plugin_actif('COORDONNEES')) {
1793        include_spip('inc/association_coordonnees');
1794}
1795
1796
1797?>
Note: See TracBrowser for help on using the repository browser.