3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2014 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
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 \***************************************************************************/
13 if (!defined('_ECRIRE_INC_VERSION')) return;
17 * Module facilitant l'ecriture de formulaires CVT
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
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)
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
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
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
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
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()
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
68 * Reinjecter dans _request() les valeurs postees
69 * dans les etapes precedentes
74 function cvtmulti_recuperer_post_precedents($form){
75 include_spip('inc/filtres');
77 AND $c = _request('cvtm_prev_post')
78 AND $c = decoder_contexte_ajax($c, $form)){
81 # reinjecter dans la bonne variable pour permettre de retrouver
82 # toutes les saisies dans un seul tableau
83 if ($_SERVER['REQUEST_METHOD']=='POST')
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])
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))
100 $_REQUEST[$k] = $store[$k] = array_merge($v,$store[$k]);
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']);
111 * Sauvegarder les valeurs postees dans une variable encodee
112 * pour les recuperer a la prochaine etape
114 * @param string $form
115 * @param bool $je_suis_poste
116 * @param array $valeurs
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)
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;
143 * Reperer une demande de formulaire CVT multi page
146 * @param <type> $flux
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;
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']);
170 * Verifier les etapes de saisie
175 function cvtmulti_formulaire_verifier($flux){
176 #var_dump('Pipe verifier');
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
184 // lancer les verifs pour chaque etape deja saisie de 1 a $etape
186 $derniere_etape_ok = 0;
188 while ($e<$etape AND $e<$etapes){
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);
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;
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){
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);
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
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']
240 AND file_exists($f."_$e.$ext"))
241 $flux['data'] = $f."_$e";