PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/ecrire/inc/cvt_multietapes.php

https://bitbucket.org/re_al_/real.test.spip
PHP | 307 lines | 149 code | 26 blank | 132 comment | 29 complexity | 33d758bc7efe2d780c77c0a98d9c0322 MD5 | raw file
Possible License(s): LGPL-2.1, MIT
  1. <?php
  2. /***************************************************************************\
  3. * SPIP, Systeme de publication pour l'internet *
  4. * *
  5. * Copyright (c) 2001-2017 *
  6. * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
  7. * *
  8. * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
  9. * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
  10. \***************************************************************************/
  11. /**
  12. * CVT Multi étapes
  13. *
  14. * Module facilitant l'écriture de formulaires CVT
  15. * en plusieurs étapes.
  16. *
  17. * `#FORMULAIRE_TRUC`
  18. *
  19. * Squelette :
  20. * Chaque étape est representée par un squelette indépendant qui doit
  21. * implémenter un formulaire autonome pour les saisies de l'étape n :
  22. *
  23. * - formulaires/truc.html pour l'etape 1
  24. * - formulaires/truc_2.html pour l'etape 2
  25. * - formulaires/truc_n.html pour l'etape n
  26. *
  27. * Si un squelette `formulaires/truc_n.html` manque pour l'étape n
  28. * c'est `formulaires/truc.html` qui sera utilisé
  29. * (charge à lui de gérer le cas de cette étape).
  30. *
  31. * Charger :
  32. * `formulaires_truc_charger_dist()` :
  33. * passer '_etapes' => nombre total d'etapes de saisies (>1 !)
  34. * indiquer toutes les valeurs à saisir sur toutes les pages
  35. * comme si il s'agissait d'un formulaire unique
  36. *
  37. * Vérifier :
  38. * Le numero d'étape courante est disponible dans `$x=_request('_etape')`, si nécessaire
  39. * `_request()` permet d'accéder aux saisies effectuées depuis l'étape 1,
  40. * comme si les étapes 1 a `$x` avaient été saisies en une seule fois
  41. *
  42. * - formulaires_truc_verifier_1_dist() : verifier les saisies de l'etape 1 uniquement
  43. * - formulaires_truc_verifier_2_dist() : verifier les saisies de l'etape 2
  44. * - formulaires_truc_verifier_n_dist() : verifier les saisies de l'etape n
  45. *
  46. * Il est possible d'implémenter toutes les vérifications dans une fonction unique
  47. * qui sera alors appelée avec en premier argument le numero de l'étape à vérifier
  48. * `formulaires_truc_verifier_etape_dist($etape,...)` : vérifier les saisies
  49. * de l'étape `$etape` uniquement.
  50. *
  51. * À chaque étape x, les étapes 1 a x sont appelées en vérification
  52. * pour vérifier l'absence de régression dans la validation (erreur, tentative de réinjection ...)
  53. * en cas d'erreur, la saisie retourne à la première étape en erreur.
  54. * en cas de succès, l'étape est incrémentée, sauf si c'est la dernière.
  55. * Dans ce dernier cas on déclenche `traiter()`.
  56. *
  57. * Traiter :
  58. * `formulaires_truc_traiter_dist()` : ne sera appelé que lorsque **toutes**
  59. * les étapes auront été saisies sans erreur.
  60. *
  61. * La fonction traiter peut donc traiter l'ensemble des saisies comme si il
  62. * s'agissait d'un formulaire unique dans lequel toutes les données auraient
  63. * été saisies en une fois.
  64. */
  65. if (!defined('_ECRIRE_INC_VERSION')) {
  66. return;
  67. }
  68. /**
  69. * Reinjecter dans _request() les valeurs postees
  70. * dans les etapes precedentes
  71. *
  72. * @param string $form
  73. * @return array
  74. */
  75. function cvtmulti_recuperer_post_precedents($form) {
  76. include_spip('inc/filtres');
  77. if ($form
  78. and $c = _request('cvtm_prev_post')
  79. and $c = decoder_contexte_ajax($c, $form)
  80. ) {
  81. #var_dump($c);
  82. # reinjecter dans la bonne variable pour permettre de retrouver
  83. # toutes les saisies dans un seul tableau
  84. if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  85. $store = &$_POST;
  86. } else {
  87. $store = &$_GET;
  88. }
  89. foreach ($c as $k => $v) // on ecrase pas si saisi a nouveau !
  90. {
  91. if (!isset($store[$k])) {
  92. $_REQUEST[$k] = $store[$k] = $v;
  93. } // mais si tableau des deux cotes, on merge avec priorite a la derniere saisie
  94. elseif (is_array($store[$k])
  95. and is_array($v)
  96. and $z = array_keys($v)
  97. and !is_numeric(reset($z))
  98. and $z = array_keys($store[$k])
  99. and !is_numeric(reset($z))
  100. ) {
  101. $_REQUEST[$k] = $store[$k] = array_merge($v, $store[$k]);
  102. }
  103. }
  104. // vider pour eviter un second appel a verifier_n
  105. // en cas de double implementation (unipotence)
  106. set_request('cvtm_prev_post');
  107. return array($c['_etape'], $c['_etapes']);
  108. }
  109. return false;
  110. }
  111. /**
  112. * Sauvegarder les valeurs postees dans une variable encodee
  113. * pour les recuperer a la prochaine etape
  114. *
  115. * @param string $form
  116. * @param bool $je_suis_poste
  117. * @param array $valeurs
  118. * @return array
  119. */
  120. function cvtmulti_sauver_post($form, $je_suis_poste, &$valeurs) {
  121. if (!isset($valeurs['_cvtm_prev_post'])) {
  122. $post = array('_etape' => $valeurs['_etape'], '_etapes' => $valeurs['_etapes']);
  123. foreach (array_keys($valeurs) as $champ) {
  124. if (substr($champ, 0, 1) !== '_') {
  125. if ($je_suis_poste || (isset($valeurs['_forcer_request']) && $valeurs['_forcer_request'])) {
  126. if (($v = _request($champ)) !== null) {
  127. $post[$champ] = $v;
  128. }
  129. }
  130. }
  131. }
  132. include_spip('inc/filtres');
  133. $c = encoder_contexte_ajax($post, $form);
  134. if (!isset($valeurs['_hidden'])) {
  135. $valeurs['_hidden'] = '';
  136. }
  137. $valeurs['_hidden'] .= "<input type='hidden' name='cvtm_prev_post' value='$c' />";
  138. // marquer comme fait, pour eviter double encodage (unipotence)
  139. $valeurs['_cvtm_prev_post'] = true;
  140. }
  141. return $valeurs;
  142. }
  143. /**
  144. * Reperer une demande de formulaire CVT multi page
  145. * et la reformater
  146. *
  147. * @deprecated : appel direct de cvtmulti_formulaire_charger_etapes par le core
  148. * @param array $flux
  149. * @return array
  150. */
  151. function cvtmulti_formulaire_charger($flux) {
  152. if (is_array($flux['data'])
  153. and isset($flux['data']['_etapes'])
  154. ) {
  155. $flux['data'] = cvtmulti_formulaire_charger_etapes($flux['args'], $flux['data']);
  156. }
  157. return $flux;
  158. }
  159. /**
  160. * Charger une etape du cvt multi
  161. * @param $args
  162. * @param $valeurs
  163. * @return array
  164. */
  165. function cvtmulti_formulaire_charger_etapes($args, $valeurs) {
  166. if (!isset($valeurs['_etape'])) {
  167. $form = $args['form'];
  168. $je_suis_poste = $args['je_suis_poste'];
  169. $nb_etapes = $valeurs['_etapes'];
  170. $etape = _request('_etape');
  171. $etape = min(max($etape, 1), $nb_etapes);
  172. set_request('_etape', $etape);
  173. $valeurs['_etape'] = $etape;
  174. // sauver les posts de cette etape pour les avoir a la prochaine etape
  175. $valeurs = cvtmulti_sauver_post($form, $je_suis_poste, $valeurs);
  176. }
  177. return $valeurs;
  178. }
  179. /**
  180. * Verifier les etapes de saisie
  181. *
  182. * @deprecated : appel direct de cvtmulti_formulaire_verifier_etapes par le core
  183. * @param array $flux
  184. * @return array
  185. */
  186. function cvtmulti_formulaire_verifier($flux) {
  187. $flux['data'] = cvtmulti_formulaire_verifier_etapes($flux['args'], $flux['data']);
  188. return $flux;
  189. }
  190. /**
  191. * Verifier les etapes de saisie
  192. *
  193. * @param array $args
  194. * @param $erreurs
  195. * @return array
  196. */
  197. function cvtmulti_formulaire_verifier_etapes($args, $erreurs) {
  198. #var_dump('Pipe verifier');
  199. if ($form = $args['form']
  200. and ($e = cvtmulti_recuperer_post_precedents($form)) !== false
  201. ) {
  202. // recuperer l'etape saisie et le nombre d'etapes total
  203. list($etape, $etapes) = $e;
  204. $etape_demandee = _request('aller_a_etape'); // possibilite de poster en entier dans aller_a_etape
  205. // lancer les verifs pour chaque etape deja saisie de 1 a $etape
  206. $erreurs_etapes = array();
  207. $derniere_etape_ok = 0;
  208. $e = 0;
  209. while ($e < $etape and $e < $etapes) {
  210. $e++;
  211. $erreurs_etapes[$e] = array();
  212. if ($verifier = charger_fonction("verifier_$e", "formulaires/$form/", true)) {
  213. $erreurs_etapes[$e] = call_user_func_array($verifier, $args['args']);
  214. } elseif ($verifier = charger_fonction("verifier_etape", "formulaires/$form/", true)) {
  215. $a = $args['args'];
  216. array_unshift($a, $e);
  217. $erreurs_etapes[$e] = call_user_func_array($verifier, $a);
  218. }
  219. // et on appelle un pipeline dedie aux etapes, plus easy
  220. $args['etape'] = $e;
  221. $erreurs_etapes[$e] = pipeline(
  222. 'formulaire_verifier_etape',
  223. array(
  224. 'args' => $args,
  225. 'data' => $erreurs_etapes[$e]
  226. )
  227. );
  228. if ($derniere_etape_ok == $e - 1 and !count($erreurs_etapes[$e])) {
  229. $derniere_etape_ok = $e;
  230. }
  231. // possibilite de poster dans _retour_etape_x
  232. if (!is_null(_request("_retour_etape_$e"))) {
  233. $etape_demandee = $e;
  234. }
  235. }
  236. // si la derniere etape OK etait la derniere
  237. // on renvoie le flux inchange et ca declenche traiter
  238. if ($derniere_etape_ok == $etapes and !$etape_demandee) {
  239. return $erreurs;
  240. } else {
  241. $etape = $derniere_etape_ok + 1;
  242. if ($etape_demandee > 0 and $etape_demandee < $etape) {
  243. $etape = $etape_demandee;
  244. }
  245. $etape = min($etape, $etapes);
  246. #var_dump("prochaine etape $etape");
  247. // retourner les erreurs de l'etape ciblee
  248. $erreurs = isset($erreurs_etapes[$etape]) ? $erreurs_etapes[$etape] : array();
  249. // Ne pas se tromper dans le texte du message d'erreur : la clé '_etapes' n'est pas une erreur !
  250. if ($erreurs) {
  251. $erreurs['message_erreur'] = singulier_ou_pluriel(count($erreurs), 'avis_1_erreur_saisie', 'avis_nb_erreurs_saisie');
  252. } else {
  253. $erreurs['message_erreur'] = "";
  254. }
  255. $erreurs['_etapes'] = "etape suivante $etape";
  256. set_request('_etape', $etape);
  257. }
  258. }
  259. return $erreurs;
  260. }
  261. /**
  262. * Selectionner le bon fond en fonction de l'etape
  263. * L'etape 1 est sur le fond sans suffixe
  264. * Les autres etapes x sont sur le fond _x
  265. *
  266. * @param array $flux
  267. * @return array
  268. */
  269. function cvtmulti_styliser($flux) {
  270. if (strncmp($flux['args']['fond'], 'formulaires/', 12) == 0
  271. and isset($flux['args']['contexte']['_etapes'])
  272. and isset($flux['args']['contexte']['_etape'])
  273. and ($e = $flux['args']['contexte']['_etape']) > 1
  274. and $ext = $flux['args']['ext']
  275. and $f = $flux['data']
  276. and file_exists($f . "_$e.$ext")
  277. ) {
  278. $flux['data'] = $f . "_$e";
  279. }
  280. return $flux;
  281. }