[PLUGINS] ~maj globale
[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 (array_key_exists('saisie', $ligne) and (!isset($ligne['saisies']) or !is_array($ligne['saisies']) or $avec_conteneur) and isset($ligne['options'])) {
59 $saisies[$ligne['options']['nom']] = $ligne;
60 }
61 if (isset($ligne['saisies']) and is_array($ligne['saisies'])) {
62 $saisies = array_merge($saisies, saisies_lister_par_nom($ligne['saisies']));
63 }
64 }
65 }
66 }
67
68 return $saisies;
69 }
70
71 /**
72 * Liste les saisies ayant une option X
73 * # saisies_lister_avec_option('sql', $saisies);.
74 *
75 *
76 * @param String $option Nom de l'option cherchée
77 * @param Array $saisies Liste de saisies
78 * @param String $tri tri par défaut des résultats (s'ils ne sont pas deja triés) ('nom', 'identifiant')
79 *
80 * @return liste de ces saisies triees par nom ayant une option X définie
81 */
82 function saisies_lister_avec_option($option, $saisies, $tri = 'nom') {
83 $saisies_option = array();
84 // tri par nom si ce n'est pas le cas
85 $s = array_keys($saisies);
86 if (is_int(array_shift($s))) {
87 $trier = 'saisies_lister_par_'.$tri;
88 $saisies = $trier($saisies);
89 }
90 foreach ($saisies as $nom_ou_id => $saisie) {
91 if (isset($saisie['options'][$option]) and $saisie['options'][$option]) {
92 $saisies_option[$nom_ou_id] = $saisie;
93 }
94 }
95
96 return $saisies_option;
97 }
98
99 /**
100 * Liste les saisies ayant une definition SQL.
101 *
102 * @param Array $saisies liste de saisies
103 * @param String $tri tri par défaut des résultats (s'ils ne sont pas deja triés) ('nom', 'identifiant')
104 *
105 * @return liste de ces saisies triees par nom ayant une option sql définie
106 */
107 function saisies_lister_avec_sql($saisies, $tri = 'nom') {
108 return saisies_lister_avec_option('sql', $saisies, $tri);
109 }
110
111 /**
112 * Prend la description complète du contenu d'un formulaire et retourne
113 * les saisies "à plat" classées par type de saisie.
114 * $saisie['input']['input_1'] = $saisie.
115 *
116 * @param array $contenu Le contenu d'un formulaire
117 *
118 * @return array Un tableau avec uniquement les saisies
119 */
120 function saisies_lister_par_type($contenu) {
121 $saisies = array();
122
123 if (is_array($contenu)) {
124 foreach ($contenu as $ligne) {
125 if (is_array($ligne)) {
126 if (array_key_exists('saisie', $ligne) and (!is_array($ligne['saisies']))) {
127 $saisies[ $ligne['saisie'] ][ $ligne['options']['nom'] ] = $ligne;
128 }
129 if (is_array($ligne['saisies'])) {
130 $saisies = array_merge_recursive($saisies, saisies_lister_par_type($ligne['saisies']));
131 }
132 }
133 }
134 }
135
136 return $saisies;
137 }
138
139 /**
140 * Prend la description complète du contenu d'un formulaire et retourne
141 * une liste des noms des champs du formulaire.
142 *
143 * @param array $contenu Le contenu d'un formulaire
144 * @param bool $avec_conteneur Indique si on renvoie aussi les saisies ayant des enfants, comme les fieldset
145 *
146 * @return array Un tableau listant les noms des champs
147 */
148 function saisies_lister_champs($contenu, $avec_conteneur = true) {
149 $saisies = saisies_lister_par_nom($contenu, $avec_conteneur);
150
151 return array_keys($saisies);
152 }
153
154 /**
155 * A utiliser dans une fonction charger d'un formulaire CVT,
156 * cette fonction renvoie le tableau de contexte correspondant
157 * de la forme $contexte['nom_champ'] = ''.
158 *
159 * @param array $contenu Le contenu d'un formulaire (un tableau de saisies)
160 *
161 * @return array Un tableau de contexte
162 */
163 function saisies_charger_champs($contenu) {
164 // array_fill_keys est disponible uniquement avec PHP >= 5.2.0
165 // return array_fill_keys(saisies_lister_champs($contenu, false), '');
166 $champs = array();
167 foreach (saisies_lister_champs($contenu, false) as $champ) {
168 $champs[$champ] = '';
169 }
170
171 return $champs;
172 }
173
174 /**
175 * Prend la description complète du contenu d'un formulaire et retourne
176 * une liste des valeurs par défaut des champs du formulaire.
177 *
178 * @param array $contenu Le contenu d'un formulaire
179 *
180 * @return array Un tableau renvoyant la valeur par défaut de chaque champs
181 */
182 function saisies_lister_valeurs_defaut($contenu) {
183 $contenu = saisies_lister_par_nom($contenu, false);
184 $defauts = array();
185 foreach ($contenu as $nom => $saisie) {
186 // Si le nom du champ est un tableau indexé, il faut parser !
187 if (preg_match('/([\w]+)((\[[\w]+\])+)/', $nom, $separe)) {
188 $nom = $separe[1];
189 // Dans ce cas on ne récupère que le nom, la valeur par défaut du tableau devra être renseigné autre part
190 $defauts[$nom] = array();
191 } else {
192 $defauts[$nom] = isset($saisie['options']['defaut']) ? $saisie['options']['defaut'] : '';
193 }
194 }
195
196 return $defauts;
197 }
198
199 /**
200 * Compare deux tableaux de saisies pour connaitre les différences.
201 *
202 * @param array $saisies_anciennes Un tableau décrivant des saisies
203 * @param array $saisies_nouvelles Un autre tableau décrivant des saisies
204 * @param bool $avec_conteneur Indique si on veut prendre en compte dans la comparaison les conteneurs comme les fieldsets
205 * @param string $tri Comparer selon quel tri ? 'nom' / 'identifiant'
206 *
207 * @return array Retourne le tableau des saisies supprimées, ajoutées et modifiées
208 */
209 function saisies_comparer($saisies_anciennes, $saisies_nouvelles, $avec_conteneur = true, $tri = 'nom') {
210 $trier = "saisies_lister_par_$tri";
211 $saisies_anciennes = $trier($saisies_anciennes, $avec_conteneur);
212 $saisies_nouvelles = $trier($saisies_nouvelles, $avec_conteneur);
213
214 // Les saisies supprimées sont celles qui restent dans les anciennes quand on a enlevé toutes les nouvelles
215 $saisies_supprimees = array_diff_key($saisies_anciennes, $saisies_nouvelles);
216 // Les saisies ajoutées, c'est le contraire
217 $saisies_ajoutees = array_diff_key($saisies_nouvelles, $saisies_anciennes);
218 // Il reste alors les saisies qui ont le même nom
219 $saisies_restantes = array_intersect_key($saisies_anciennes, $saisies_nouvelles);
220 // Dans celles-ci, celles qui sont modifiées sont celles dont la valeurs est différentes
221 $saisies_modifiees = array_udiff(array_diff_key($saisies_nouvelles, $saisies_ajoutees), $saisies_restantes, 'saisies_comparer_rappel');
222 #$saisies_modifiees = array_udiff($saisies_nouvelles, $saisies_restantes, 'saisies_comparer_rappel');
223 // Et enfin les saisies qui ont le même nom et la même valeur
224 $saisies_identiques = array_diff_key($saisies_restantes, $saisies_modifiees);
225
226 return array(
227 'supprimees' => $saisies_supprimees,
228 'ajoutees' => $saisies_ajoutees,
229 'modifiees' => $saisies_modifiees,
230 'identiques' => $saisies_identiques,
231 );
232 }
233
234 /**
235 * Compare deux saisies et indique si elles sont égales ou pas.
236 *
237 * @param array $a Une description de saisie
238 * @param array $b Une autre description de saisie
239 *
240 * @return int Retourne 0 si les saisies sont identiques, 1 sinon.
241 */
242 function saisies_comparer_rappel($a, $b) {
243 if ($a === $b) {
244 return 0;
245 } else {
246 return 1;
247 }
248 }
249
250 /**
251 * Compare deux tableaux de saisies pour connaitre les différences
252 * en s'appuyant sur les identifiants de saisies.
253 *
254 * @see saisies_comparer()
255 *
256 * @param array $saisies_anciennes Un tableau décrivant des saisies
257 * @param array $saisies_nouvelles Un autre tableau décrivant des saisies
258 * @param bool $avec_conteneur Indique si on veut prendre en compte dans la comparaison
259 * les conteneurs comme les fieldsets
260 *
261 * @return array Retourne le tableau des saisies supprimées, ajoutées et modifiées
262 */
263 function saisies_comparer_par_identifiant($saisies_anciennes, $saisies_nouvelles, $avec_conteneur = true) {
264 return saisies_comparer($saisies_anciennes, $saisies_nouvelles, $avec_conteneur, 'identifiant');
265 }
266
267 /**
268 * Liste toutes les saisies configurables (ayant une description).
269 *
270 * @return array Un tableau listant des saisies et leurs options
271 */
272 function saisies_lister_disponibles($saisies_repertoire = 'saisies') {
273 static $saisies = null;
274
275 if (is_null($saisies)) {
276 $saisies = array();
277 $liste = find_all_in_path("$saisies_repertoire/", '.+[.]yaml$');
278
279 if (count($liste)) {
280 foreach ($liste as $fichier => $chemin) {
281 $type_saisie = preg_replace(',[.]yaml$,i', '', $fichier);
282 $dossier = str_replace($fichier, '', $chemin);
283 // On ne garde que les saisies qui ont bien le HTML avec !
284 if (file_exists("$dossier$type_saisie.html")
285 and (
286 is_array($saisie = saisies_charger_infos($type_saisie))
287 )
288 ) {
289 $saisies[$type_saisie] = $saisie;
290 }
291 }
292 }
293 }
294
295 return $saisies;
296 }
297
298 /**
299 * Liste tous les groupes de saisies configurables (ayant une description).
300 *
301 * @return array Un tableau listant des saisies et leurs options
302 */
303 function saisies_groupes_lister_disponibles($saisies_repertoire = 'saisies') {
304 static $saisies = null;
305
306 if (is_null($saisies)) {
307 $saisies = array();
308 $liste = find_all_in_path("$saisies_repertoire/", '.+[.]yaml$');
309
310 if (count($liste)) {
311 foreach ($liste as $fichier => $chemin) {
312 $type_saisie = preg_replace(',[.]yaml$,i', '', $fichier);
313 $dossier = str_replace($fichier, '', $chemin);
314 // On ne garde que les saisies qui ont bien le HTML avec !
315 if (is_array($saisie = saisies_charger_infos($type_saisie, $saisies_repertoire))) {
316 $saisies[$type_saisie] = $saisie;
317 }
318 }
319 }
320 }
321 return $saisies;
322 }
323
324 /**
325 * Lister les saisies existantes ayant une définition SQL.
326 *
327 * @return array Un tableau listant des saisies et leurs options
328 */
329 function saisies_lister_disponibles_sql($saisies_repertoire = 'saisies') {
330 $saisies = array();
331 $saisies_disponibles = saisies_lister_disponibles($saisies_repertoire);
332 foreach ($saisies_disponibles as $type => $saisie) {
333 if (isset($saisie['defaut']['options']['sql']) and $saisie['defaut']['options']['sql']) {
334 $saisies[$type] = $saisie;
335 }
336 }
337
338 return $saisies;
339 }
340
341 /**
342 * Charger les informations contenues dans le YAML d'une saisie.
343 *
344 * @param string $type_saisie Le type de la saisie
345 *
346 * @return array Un tableau contenant le YAML décodé
347 */
348 function saisies_charger_infos($type_saisie, $saisies_repertoire = 'saisies') {
349 if (defined('_DIR_PLUGIN_YAML')) {
350 include_spip('inc/yaml');
351 $fichier = find_in_path("$saisies_repertoire/$type_saisie.yaml");
352 $saisie = yaml_decode_file($fichier);
353 if (is_array($saisie)) {
354 $saisie['titre'] = (isset($saisie['titre']) and $saisie['titre'])
355 ? _T_ou_typo($saisie['titre']) : $type_saisie;
356 $saisie['description'] = (isset($saisie['description']) and $saisie['description'])
357 ? _T_ou_typo($saisie['description']) : '';
358 $saisie['icone'] = (isset($saisie['icone']) and $saisie['icone'])
359 ? find_in_path($saisie['icone']) : '';
360 }
361 } else {
362 $saisie = array();
363 }
364
365 return $saisie;
366 }
367
368 /**
369 * Quelles sont les saisies qui se débrouillent toutes seules, sans le _base commun.
370 *
371 * @return array Retourne un tableau contenant les types de saisies qui ne doivent pas utiliser le _base.html commun
372 */
373 function saisies_autonomes() {
374 $saisies_autonomes = pipeline(
375 'saisies_autonomes',
376 array(
377 'fieldset',
378 'hidden',
379 'destinataires',
380 'explication',
381 )
382 );
383
384 return $saisies_autonomes;
385 }