22ca009115db7aa31226c7dd478ceae22e790700
[lhc/web/www.git] / www / ecrire / inc / cvt_autosave.php
1 <?php
2
3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
5 * *
6 * Copyright (c) 2001-2019 *
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 /**
14 * Sauvegarde automatique des formulaires CVT
15 *
16 * @package SPIP\Core\CVT\Autosave
17 */
18
19 if (!defined('_ECRIRE_INC_VERSION')) {
20 return;
21 }
22
23 /**
24 * Nettoyer les échappements
25 *
26 * @param $val
27 * @return string
28 */
29 function autosave_clean_value($val) {
30 return stripslashes(urldecode($val));
31 }
32
33 /**
34 * Repérer une demande de formulaire autosave
35 * et la conditionner
36 *
37 * @param array $flux
38 * @return array
39 */
40 function cvtautosave_formulaire_charger($flux) {
41 if (is_array($flux['data'])
42 and isset($flux['data']['_autosave_id'])
43 and $cle_autosave = $flux['data']['_autosave_id']
44 ) {
45
46 $form = $flux['args']['form'];
47 $je_suis_poste = $flux['args']['je_suis_poste'];
48
49 $cle_autosave = serialize($cle_autosave);
50 $cle_autosave = $form . "_" . md5($cle_autosave);
51
52 // si on a un backup en session et qu'on est au premier chargement, non poste
53 // on restitue les donnees
54 if (isset($GLOBALS['visiteur_session']['session_autosave_' . $cle_autosave])
55 and !$je_suis_poste
56 ) {
57 parse_str($GLOBALS['visiteur_session']['session_autosave_' . $cle_autosave], $vars);
58 foreach ($vars as $key => $val) {
59 if (isset($flux['data'][$key])) {
60 $flux['data'][$key] = (is_string($val) ? autosave_clean_value($val) : array_map('autosave_clean_value',
61 $val));
62 }
63 }
64 }
65
66 // si on est dans le charger() qui suit le traiter(), l'autosave a normalement ete vide
67 // mais si il y a plusieurs sessions il peut y avoir concurrence et un retour de l'autosave
68 if ($je_suis_poste and _request('autosave') === $cle_autosave and function_exists('terminer_actualiser_sessions')) {
69 terminer_actualiser_sessions();
70 // et verifions si jamais l'autosave a fait un come back, dans ce cas on le revide
71 if (isset($GLOBALS['visiteur_session']['session_autosave_' . $cle_autosave])) {
72 session_set('session_autosave_' . $cle_autosave, null);
73 // en court sleep pour etre certain que la concurrence est finie
74 sleep(1);
75 terminer_actualiser_sessions();
76 }
77 }
78
79
80 /**
81 * Envoyer le input hidden et le bout de js qui l'utilisera
82 */
83 $flux['data']['_hidden'] .= "<input type='hidden' name='autosave' class='autosaveactive' value='$cle_autosave' />"
84 . '<script type="text/javascript">/*<![CDATA[*/if (window.jQuery) jQuery(function(){
85 $("input.autosaveactive").closest("form:not(.autosaveon)").autosave({url:"' . $GLOBALS['meta']['adresse_site'] . '/"}).addClass("autosaveon");
86 });/*]]>*/</script>';
87
88 }
89
90 return $flux;
91 }
92
93 /**
94 * Traitement d'un formulaire ayant activé `autosave`
95 *
96 * Quand on poste définitivement un formulaire `autosave`,
97 * on peut vider la session `autosave`
98 * et on vide aussi toutes les `autosave` de plus de 72H (délai par défaut) ou sans `__timestamp` (vieilles sessions)
99 *
100 * @param array $flux
101 * @return array
102 */
103 function cvtautosave_formulaire_traiter($flux) {
104 // si on poste 'autosave' c'est qu'on n'a plus besoin de sauvegarder :
105 // on elimine les donnees de la session
106 if ($cle_autosave = _request('autosave')) {
107 include_spip('inc/session');
108 session_set('session_autosave_' . $cle_autosave, null);
109 }
110
111 if (isset($GLOBALS['visiteur_session']) and $GLOBALS['visiteur_session']) {
112 // delai par defaut avant purge d'un backup de form : 72H
113 if (!defined('_AUTOSAVE_GB_DELAY')) {
114 define('_AUTOSAVE_GB_DELAY', 72 * 3600);
115 }
116 $time_too_old = time() - _AUTOSAVE_GB_DELAY;
117 // purger aussi toutes les vieilles autosave
118 $session = $GLOBALS['visiteur_session'];
119 foreach ($session as $k => $v) {
120 if (strncmp($k, 'session_autosave_', 17) == 0) {
121 $timestamp = 0;
122 if (preg_match(",&__timestamp=(\d+)$,", $v, $m)) {
123 $timestamp = intval($m[1]);
124 }
125 if ($timestamp < $time_too_old) {
126 session_set($k, null);
127 }
128 }
129 }
130 }
131
132 return $flux;
133 }