source: spip-zone/_plugins_/saisies/trunk/inc/saisies_lister.php @ 113849

Last change on this file since 113849 was 113849, checked in by root, 3 months ago

Nouvelle fonction saisies_saisie_est_tabulaire() qui permet de savoir si
la saisie renvoie un tableau ou pas. Utilisée notamment dans les
traitement de formidable pour gérer le cas d'envoi vide de saisie,
lorsqu'il faut effacer la précédente valeur.

Un pipeline permet d'ajouter ses propres saisies.

File size: 15.0 KB
Line 
1<?php
2
3/**
4 * Gestion de listes des saisies.
5 *
6 * @return SPIP\Saisies\Listes
7 **/
8
9// Sécurité
10if (!defined('_ECRIRE_INC_VERSION')) {
11        return;
12}
13
14/**
15 * Prend la description complète du contenu d'un formulaire et retourne
16 * les saisies "à plat" classées par identifiant unique.
17 *
18 * @param array $contenu        Le contenu d'un formulaire
19 * @param bool  $avec_conteneur Indique si on renvoie aussi les saisies ayant des enfants, comme les fieldsets
20 *
21 * @return array Un tableau avec uniquement les saisies
22 */
23function saisies_lister_par_identifiant($contenu, $avec_conteneur = true) {
24        $saisies = array();
25
26        if (is_array($contenu)) {
27                foreach ($contenu as $ligne) {
28                        if (is_array($ligne)) {
29                                $enfants_presents = (isset($ligne['saisies']) and is_array($ligne['saisies']));
30                                if (array_key_exists('saisie', $ligne) and (!$enfants_presents or $avec_conteneur)) {
31                                        $saisies[$ligne['identifiant']] = $ligne;
32                                }
33                                if ($enfants_presents) {
34                                        $saisies = array_merge($saisies, saisies_lister_par_identifiant($ligne['saisies']));
35                                }
36                        }
37                }
38        }
39
40        return $saisies;
41}
42
43/**
44 * Prend la description complète du contenu d'un formulaire et retourne
45 * les saisies "à plat" classées par nom.
46 *
47 * @param array $contenu        Le contenu d'un formulaire
48 * @param bool  $avec_conteneur Indique si on renvoie aussi les saisies ayant des enfants, comme les fieldset
49 *
50 * @return array Un tableau avec uniquement les saisies
51 */
52function saisies_lister_par_nom($contenu, $avec_conteneur = true) {
53        $saisies = array();
54
55        if (is_array($contenu)) {
56                foreach ($contenu as $ligne) {
57                        if (is_array($ligne)) {
58                                if (
59                                        array_key_exists('saisie', $ligne)
60                                        and (!isset($ligne['saisies']) or !is_array($ligne['saisies']) or $avec_conteneur)
61                                        and isset($ligne['options'])
62                                ) {
63                                        $saisies[$ligne['options']['nom']] = $ligne;
64                                }
65                                if (isset($ligne['saisies']) and is_array($ligne['saisies'])) {
66                                        $saisies = array_merge($saisies, saisies_lister_par_nom($ligne['saisies']));
67                                }
68                        }
69                }
70        }
71
72        return $saisies;
73}
74
75/**
76 * Liste les saisies ayant une option X
77 * # saisies_lister_avec_option('sql', $saisies);.
78 *
79 *
80 * @param string $option  Nom de l'option cherchée
81 * @param array  $saisies Liste de saisies
82 * @param string $tri     tri par défaut des résultats (s'ils ne sont pas deja triés) ('nom', 'identifiant')
83 *
84 * @return liste de ces saisies triees par nom ayant une option X définie
85 */
86function saisies_lister_avec_option($option, $saisies, $tri = 'nom') {
87        $saisies_option = array();
88
89        // tri par nom si ce n'est pas le cas
90        $s = array_keys($saisies);
91        if (is_int(array_shift($s))) {
92                $trier = 'saisies_lister_par_'.$tri;
93                $saisies = $trier($saisies);
94        }
95
96        foreach ($saisies as $nom_ou_id => $saisie) {
97                if (isset($saisie['options'][$option]) and $saisie['options'][$option]) {
98                        $saisies_option[$nom_ou_id] = $saisie;
99                }
100        }
101
102        return $saisies_option;
103}
104
105/**
106 * Liste les saisies ayant une definition SQL.
107 *
108 * @param array  $saisies liste de saisies
109 * @param string $tri     tri par défaut des résultats (s'ils ne sont pas deja triés) ('nom', 'identifiant')
110 *
111 * @return liste de ces saisies triees par nom ayant une option sql définie
112 */
113function saisies_lister_avec_sql($saisies, $tri = 'nom') {
114        return saisies_lister_avec_option('sql', $saisies, $tri);
115}
116
117/**
118 * Liste les saisies d'un certain type.
119 *
120 * @example `$saisies_date = saisies_lister_avec_type($saisies, 'date')`
121 *
122 * @param array  $saisies liste de saisies
123 * @param string|array $type    Type de la saisie, ou tableau de types
124 * @param string $tri     tri par défaut des résultats (s'ils ne sont pas deja triés) ('nom')
125 *
126 * @return liste de ces saisies triees par nom
127 */
128function saisies_lister_avec_type($saisies, $type, $tri = 'nom') {
129        if (!is_array($type)) {
130                $type = array($type);
131        }
132        $saisies_type = array();
133
134        // tri par nom si ce n'est pas le cas
135        $s = array_keys($saisies);
136        if (is_int(array_shift($s))) {
137                $trier = 'saisies_lister_par_'.$tri;
138                $saisies = $trier($saisies);
139        }
140
141        foreach ($saisies as $nom_ou_id => $saisie) {
142                if (in_array($saisie['saisie'], $type)) {
143                        $saisies_type[$nom_ou_id] = $saisie;
144                }
145        }
146        return $saisies_type;
147}
148
149/**
150 * Prend la description complète du contenu d'un formulaire et retourne
151 * les saisies "à plat" classées par type de saisie.
152 * $saisie['input']['input_1'] = $saisie.
153 *
154 * @param array $contenu Le contenu d'un formulaire
155 *
156 * @return array Un tableau avec uniquement les saisies
157 */
158function saisies_lister_par_type($contenu) {
159        $saisies = array();
160
161        if (is_array($contenu)) {
162                foreach ($contenu as $ligne) {
163                        if (is_array($ligne)) {
164                                if (array_key_exists('saisie', $ligne) and (!is_array($ligne['saisies']))) {
165                                        $saisies[ $ligne['saisie'] ][ $ligne['options']['nom'] ] = $ligne;
166                                }
167                                if (is_array($ligne['saisies'])) {
168                                        $saisies = array_merge_recursive($saisies, saisies_lister_par_type($ligne['saisies']));
169                                }
170                        }
171                }
172        }
173
174        return $saisies;
175}
176
177/**
178 * Prend la description complète du contenu d'un formulaire et retourne
179 * une liste des noms des champs du formulaire.
180 *
181 * @param array $contenu        Le contenu d'un formulaire
182 * @param bool  $avec_conteneur Indique si on renvoie aussi les saisies ayant des enfants, comme les fieldset
183 *
184 * @return array Un tableau listant les noms des champs
185 */
186function saisies_lister_champs($contenu, $avec_conteneur = true) {
187        $saisies = saisies_lister_par_nom($contenu, $avec_conteneur);
188
189        return array_keys($saisies);
190}
191
192/**
193 * Prend la description complète du contenu d'un formulaire et retourne
194 * une liste des labels humains des vrais champs du formulaire (par nom)
195 *
196 * @param array $contenu        Le contenu d'un formulaire
197 * @param bool  $avec_conteneur Indique si on renvoie aussi les saisies ayant des enfants, comme les fieldset
198 *
199 * @return array Un tableau listant les labels humains des champs
200 */
201function saisies_lister_labels($contenu, $avec_conteneur = false) {
202        $saisies = saisies_lister_par_nom($contenu, $avec_conteneur);
203
204        $labels = array();
205        foreach ($saisies as $nom => $saisie) {
206                if (isset($saisie['options']['label'])) {
207                        $labels[$nom] = $saisie['options']['label'];
208                }
209        }
210
211        return $labels;
212}
213
214/**
215 * A utiliser dans une fonction charger d'un formulaire CVT,
216 * cette fonction renvoie le tableau de contexte correspondant
217 * de la forme $contexte['nom_champ'] = ''.
218 *
219 * @param array $contenu Le contenu d'un formulaire (un tableau de saisies)
220 *
221 * @return array Un tableau de contexte
222 */
223function saisies_charger_champs($contenu) {
224        if (function_exists('array_fill_keys')) { // php 5.2
225                return array_fill_keys(saisies_lister_champs($contenu, false), null);
226        }
227        $champs = array();
228        foreach (saisies_lister_champs($contenu, false) as $champ) {
229                $champs[$champ] = null;
230        }
231
232        return $champs;
233}
234
235/**
236 * Prend la description complète du contenu d'un formulaire et retourne
237 * une liste des valeurs par défaut des champs du formulaire.
238 *
239 * @param array $contenu Le contenu d'un formulaire
240 *
241 * @return array Un tableau renvoyant la valeur par défaut de chaque champs
242 */
243function saisies_lister_valeurs_defaut($contenu) {
244        $contenu = saisies_lister_par_nom($contenu, false);
245        $defauts = array();
246
247        foreach ($contenu as $nom => $saisie) {
248                // Si le nom du champ est un tableau indexé, il faut parser !
249                if (preg_match('/([\w]+)((\[[\w]+\])+)/', $nom, $separe)) {
250                        $nom = $separe[1];
251                        // Dans ce cas on ne récupère que le nom,
252                        // la valeur par défaut du tableau devra être renseigné autre part
253                        $defauts[$nom] = array();
254                }
255                else {
256                        $defauts[$nom] = isset($saisie['options']['defaut']) ? $saisie['options']['defaut'] : '';
257                }
258        }
259
260        return $defauts;
261}
262
263/**
264 * Compare deux tableaux de saisies pour connaitre les différences.
265 *
266 * @param array  $saisies_anciennes Un tableau décrivant des saisies
267 * @param array  $saisies_nouvelles Un autre tableau décrivant des saisies
268 * @param bool   $avec_conteneur    Indique si on veut prendre en compte dans la comparaison les conteneurs comme les fieldsets
269 * @param string $tri               Comparer selon quel tri ? 'nom' / 'identifiant'
270 *
271 * @return array Retourne le tableau des saisies supprimées, ajoutées et modifiées
272 */
273function saisies_comparer($saisies_anciennes, $saisies_nouvelles, $avec_conteneur = true, $tri = 'nom') {
274        $trier = "saisies_lister_par_$tri";
275        $saisies_anciennes = $trier($saisies_anciennes, $avec_conteneur);
276        $saisies_nouvelles = $trier($saisies_nouvelles, $avec_conteneur);
277
278        // Les saisies supprimées sont celles qui restent dans les anciennes quand on a enlevé toutes les nouvelles
279        $saisies_supprimees = array_diff_key($saisies_anciennes, $saisies_nouvelles);
280        // Les saisies ajoutées, c'est le contraire
281        $saisies_ajoutees = array_diff_key($saisies_nouvelles, $saisies_anciennes);
282        // Il reste alors les saisies qui ont le même nom
283        $saisies_restantes = array_intersect_key($saisies_anciennes, $saisies_nouvelles);
284        // Dans celles-ci, celles qui sont modifiées sont celles dont la valeurs est différentes
285        $saisies_modifiees = array_udiff(array_diff_key($saisies_nouvelles, $saisies_ajoutees), $saisies_restantes, 'saisies_comparer_rappel');
286        #$saisies_modifiees = array_udiff($saisies_nouvelles, $saisies_restantes, 'saisies_comparer_rappel');
287        // Et enfin les saisies qui ont le même nom et la même valeur
288        $saisies_identiques = array_diff_key($saisies_restantes, $saisies_modifiees);
289
290        return array(
291                'supprimees' => $saisies_supprimees,
292                'ajoutees' => $saisies_ajoutees,
293                'modifiees' => $saisies_modifiees,
294                'identiques' => $saisies_identiques,
295        );
296}
297
298/**
299 * Compare deux saisies et indique si elles sont égales ou pas.
300 *
301 * @param array $a Une description de saisie
302 * @param array $b Une autre description de saisie
303 *
304 * @return int Retourne 0 si les saisies sont identiques, 1 sinon.
305 */
306function saisies_comparer_rappel($a, $b) {
307        if ($a === $b) {
308                return 0;
309        } else {
310                return 1;
311        }
312}
313
314/**
315 * Compare deux tableaux de saisies pour connaitre les différences
316 * en s'appuyant sur les identifiants de saisies.
317 *
318 * @see saisies_comparer()
319 *
320 * @param array $saisies_anciennes Un tableau décrivant des saisies
321 * @param array $saisies_nouvelles Un autre tableau décrivant des saisies
322 * @param bool  $avec_conteneur    Indique si on veut prendre en compte dans la comparaison
323 *                                 les conteneurs comme les fieldsets
324 *
325 * @return array Retourne le tableau des saisies supprimées, ajoutées et modifiées
326 */
327function saisies_comparer_par_identifiant($saisies_anciennes, $saisies_nouvelles, $avec_conteneur = true) {
328        return saisies_comparer($saisies_anciennes, $saisies_nouvelles, $avec_conteneur, 'identifiant');
329}
330
331/**
332 * Liste toutes les saisies configurables (ayant une description).
333 *
334 * @return array Un tableau listant des saisies et leurs options
335 */
336function saisies_lister_disponibles($saisies_repertoire = 'saisies') {
337        static $saisies = null;
338
339        if (is_null($saisies)) {
340                $saisies = array();
341                $liste = find_all_in_path("$saisies_repertoire/", '.+[.]yaml$');
342
343                if (count($liste)) {
344                        foreach ($liste as $fichier => $chemin) {
345                                $type_saisie = preg_replace(',[.]yaml$,i', '', $fichier);
346                                $dossier = str_replace($fichier, '', $chemin);
347
348                                // On ne garde que les saisies qui ont bien le HTML avec !
349                                if (
350                                        file_exists("$dossier$type_saisie.html")
351                                        and (
352                                                is_array($saisie = saisies_charger_infos($type_saisie))
353                                        )
354                                ) {
355                                        $saisies[$type_saisie] = $saisie;
356                                }
357                        }
358                }
359        }
360
361        return $saisies;
362}
363
364/**
365 * Liste tous les groupes de saisies configurables (ayant une description).
366 *
367 * @return array Un tableau listant des saisies et leurs options
368 */
369function saisies_groupes_lister_disponibles($saisies_repertoire = 'saisies') {
370        static $saisies = null;
371
372        if (is_null($saisies)) {
373                $saisies = array();
374                $liste = find_all_in_path("$saisies_repertoire/", '.+[.]yaml$');
375
376                if (count($liste)) {
377                        foreach ($liste as $fichier => $chemin) {
378                                $type_saisie = preg_replace(',[.]yaml$,i', '', $fichier);
379                                $dossier = str_replace($fichier, '', $chemin);
380
381                                if (is_array($saisie = saisies_charger_infos($type_saisie, $saisies_repertoire))) {
382                                        $saisies[$type_saisie] = $saisie;
383                                }
384                        }
385                }
386        }
387
388        return $saisies;
389}
390
391/**
392 * Lister les saisies existantes ayant une définition SQL.
393 *
394 * @return array Un tableau listant des saisies et leurs options
395 */
396function saisies_lister_disponibles_sql($saisies_repertoire = 'saisies') {
397        $saisies = array();
398        $saisies_disponibles = saisies_lister_disponibles($saisies_repertoire);
399
400        foreach ($saisies_disponibles as $type => $saisie) {
401                if (isset($saisie['defaut']['options']['sql']) and $saisie['defaut']['options']['sql']) {
402                        $saisies[$type] = $saisie;
403                }
404        }
405
406        return $saisies;
407}
408
409/**
410 * Charger les informations contenues dans le YAML d'une saisie.
411 *
412 * @param string $type_saisie Le type de la saisie
413 *
414 * @return array Un tableau contenant le YAML décodé
415 */
416function saisies_charger_infos($type_saisie, $saisies_repertoire = 'saisies') {
417        if (defined('_DIR_PLUGIN_YAML')) {
418                include_spip('inc/yaml');
419                $fichier = find_in_path("$saisies_repertoire/$type_saisie.yaml");
420                $saisie = yaml_decode_file($fichier);
421
422                if (is_array($saisie)) {
423                        $saisie['titre'] = (isset($saisie['titre']) and $saisie['titre'])
424                                ? _T_ou_typo($saisie['titre']) : $type_saisie;
425                        $saisie['description'] = (isset($saisie['description']) and $saisie['description'])
426                                ? _T_ou_typo($saisie['description']) : '';
427                        $saisie['icone'] = (isset($saisie['icone']) and $saisie['icone'])
428                                ? find_in_path($saisie['icone']) : '';
429                }
430        }
431        else {
432                $saisie = array();
433        }
434
435        return $saisie;
436}
437
438/**
439 * Quelles sont les saisies qui se débrouillent toutes seules, sans le _base commun.
440 *
441 * @return array Retourne un tableau contenant les types de saisies qui ne doivent pas utiliser le _base.html commun
442 */
443function saisies_autonomes() {
444        $saisies_autonomes = pipeline(
445                'saisies_autonomes',
446                array(
447                        'fieldset',
448                        'hidden',
449                        'destinataires',
450                        'explication',
451                )
452        );
453
454        return $saisies_autonomes;
455}
456
457/**
458 * La saisie renvoie t-elle un tableau?
459 * note: on teste saisie par saisie, et non pas type de saisie par type de saisie, car certaine type (Evenements par ex) peut, en fonction des options, être tabulaire ou pas.
460 * @param $saisie
461 * @return return bool true si la saisie est tabulaire, false sinon
462**/
463function saisies_saisie_est_tabulaire($saisie) {
464        if (in_array($saisie['saisie'], array('checkbox', 'selection_multiple'))) {
465                $est_tabulaire = true;
466        } else {
467                $est_tabulaire =  false;
468        }
469        return pipeline('saisie_est_tabulaire',
470                array('args' => $saisie, 'data' => $est_tabulaire)
471        );
472}
473
474/**
475 * Indique si une saisie à sa valeur gelée
476 * - soit par option disabled avec envoi cachée
477 * - soit par option readonly
478 * @param array $description description de la saisie
479 * @return bool true si gélée, false sinon)
480**/
481function saisies_verifier_gel_saisie($description) {
482        $options = $description['options'];
483        //As t-on bloqué d'une manière ou d'une autre la valeur postée?
484        if ((
485                isset($options['readonly'])
486                and $options['readonly']
487        )
488        or (
489                isset($options['disable'])
490                and isset($options['disable_avec_post'])
491                and $options['disable']
492                and $options['disable_avec_post']
493        )
494        ) {
495                return true;
496        } else {
497                return false;
498        }
499}
Note: See TracBrowser for help on using the repository browser.