[CSS] +fix page header and title color
[lhc/web/www.git] / www / plugins / saisies / inc / saisies_lister.php
1 <?php
2
3 /**
4 * Gestion de listes des saisies.
5 *
6 * @return SPIP\Saisies\Listes
7 **/
8
9 // Sécurité
10 if (!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 */
23 function 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 */
52 function 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 */
86 function 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 */
113 function 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 $type Type de la saisie
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 */
128 function saisies_lister_avec_type($saisies, $type, $tri = 'nom') {
129 $saisies_type = array();
130
131 // tri par nom si ce n'est pas le cas
132 $s = array_keys($saisies);
133 if (is_int(array_shift($s))) {
134 $trier = 'saisies_lister_par_'.$tri;
135 $saisies = $trier($saisies);
136 }
137
138 foreach ($saisies as $nom_ou_id => $saisie) {
139 if ($saisie['saisie'] == $type) {
140 $saisies_type[$nom_ou_id] = $saisie;
141 }
142 }
143
144 return $saisies_type;
145 }
146
147 /**
148 * Prend la description complète du contenu d'un formulaire et retourne
149 * les saisies "à plat" classées par type de saisie.
150 * $saisie['input']['input_1'] = $saisie.
151 *
152 * @param array $contenu Le contenu d'un formulaire
153 *
154 * @return array Un tableau avec uniquement les saisies
155 */
156 function saisies_lister_par_type($contenu) {
157 $saisies = array();
158
159 if (is_array($contenu)) {
160 foreach ($contenu as $ligne) {
161 if (is_array($ligne)) {
162 if (array_key_exists('saisie', $ligne) and (!is_array($ligne['saisies']))) {
163 $saisies[ $ligne['saisie'] ][ $ligne['options']['nom'] ] = $ligne;
164 }
165 if (is_array($ligne['saisies'])) {
166 $saisies = array_merge_recursive($saisies, saisies_lister_par_type($ligne['saisies']));
167 }
168 }
169 }
170 }
171
172 return $saisies;
173 }
174
175 /**
176 * Prend la description complète du contenu d'un formulaire et retourne
177 * une liste des noms des champs du formulaire.
178 *
179 * @param array $contenu Le contenu d'un formulaire
180 * @param bool $avec_conteneur Indique si on renvoie aussi les saisies ayant des enfants, comme les fieldset
181 *
182 * @return array Un tableau listant les noms des champs
183 */
184 function saisies_lister_champs($contenu, $avec_conteneur = true) {
185 $saisies = saisies_lister_par_nom($contenu, $avec_conteneur);
186
187 return array_keys($saisies);
188 }
189
190 /**
191 * A utiliser dans une fonction charger d'un formulaire CVT,
192 * cette fonction renvoie le tableau de contexte correspondant
193 * de la forme $contexte['nom_champ'] = ''.
194 *
195 * @param array $contenu Le contenu d'un formulaire (un tableau de saisies)
196 *
197 * @return array Un tableau de contexte
198 */
199 function saisies_charger_champs($contenu) {
200 // array_fill_keys est disponible uniquement avec PHP >= 5.2.0
201 // return array_fill_keys(saisies_lister_champs($contenu, false), '');
202 $champs = array();
203 foreach (saisies_lister_champs($contenu, false) as $champ) {
204 $champs[$champ] = '';
205 }
206
207 return $champs;
208 }
209
210 /**
211 * Prend la description complète du contenu d'un formulaire et retourne
212 * une liste des valeurs par défaut des champs du formulaire.
213 *
214 * @param array $contenu Le contenu d'un formulaire
215 *
216 * @return array Un tableau renvoyant la valeur par défaut de chaque champs
217 */
218 function saisies_lister_valeurs_defaut($contenu) {
219 $contenu = saisies_lister_par_nom($contenu, false);
220 $defauts = array();
221
222 foreach ($contenu as $nom => $saisie) {
223 // Si le nom du champ est un tableau indexé, il faut parser !
224 if (preg_match('/([\w]+)((\[[\w]+\])+)/', $nom, $separe)) {
225 $nom = $separe[1];
226 // Dans ce cas on ne récupère que le nom,
227 // la valeur par défaut du tableau devra être renseigné autre part
228 $defauts[$nom] = array();
229 }
230 else {
231 $defauts[$nom] = isset($saisie['options']['defaut']) ? $saisie['options']['defaut'] : '';
232 }
233 }
234
235 return $defauts;
236 }
237
238 /**
239 * Compare deux tableaux de saisies pour connaitre les différences.
240 *
241 * @param array $saisies_anciennes Un tableau décrivant des saisies
242 * @param array $saisies_nouvelles Un autre tableau décrivant des saisies
243 * @param bool $avec_conteneur Indique si on veut prendre en compte dans la comparaison les conteneurs comme les fieldsets
244 * @param string $tri Comparer selon quel tri ? 'nom' / 'identifiant'
245 *
246 * @return array Retourne le tableau des saisies supprimées, ajoutées et modifiées
247 */
248 function saisies_comparer($saisies_anciennes, $saisies_nouvelles, $avec_conteneur = true, $tri = 'nom') {
249 $trier = "saisies_lister_par_$tri";
250 $saisies_anciennes = $trier($saisies_anciennes, $avec_conteneur);
251 $saisies_nouvelles = $trier($saisies_nouvelles, $avec_conteneur);
252
253 // Les saisies supprimées sont celles qui restent dans les anciennes quand on a enlevé toutes les nouvelles
254 $saisies_supprimees = array_diff_key($saisies_anciennes, $saisies_nouvelles);
255 // Les saisies ajoutées, c'est le contraire
256 $saisies_ajoutees = array_diff_key($saisies_nouvelles, $saisies_anciennes);
257 // Il reste alors les saisies qui ont le même nom
258 $saisies_restantes = array_intersect_key($saisies_anciennes, $saisies_nouvelles);
259 // Dans celles-ci, celles qui sont modifiées sont celles dont la valeurs est différentes
260 $saisies_modifiees = array_udiff(array_diff_key($saisies_nouvelles, $saisies_ajoutees), $saisies_restantes, 'saisies_comparer_rappel');
261 #$saisies_modifiees = array_udiff($saisies_nouvelles, $saisies_restantes, 'saisies_comparer_rappel');
262 // Et enfin les saisies qui ont le même nom et la même valeur
263 $saisies_identiques = array_diff_key($saisies_restantes, $saisies_modifiees);
264
265 return array(
266 'supprimees' => $saisies_supprimees,
267 'ajoutees' => $saisies_ajoutees,
268 'modifiees' => $saisies_modifiees,
269 'identiques' => $saisies_identiques,
270 );
271 }
272
273 /**
274 * Compare deux saisies et indique si elles sont égales ou pas.
275 *
276 * @param array $a Une description de saisie
277 * @param array $b Une autre description de saisie
278 *
279 * @return int Retourne 0 si les saisies sont identiques, 1 sinon.
280 */
281 function saisies_comparer_rappel($a, $b) {
282 if ($a === $b) {
283 return 0;
284 } else {
285 return 1;
286 }
287 }
288
289 /**
290 * Compare deux tableaux de saisies pour connaitre les différences
291 * en s'appuyant sur les identifiants de saisies.
292 *
293 * @see saisies_comparer()
294 *
295 * @param array $saisies_anciennes Un tableau décrivant des saisies
296 * @param array $saisies_nouvelles Un autre tableau décrivant des saisies
297 * @param bool $avec_conteneur Indique si on veut prendre en compte dans la comparaison
298 * les conteneurs comme les fieldsets
299 *
300 * @return array Retourne le tableau des saisies supprimées, ajoutées et modifiées
301 */
302 function saisies_comparer_par_identifiant($saisies_anciennes, $saisies_nouvelles, $avec_conteneur = true) {
303 return saisies_comparer($saisies_anciennes, $saisies_nouvelles, $avec_conteneur, 'identifiant');
304 }
305
306 /**
307 * Liste toutes les saisies configurables (ayant une description).
308 *
309 * @return array Un tableau listant des saisies et leurs options
310 */
311 function saisies_lister_disponibles($saisies_repertoire = 'saisies') {
312 static $saisies = null;
313
314 if (is_null($saisies)) {
315 $saisies = array();
316 $liste = find_all_in_path("$saisies_repertoire/", '.+[.]yaml$');
317
318 if (count($liste)) {
319 foreach ($liste as $fichier => $chemin) {
320 $type_saisie = preg_replace(',[.]yaml$,i', '', $fichier);
321 $dossier = str_replace($fichier, '', $chemin);
322
323 // On ne garde que les saisies qui ont bien le HTML avec !
324 if (
325 file_exists("$dossier$type_saisie.html")
326 and (
327 is_array($saisie = saisies_charger_infos($type_saisie))
328 )
329 ) {
330 $saisies[$type_saisie] = $saisie;
331 }
332 }
333 }
334 }
335
336 return $saisies;
337 }
338
339 /**
340 * Liste tous les groupes de saisies configurables (ayant une description).
341 *
342 * @return array Un tableau listant des saisies et leurs options
343 */
344 function saisies_groupes_lister_disponibles($saisies_repertoire = 'saisies') {
345 static $saisies = null;
346
347 if (is_null($saisies)) {
348 $saisies = array();
349 $liste = find_all_in_path("$saisies_repertoire/", '.+[.]yaml$');
350
351 if (count($liste)) {
352 foreach ($liste as $fichier => $chemin) {
353 $type_saisie = preg_replace(',[.]yaml$,i', '', $fichier);
354 $dossier = str_replace($fichier, '', $chemin);
355
356 if (is_array($saisie = saisies_charger_infos($type_saisie, $saisies_repertoire))) {
357 $saisies[$type_saisie] = $saisie;
358 }
359 }
360 }
361 }
362
363 return $saisies;
364 }
365
366 /**
367 * Lister les saisies existantes ayant une définition SQL.
368 *
369 * @return array Un tableau listant des saisies et leurs options
370 */
371 function saisies_lister_disponibles_sql($saisies_repertoire = 'saisies') {
372 $saisies = array();
373 $saisies_disponibles = saisies_lister_disponibles($saisies_repertoire);
374
375 foreach ($saisies_disponibles as $type => $saisie) {
376 if (isset($saisie['defaut']['options']['sql']) and $saisie['defaut']['options']['sql']) {
377 $saisies[$type] = $saisie;
378 }
379 }
380
381 return $saisies;
382 }
383
384 /**
385 * Charger les informations contenues dans le YAML d'une saisie.
386 *
387 * @param string $type_saisie Le type de la saisie
388 *
389 * @return array Un tableau contenant le YAML décodé
390 */
391 function saisies_charger_infos($type_saisie, $saisies_repertoire = 'saisies') {
392 if (defined('_DIR_PLUGIN_YAML')) {
393 include_spip('inc/yaml');
394 $fichier = find_in_path("$saisies_repertoire/$type_saisie.yaml");
395 $saisie = yaml_decode_file($fichier);
396
397 if (is_array($saisie)) {
398 $saisie['titre'] = (isset($saisie['titre']) and $saisie['titre'])
399 ? _T_ou_typo($saisie['titre']) : $type_saisie;
400 $saisie['description'] = (isset($saisie['description']) and $saisie['description'])
401 ? _T_ou_typo($saisie['description']) : '';
402 $saisie['icone'] = (isset($saisie['icone']) and $saisie['icone'])
403 ? find_in_path($saisie['icone']) : '';
404 }
405 }
406 else {
407 $saisie = array();
408 }
409
410 return $saisie;
411 }
412
413 /**
414 * Quelles sont les saisies qui se débrouillent toutes seules, sans le _base commun.
415 *
416 * @return array Retourne un tableau contenant les types de saisies qui ne doivent pas utiliser le _base.html commun
417 */
418 function saisies_autonomes() {
419 $saisies_autonomes = pipeline(
420 'saisies_autonomes',
421 array(
422 'fieldset',
423 'hidden',
424 'destinataires',
425 'explication',
426 )
427 );
428
429 return $saisies_autonomes;
430 }