[SPIP] ~v3.0.20-->v3.0.25
[lhc/web/clavette_www.git] / www / ecrire / inc / cvt_multietapes.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2016 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
8 * *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
12
13 if (!defined('_ECRIRE_INC_VERSION')) return;
14
15 /*
16 * CVT Multi etapes
17 * Module facilitant l'ecriture de formulaires CVT
18 * en plusieurs etapes
19 *
20 * #FORMULAIRE_TRUC
21 *
22 * Squelette :
23 * Chaque etape est representee par un squelette independant qui doit
24 * implementer un formulaire autonome pour les saisies de l'etape n
25 * formulaires/truc.html pour l'etape 1
26 * formulaires/truc_2.html pour l'etape 2
27 * formulaires/truc_n.html pour l'etape n
28 *
29 * Si un squelette formulaires/truc_n.html manque pour l'etape n
30 * c'est formulaires/truc.html qui sera utilise
31 * (charge a lui de gerer le cas de cette etape)
32 *
33 * Charger :
34 * formulaires_truc_charger_dist() :
35 * passer '_etapes' => nombre total d'etapes de saisies (>1 !)
36 * indiquer toutes les valeurs a saisir sur toutes les pages
37 * comme si il s'agissait d'un formulaire unique
38 *
39 * Verifier :
40 * le numero d'etape courante est disponible dans $x=_request('_etape'), si necessaire
41 * _request() permet d'acceder aux saisies effectuees depuis l'etape 1,
42 * comme si les etapes 1 a $x avaient ete saisies en une seule fois
43 *
44 * formulaires_truc_verifier_1_dist() : verifier les saisies de l'etape 1 uniquement
45 * formulaires_truc_verifier_2_dist() : verifier les saisies de l'etape 2
46 * formulaires_truc_verifier_n_dist() : verifier les saisies de l'etape n
47 *
48 * Il est possible d'implementer toutes les verifications dans une fonction unique qui sera alors appelee
49 * avec en premier argument le numero de l'etape a verifier
50 * formulaires_truc_verifier_etape_dist($etape,...) : verifier les saisies de l'etape $etape uniquement
51 *
52 * A chaque etape x, les etapes 1 a x sont appelees en verification
53 * pour verifier l'absence de regression dans la validation (erreur, tentative de reinjection ...)
54 * en cas d'erreur, la saisie retourne a la premiere etape en erreur.
55 * en cas de succes, l'etape est incrementee, sauf si c'est la derniere.
56 * Dans ce dernier cas on declenche traiter()
57 *
58 * Traiter
59 * formulaires_truc_traiter_dist() : ne sera appele que lorsque *toutes*
60 * les etapes auront ete saisies sans erreur.
61 * La fonction traiter peut donc traiter l'ensemble des saisies comme si il s'agissait d'un formulaire unique
62 * dans lequel toutes les donnees auraient ete saisies en une fois
63 *
64 *
65 */
66
67 /**
68 * Reinjecter dans _request() les valeurs postees
69 * dans les etapes precedentes
70 *
71 * @param string $form
72 * @return array
73 */
74 function cvtmulti_recuperer_post_precedents($form){
75 include_spip('inc/filtres');
76 if ($form
77 AND $c = _request('cvtm_prev_post')
78 AND $c = decoder_contexte_ajax($c, $form)){
79 #var_dump($c);
80
81 # reinjecter dans la bonne variable pour permettre de retrouver
82 # toutes les saisies dans un seul tableau
83 if ($_SERVER['REQUEST_METHOD']=='POST')
84 $store = &$_POST;
85 else
86 $store = &$_GET;
87
88 foreach($c as $k=>$v)
89 // on ecrase pas si saisi a nouveau !
90 if (!isset($store[$k]))
91 $_REQUEST[$k] = $store[$k] = $v;
92 // mais si tableau des deux cotes, on merge avec priorite a la derniere saisie
93 elseif(is_array($store[$k])
94 AND is_array($v)
95 AND $z = array_keys($v)
96 AND !is_numeric(reset($z))
97 AND $z = array_keys($store[$k])
98 AND !is_numeric(reset($z))
99 )
100 $_REQUEST[$k] = $store[$k] = array_merge($v,$store[$k]);
101
102 // vider pour eviter un second appel a verifier_n
103 // en cas de double implementation (unipotence)
104 set_request('cvtm_prev_post');
105 return array($c['_etape'],$c['_etapes']);
106 }
107 return false;
108 }
109
110 /**
111 * Sauvegarder les valeurs postees dans une variable encodee
112 * pour les recuperer a la prochaine etape
113 *
114 * @param string $form
115 * @param bool $je_suis_poste
116 * @param array $valeurs
117 * @return array
118 */
119 function cvtmulti_sauver_post($form, $je_suis_poste, &$valeurs){
120 if (!isset($valeurs['_cvtm_prev_post'])){
121 $post = array('_etape'=>$valeurs['_etape'],'_etapes'=>$valeurs['_etapes']);
122 foreach(array_keys($valeurs) as $champ){
123 if (substr($champ,0,1)!=='_'){
124 if ($je_suis_poste || (isset($valeurs['_forcer_request']) && $valeurs['_forcer_request'])) {
125 if (($v = _request($champ))!==NULL)
126 $post[$champ] = $v;
127 }
128 }
129 }
130 include_spip('inc/filtres');
131 $c = encoder_contexte_ajax($post,$form);
132 if (!isset($valeurs['_hidden']))
133 $valeurs['_hidden'] = '';
134 $valeurs['_hidden'] .= "<input type='hidden' name='cvtm_prev_post' value='$c' />";
135 // marquer comme fait, pour eviter double encodage (unipotence)
136 $valeurs['_cvtm_prev_post'] = true;
137 }
138 return $valeurs;
139 }
140
141
142 /**
143 * Reperer une demande de formulaire CVT multi page
144 * et la reformater
145 *
146 * @param <type> $flux
147 * @return <type>
148 */
149 function cvtmulti_formulaire_charger($flux){
150 #var_dump($flux['data']['_etapes']);
151 if (is_array($flux['data'])
152 AND isset($flux['data']['_etapes'])){
153 $form = $flux['args']['form'];
154 $je_suis_poste = $flux['args']['je_suis_poste'];
155 $nb_etapes = $flux['data']['_etapes'];
156 $etape = _request('_etape');
157 $etape = min(max($etape,1),$nb_etapes);
158 set_request('_etape',$etape);
159 $flux['data']['_etape'] = $etape;
160
161 // sauver les posts de cette etape pour les avoir a la prochaine etape
162 $flux['data'] = cvtmulti_sauver_post($form, $je_suis_poste, $flux['data']);
163 #var_dump($flux['data']);
164 }
165 return $flux;
166 }
167
168
169 /**
170 * Verifier les etapes de saisie
171 *
172 * @param array $flux
173 * @return array
174 */
175 function cvtmulti_formulaire_verifier($flux){
176 #var_dump('Pipe verifier');
177
178 if ($form = $flux['args']['form']
179 AND ($e = cvtmulti_recuperer_post_precedents($form))!==false){
180 // recuperer l'etape saisie et le nombre d'etapes total
181 list($etape,$etapes) = $e;
182 $etape_demandee = _request('aller_a_etape'); // possibilite de poster en entier dans aller_a_etape
183
184 // lancer les verifs pour chaque etape deja saisie de 1 a $etape
185 $erreurs = array();
186 $derniere_etape_ok = 0;
187 $e = 0;
188 while ($e<$etape AND $e<$etapes){
189 $e++;
190 $erreurs[$e] = array();
191 if ($verifier = charger_fonction("verifier_$e","formulaires/$form/",true))
192 $erreurs[$e] = call_user_func_array($verifier, $flux['args']['args']);
193 elseif ($verifier = charger_fonction("verifier_etape","formulaires/$form/",true)){
194 $args = $flux['args']['args'];
195 array_unshift($args, $e);
196 $erreurs[$e] = call_user_func_array($verifier, $args);
197 }
198 if ($derniere_etape_ok==$e-1 AND !count($erreurs[$e]))
199 $derniere_etape_ok = $e;
200 // possibilite de poster dans _retour_etape_x
201 if (!is_null(_request("_retour_etape_$e")))
202 $etape_demandee = $e;
203 }
204
205 // si la derniere etape OK etait la derniere
206 // on renvoie le flux inchange et ca declenche traiter
207 if ($derniere_etape_ok==$etapes AND !$etape_demandee){
208 return $flux;
209 }
210 else {
211 $etape = $derniere_etape_ok+1;
212 if ($etape_demandee>0 AND $etape_demandee<$etape)
213 $etape = $etape_demandee;
214 $etape = min($etape,$etapes);
215 #var_dump("prochaine etape $etape");
216 // retourner les erreurs de l'etape ciblee
217 $flux['data'] = isset($erreurs[$etape]) ? $erreurs[$etape] : array() ;
218 $flux['data']['_etapes'] = "etape suivante $etape";
219 set_request('_etape',$etape);
220 }
221 }
222 return $flux;
223 }
224
225 /**
226 * Selectionner le bon fond en fonction de l'etape
227 * L'etape 1 est sur le fond sans suffixe
228 * Les autres etapes x sont sur le fond _x
229 *
230 * @param array $flux
231 * @return array
232 */
233 function cvtmulti_styliser($flux){
234 if (strncmp($flux['args']['fond'],'formulaires/',12)==0
235 AND isset($flux['args']['contexte']['_etapes'])
236 AND isset($flux['args']['contexte']['_etape'])
237 AND ($e=$flux['args']['contexte']['_etape'])>1
238 AND $ext = $flux['args']['ext']
239 AND $f=$flux['data']
240 AND file_exists($f."_$e.$ext"))
241 $flux['data'] = $f."_$e";
242 return $flux;
243 }
244
245
246 ?>