[SPIP] +installation version 3.0.10
[lhc/web/www.git] / www / ecrire / inc / cvt_multietapes.php
diff --git a/www/ecrire/inc/cvt_multietapes.php b/www/ecrire/inc/cvt_multietapes.php
new file mode 100644 (file)
index 0000000..12785e0
--- /dev/null
@@ -0,0 +1,246 @@
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2012                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined('_ECRIRE_INC_VERSION')) return;
+
+/*
+ * CVT Multi etapes
+ * Module facilitant l'ecriture de formulaires CVT
+ * en plusieurs etapes
+ *
+ * #FORMULAIRE_TRUC
+ *
+ * Squelette :
+ * Chaque etape est representee par un squelette independant qui doit
+ * implementer un formulaire autonome pour les saisies de l'etape n
+ * formulaires/truc.html pour l'etape 1
+ * formulaires/truc_2.html pour l'etape 2
+ * formulaires/truc_n.html pour l'etape n
+ *
+ * Si un squelette formulaires/truc_n.html manque pour l'etape n
+ * c'est formulaires/truc.html qui sera utilise
+ * (charge a lui de gerer le cas de cette etape)
+ *
+ * Charger :
+ * formulaires_truc_charger_dist() :
+ *     passer '_etapes' => nombre total d'etapes de saisies (>1 !)
+ *  indiquer toutes les valeurs a saisir sur toutes les pages
+ *  comme si il s'agissait d'un formulaire unique
+ *
+ * Verifier :
+ * le numero d'etape courante est disponible dans $x=_request('_etape'), si necessaire
+ * _request() permet d'acceder aux saisies effectuees depuis l'etape 1,
+ * comme si les etapes 1 a $x avaient ete saisies en une seule fois
+ *
+ * formulaires_truc_verifier_1_dist() : verifier les saisies de l'etape 1 uniquement
+ * formulaires_truc_verifier_2_dist() : verifier les saisies de l'etape 2
+ * formulaires_truc_verifier_n_dist() : verifier les saisies de l'etape n
+ *
+ * Il est possible d'implementer toutes les verifications dans une fonction unique qui sera alors appelee
+ * avec en premier argument le numero de l'etape a verifier
+ * formulaires_truc_verifier_etape_dist($etape,...) : verifier les saisies de l'etape $etape uniquement
+ *
+ * A chaque etape x, les etapes 1 a x sont appelees en verification
+ * pour verifier l'absence de regression dans la validation (erreur, tentative de reinjection ...)
+ * en cas d'erreur, la saisie retourne a la premiere etape en erreur.
+ * en cas de succes, l'etape est incrementee, sauf si c'est la derniere.
+ * Dans ce dernier cas on declenche traiter()
+ *
+ * Traiter
+ * formulaires_truc_traiter_dist() : ne sera appele que lorsque *toutes*
+ * les etapes auront ete saisies sans erreur.
+ * La fonction traiter peut donc traiter l'ensemble des saisies comme si il s'agissait d'un formulaire unique
+ * dans lequel toutes les donnees auraient ete saisies en une fois
+ *
+ *
+ */
+
+/**
+ * Reinjecter dans _request() les valeurs postees
+ * dans les etapes precedentes
+ *
+ * @param string $form
+ * @return array
+ */
+function cvtmulti_recuperer_post_precedents($form){
+       include_spip('inc/filtres');
+       if ($form
+         AND $c = _request('cvtm_prev_post')
+               AND $c = decoder_contexte_ajax($c, $form)){
+               #var_dump($c);
+               
+               # reinjecter dans la bonne variable pour permettre de retrouver
+               # toutes les saisies dans un seul tableau
+               if ($_SERVER['REQUEST_METHOD']=='POST')
+                       $store = &$_POST;
+               else
+                       $store = &$_GET;
+
+               foreach($c as $k=>$v)
+                       // on ecrase pas si saisi a nouveau !
+                       if (!isset($store[$k]))
+                               $_REQUEST[$k] = $store[$k] = $v;
+                       // mais si tableau des deux cotes, on merge avec priorite a la derniere saisie
+                       elseif(is_array($store[$k])
+                         AND is_array($v)
+                               AND $z = array_keys($v)
+                               AND !is_numeric(reset($z))
+                               AND $z = array_keys($store[$k])
+                               AND !is_numeric(reset($z))
+                               )
+                               $_REQUEST[$k] = $store[$k] = array_merge($v,$store[$k]);
+
+               // vider pour eviter un second appel a verifier_n
+               // en cas de double implementation (unipotence)
+               set_request('cvtm_prev_post');
+               return array($c['_etape'],$c['_etapes']);
+       }
+       return false;
+}
+
+/**
+ * Sauvegarder les valeurs postees dans une variable encodee
+ * pour les recuperer a la prochaine etape
+ *  
+ * @param string $form
+ * @param bool $je_suis_poste
+ * @param array $valeurs
+ * @return array
+ */
+function cvtmulti_sauver_post($form, $je_suis_poste, &$valeurs){
+       if (!isset($valeurs['_cvtm_prev_post'])){
+               $post = array('_etape'=>$valeurs['_etape'],'_etapes'=>$valeurs['_etapes']);
+               foreach(array_keys($valeurs) as $champ){
+                       if (substr($champ,0,1)!=='_'){
+                               if ($je_suis_poste || (isset($valeurs['_forcer_request']) && $valeurs['_forcer_request'])) {
+                                       if (($v = _request($champ))!==NULL)
+                                               $post[$champ] = $v;
+                               }
+                       }
+               }
+               include_spip('inc/filtres');
+               $c = encoder_contexte_ajax($post,$form);
+               if (!isset($valeurs['_hidden']))
+                       $valeurs['_hidden'] = '';
+               $valeurs['_hidden'] .= "<input type='hidden' name='cvtm_prev_post' value='$c' />";
+               // marquer comme fait, pour eviter double encodage (unipotence)
+               $valeurs['_cvtm_prev_post'] = true;
+       }
+       return $valeurs;
+}
+
+
+/**
+ * Reperer une demande de formulaire CVT multi page
+ * et la reformater
+ * 
+ * @param <type> $flux
+ * @return <type> 
+ */
+function cvtmulti_formulaire_charger($flux){
+       #var_dump($flux['data']['_etapes']);
+       if (is_array($flux['data'])
+         AND isset($flux['data']['_etapes'])){
+               $form = $flux['args']['form'];
+               $je_suis_poste = $flux['args']['je_suis_poste'];
+               $nb_etapes = $flux['data']['_etapes'];
+               $etape = _request('_etape');
+               $etape = min(max($etape,1),$nb_etapes);
+               set_request('_etape',$etape);
+               $flux['data']['_etape'] = $etape;
+
+               // sauver les posts de cette etape pour les avoir a la prochaine etape
+               $flux['data'] = cvtmulti_sauver_post($form, $je_suis_poste, $flux['data']);
+               #var_dump($flux['data']);
+       }
+       return $flux;
+}
+
+
+/**
+ * Verifier les etapes de saisie
+ *
+ * @param array $flux
+ * @return array
+ */
+function cvtmulti_formulaire_verifier($flux){
+       #var_dump('Pipe verifier');
+       
+       if ($form = $flux['args']['form']
+         AND ($e = cvtmulti_recuperer_post_precedents($form))!==false){
+               // recuperer l'etape saisie et le nombre d'etapes total
+               list($etape,$etapes) = $e;
+               $etape_demandee = _request('aller_a_etape'); // possibilite de poster en entier dans aller_a_etape
+
+               // lancer les verifs pour chaque etape deja saisie de 1 a $etape
+               $erreurs = array();
+               $derniere_etape_ok = 0;
+               $e = 0;
+               while ($e<$etape AND $e<$etapes){
+                       $e++;
+                       $erreurs[$e] = array();
+                       if ($verifier = charger_fonction("verifier_$e","formulaires/$form/",true))
+                               $erreurs[$e] = call_user_func_array($verifier, $flux['args']['args']);
+                       elseif ($verifier = charger_fonction("verifier_etape","formulaires/$form/",true)){
+                               $args = $flux['args']['args'];
+                               array_unshift($args, $e);
+                               $erreurs[$e] = call_user_func_array($verifier, $args);
+                       }
+                       if ($derniere_etape_ok==$e-1 AND !count($erreurs[$e]))
+                               $derniere_etape_ok = $e;
+                       // possibilite de poster dans _retour_etape_x
+                       if (!is_null(_request("_retour_etape_$e")))
+                               $etape_demandee = $e;
+               }
+
+               // si la derniere etape OK etait la derniere
+               // on renvoie le flux inchange et ca declenche traiter
+               if ($derniere_etape_ok==$etapes AND !$etape_demandee){
+                       return $flux;
+               }
+               else {
+                       $etape = $derniere_etape_ok+1;
+                       if ($etape_demandee>0 AND $etape_demandee<$etape)
+                               $etape = $etape_demandee;
+                       $etape = min($etape,$etapes);
+                       #var_dump("prochaine etape $etape");
+                       // retourner les erreurs de l'etape ciblee
+                       $flux['data'] = isset($erreurs[$etape]) ? $erreurs[$etape] : array() ;
+                       $flux['data']['_etapes'] = "etape suivante $etape";
+                       set_request('_etape',$etape);
+               }
+       }
+       return $flux;
+}
+
+/**
+ * Selectionner le bon fond en fonction de l'etape
+ * L'etape 1 est sur le fond sans suffixe
+ * Les autres etapes x sont sur le fond _x
+ * 
+ * @param array $flux
+ * @return array
+ */
+function cvtmulti_styliser($flux){
+       if (strncmp($flux['args']['fond'],'formulaires/',12)==0
+         AND isset($flux['args']['contexte']['_etapes'])
+         AND isset($flux['args']['contexte']['_etape'])
+         AND ($e=$flux['args']['contexte']['_etape'])>1
+               AND $ext = $flux['args']['ext']
+               AND $f=$flux['data']
+               AND file_exists($f."_$e.$ext"))
+               $flux['data'] = $f."_$e";
+       return $flux;
+}
+
+
+?>