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

Last change on this file since 112310 was 112310, checked in by maieul@…, 2 years ago

saisies_lister_avec_type() peut prendre un tableau de type plutôt qu'un seul type

File size: 13.7 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}
Note: See TracBrowser for help on using the repository browser.