source: spip-zone/_plugins_/saisies/inc/saisies.php @ 60107

Last change on this file since 60107 was 60107, checked in by yffic@…, 8 years ago

Normaliser la saisie si c'est demandé dans ses options

File size: 11.2 KB
Line 
1<?php
2
3// Sécurité
4if (!defined('_ECRIRE_INC_VERSION')) return;
5
6/*
7 * Une librairie pour manipuler ou obtenir des infos sur un tableau de saisies
8 *
9 * saisies_lister_par_nom()
10 * saisies_lister_champs()
11 * saisies_lister_valeurs_defaut()
12 * saisies_charger_champs()
13 * saisies_chercher()
14 * saisies_supprimer()
15 * saisies_inserer()
16 * saisies_deplacer()
17 * saisies_modifier()
18 * saisies_verifier()
19 * saisies_comparer()
20 * saisies_generer_html()
21 * saisies_generer_vue()
22 * saisies_generer_nom()
23 * saisies_inserer_html()
24 * saisies_lister_disponibles()
25 * saisies_autonomes()
26 */
27
28// Différentes méthodes pour trouver les saisies
29include_spip('inc/saisies_lister');
30
31// Différentes méthodes pour manipuler une liste de saisies
32include_spip('inc/saisies_manipuler');
33
34// Les outils pour afficher les saisies et leur vue
35include_spip('inc/saisies_afficher');
36
37/*
38 * Cherche la description des saisies d'un formulaire CVT dont on donne le nom
39 *
40 * @param string $form Nom du formulaire dont on cherche les saisies
41 * @return array Retourne les saisies du formulaire sinon false
42 */
43function saisies_chercher_formulaire($form, $args){
44        if ($fonction_saisies = charger_fonction('saisies', 'formulaires/'.$form, true)
45                and $saisies = call_user_func_array($fonction_saisies, $args)
46                and is_array($saisies)
47                // On passe les saisies dans un pipeline normé comme pour CVT
48                and $saisies = pipeline(
49                        'formulaire_saisies',
50                        array(
51                                'args' => array('form' => $form, 'args' => $args),
52                                'data' => $saisies
53                        )
54                )
55                // Si c'est toujours un tableau après le pipeline
56                and is_array($saisies)
57        ){
58                return $saisies;
59        }
60        else{
61                return false;
62        }
63}
64
65/*
66 * Cherche une saisie par son id, son nom ou son chemin et renvoie soit la saisie, soit son chemin
67 *
68 * @param array $saisies Un tableau décrivant les saisies
69 * @param unknown_type $id_ou_nom_ou_chemin L'identifiant ou le nom de la saisie à chercher ou le chemin sous forme d'une liste de clés
70 * @param bool $retourner_chemin Indique si on retourne non pas la saisie mais son chemin
71 * @return array Retourne soit la saisie, soit son chemin, soit null
72 */
73function saisies_chercher($saisies, $id_ou_nom_ou_chemin, $retourner_chemin=false){
74
75        if (is_array($saisies) and $id_ou_nom_ou_chemin){
76                if (is_string($id_ou_nom_ou_chemin)){
77                        $nom = $id_ou_nom_ou_chemin;
78                        // identifiant ? premier caractere @
79                        $id = ($nom[0] == '@');
80
81                        foreach($saisies as $cle => $saisie){
82                                $chemin = array($cle);
83                                if ($nom == ($id ? $saisie['identifiant'] : $saisie['options']['nom'])) {
84                                        return $retourner_chemin ? $chemin : $saisie;
85                                } elseif ($saisie['saisies'] and is_array($saisie['saisies']) and ($retour = saisies_chercher($saisie['saisies'], $nom, $retourner_chemin))) {
86                                        return $retourner_chemin ? array_merge($chemin, array('saisies'), $retour) : $retour;
87                                }
88
89                        }
90                }
91                elseif (is_array($id_ou_nom_ou_chemin)){
92                        $chemin = $id_ou_nom_ou_chemin;
93                        $saisie = $saisies;
94                        // On vérifie l'existence quand même
95                        foreach ($chemin as $cle){
96                                if (isset($saisie[$cle])) $saisie = $saisie[$cle];
97                                else return null;
98                        }
99                        // Si c'est une vraie saisie
100                        if ($saisie['saisie'] and $saisie['options']['nom'])
101                                return $retourner_chemin ? $chemin : $saisie;
102                }
103        }
104       
105        return null;
106}
107
108/*
109 * Génère un nom unique pour un champ d'un formulaire donné
110 *
111 * @param array $formulaire Le formulaire à analyser
112 * @param string $type_saisie Le type de champ dont on veut un identifiant
113 * @return string Un nom unique par rapport aux autres champs du formulaire
114 */
115function saisies_generer_nom($formulaire, $type_saisie){
116        $champs = saisies_lister_champs($formulaire);
117       
118        // Tant que type_numero existe, on incrémente le compteur
119        $compteur = 1;
120        while (array_search($type_saisie.'_'.$compteur, $champs) !== false)
121                $compteur++;
122       
123        // On a alors un compteur unique pour ce formulaire
124        return $type_saisie.'_'.$compteur;
125}
126
127/*
128 * Crée un identifiant Unique
129 * pour toutes les saisies donnees qui n'en ont pas
130 *
131 * @param Array $saisies Tableau de saisies
132 * @param Bool $regenerer_id Régénère un nouvel identifiant pour toutes les saisies ?
133 * @return Array Tableau de saisies complété des identifiants
134 */
135function saisies_identifier($saisies, $regenerer = false) {
136        if (!is_array($saisies)) {
137                return array();
138        }
139        foreach ($saisies as $k => $saisie) {
140                $saisies[$k] = saisie_identifier($saisie, $regenerer);
141        }
142        return $saisies;
143}
144
145/**
146 * Crée un identifiant Unique
147 * pour la saisie donnee si elle n'en a pas
148 * (et pour ses sous saisies éventuels)
149 *
150 * @param Array $saisie Tableau d'une saisie
151 * @param Bool $regenerer_id Régénère un nouvel identifiant pour la saisie ?
152 * @return Array Tableau de la saisie complété de l'identifiant
153**/
154function saisie_identifier($saisie, $regenerer = false) {
155        if (!isset($saisie['identifiant']) OR !$saisie['identifiant']) {
156                $saisie['identifiant'] = uniqid('@');
157        } elseif ($regenerer) {
158                $saisie['identifiant'] = uniqid('@');
159        }
160        if (isset($saisie['saisies']) AND is_array($saisie['saisies'])) {
161                $saisie['saisies'] = saisies_identifier($saisie['saisies'], $regenerer);
162        }
163        return $saisie;
164}
165
166/*
167 * Vérifier tout un formulaire tel que décrit avec les Saisies
168 *
169 * @param array $formulaire Le contenu d'un formulaire décrit dans un tableau de Saisies
170 * @param bool $saisies_masquees_nulles   Si TRUE, les saisies masquees selon afficher_si ne seront pas verifiees, leur valeur etant forcee a NULL.
171 *                                        Cette valeur NULL est transmise a traiter (via set_request).
172 * @return array Retourne un tableau d'erreurs
173 */
174function saisies_verifier($formulaire, $saisies_masquees_nulles=true){
175        include_spip('inc/verifier');
176        $erreurs = array();
177        $verif_fonction = charger_fonction('verifier','inc',true);
178       
179        if ($saisies_masquees_nulles)
180                $formulaire = saisies_verifier_afficher_si($formulaire);
181       
182        $saisies = saisies_lister_par_nom($formulaire);
183        foreach ($saisies as $saisie){
184                $obligatoire = $saisie['options']['obligatoire'];
185                $champ = $saisie['options']['nom'];
186                $file = ($saisie['saisie'] == 'input' and $saisie['options']['type'] == 'file');
187                $verifier = $saisie['verifier'];
188
189                // Si le nom du champ est un tableau indexé, il faut parser !
190                if (preg_match('/([\w]+)((\[[\w]+\])+)/', $champ, $separe)){
191                        $valeur = _request($separe[1]);
192                        preg_match_all('/\[([\w]+)\]/', $separe[2], $index);
193                        // On va chercher au fond du tableau
194                        foreach($index[1] as $cle){
195                                $valeur = $valeur[$cle];
196                        }
197                }
198                // Sinon la valeur est juste celle du nom
199                else
200                        $valeur = _request($champ);
201               
202                // On regarde d'abord si le champ est obligatoire
203                if ($obligatoire
204                        and $obligatoire != 'non'
205                        and (
206                                ($file and !$_FILES[$champ]['name'])
207                                or (!$file and (
208                                        is_null($valeur)
209                                        or (is_string($valeur) and trim($valeur) == '')
210                                        or (is_array($valeur) and count($valeur) == 0)
211                                ))
212                        )
213                )
214                        $erreurs[$champ] = _T('info_obligatoire');
215               
216                // On continue seulement si ya pas d'erreur d'obligation et qu'il y a une demande de verif
217                if (!$erreurs[$champ] and is_array($verifier) and $verif_fonction){
218                        $normaliser = null;
219                        // Si le champ n'est pas valide par rapport au test demandé, on ajoute l'erreur
220                        if ($erreur_eventuelle = $verif_fonction($valeur, $verifier['type'], $verifier['options'], $normaliser)) {
221                                $erreurs[$champ] = $erreur_eventuelle;
222                        } elseif (!is_null($normaliser)) {
223                                set_request($champ, $normaliser);
224                        }
225                }
226        }
227       
228        return $erreurs;
229}
230
231/*
232 * Transforme une chaine en tableau avec comme principe :
233 * - une ligne devient une case
234 * - si la ligne est de la forme truc|bidule alors truc est la clé et bidule la valeur
235 *
236 * @param string $chaine Une chaine à transformer
237 * @return array Retourne un tableau PHP
238 */
239function saisies_chaine2tableau($chaine, $separateur="\n"){
240        if ($chaine and is_string($chaine)){
241                $tableau = array();
242                // On découpe d'abord en lignes
243                $lignes = explode($separateur, $chaine);
244                foreach ($lignes as $i=>$ligne){
245                        $ligne = trim(trim($ligne), '|');
246                        // Si ce n'est pas une ligne sans rien
247                        if ($ligne !== ''){
248                                // Si on trouve un découpage dans la ligne on fait cle|valeur
249                                if (strpos($ligne, '|') !== false){
250                                        list($cle,$valeur) = explode('|', $ligne, 2);
251                                        $tableau[$cle] = $valeur;
252                                }
253                                // Sinon on génère la clé
254                                else{
255                                        $tableau[$i] = $ligne;
256                                }
257                        }
258                }
259                return $tableau;
260        }
261        // Si c'est déjà un tableau on le renvoie tel quel
262        elseif (is_array($chaine)){
263                return $chaine;
264        }
265        else{
266                return array();
267        }
268}
269
270/*
271 * Transforme un tableau en chaine de caractères avec comme principe :
272 * - une case de vient une ligne de la chaine
273 * - chaque ligne est générée avec la forme cle|valeur
274 */
275function saisies_tableau2chaine($tableau){
276        if ($tableau and is_array($tableau)){
277                $chaine = '';
278       
279                foreach($tableau as $cle=>$valeur){
280                        $ligne = trim("$cle|$valeur");
281                        $chaine .= "$ligne\n";
282                }
283                $chaine = trim($chaine);
284       
285                return $chaine;
286        }
287        // Si c'est déjà une chaine on la renvoie telle quelle
288        elseif (is_string($tableau)){
289                return $tableau;
290        }
291        else{
292                return '';
293        }
294}
295
296
297
298
299/**
300 * Passe une valeur en tableau d'élements si ce n'en est pas une
301 *
302 * entrée :
303 * cle|valeur
304 * cle|valeur
305 *
306 * Sinon :
307 * valeur,valeur
308 *
309 * @param mixed $valeur
310 * @return array Tableau de valeurs
311**/
312function saisies_valeur2tableau($valeur, $sinon_separateur="") {
313        if (is_array($valeur)) {
314                return $valeur;
315        }
316       
317        if (!strlen($valeur)) {
318                return array();
319        }
320       
321        $t = saisies_chaine2tableau($valeur);
322        if (count($t) > 1) {
323                return $t;
324        }
325
326        // qu'une seule valeur, c'est qu'elle a peut etre un separateur a virgule
327        // et a donc une cle est 0 dans ce cas la d'ailleurs
328        if (isset($t[0])) {
329                $t = saisies_chaine2tableau($t[0], ',');
330        }
331       
332        return $t;
333}
334
335
336
337
338/*
339 * Génère une page d'aide listant toutes les saisies et leurs options
340 */
341function saisies_generer_aide(){
342        // On a déjà la liste par saisie
343        $saisies = saisies_lister_disponibles();
344       
345        // On construit une liste par options
346        $options = array();
347        foreach ($saisies as $type_saisie=>$saisie){
348                $options_saisie = saisies_lister_par_nom($saisie['options'], false);
349                foreach ($options_saisie as $nom=>$option){
350                        // Si l'option n'existe pas encore
351                        if (!isset($options[$nom])){
352                                $options[$nom] = _T_ou_typo($option['options']);
353                        }
354                        // On ajoute toujours par qui c'est utilisé
355                        $options[$nom]['utilisee_par'][] = $type_saisie;
356                }
357                ksort($options_saisie);
358                $saisies[$type_saisie]['options'] = $options_saisie;
359        }
360        ksort($options);
361       
362        return recuperer_fond(
363                'inclure/saisies_aide',
364                array(
365                        'saisies' => $saisies,
366                        'options' => $options
367                )
368        );
369}
370
371/*
372 * Le tableau de saisies a-t-il une option afficher_si ?
373 *
374 * @param array $saisies Un tableau de saisies
375 * @return boolean
376 */
377
378function saisies_afficher_si($saisies) {
379        $saisies = saisies_lister_par_nom($saisies,true);
380        // Dès qu'il y a au moins une option afficher_si, on l'active
381        foreach ($saisies as $saisie) {
382                if (isset($saisie['options']['afficher_si']))
383                        return true;
384        }
385        return false;
386}
387
388?>
Note: See TracBrowser for help on using the repository browser.