Valider 8bf0cfbd rédigé par cerdic's avatar cerdic
Parcourir les fichiers

Résoud #1442 : Gestion automatisée et généralisée de la sauvegarde automatique...

Résoud #1442 : Gestion automatisée et généralisée de la sauvegarde automatique en session des formulaires CVT
En pratique, il suffit de fournir dans le charger() d'un CVT un identifiant unique dans _autosave_id pour que le formulaire soit automatiquement sauvegardé quand on quitte la page sans le soumettre.

On reprend ce qui a été introduit dans l'extension forum, et on generalise via les pipeline charger et traiter de CVT
A noter que n'importe quel type d'objet peut servir comme identifiant unique, il sera serializé puis hashé ensuite, et préfixé par le nom du formulaire pour faciliter la lecture en session (et les collisions entre formulaires différents).

Toutes les saisies du formulaires sont sauvegardées, et le décodage supporte les valeurs sous forme de tableau.

Par ailleurs, on ne vide la sauvegarde que quand traiter est appelé (la prévisu faisait perdre la sauvegarde dans l'implémentation existante), et on horodate les sauvegardes pour permettre le garbage collecting des sauvegardes de plus de 72h en session (delai surchargeable par la constante _AUTOSAVE_GB_DELAY)
parent 70623243
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+1 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -106,6 +106,7 @@ ecrire/inc/commencer_page.php -text
ecrire/inc/cookie.php -text
ecrire/inc/couleurs.php -text
ecrire/inc/csv.php -text
ecrire/inc/cvt_autosave.php -text
ecrire/inc/cvt_configurer.php -text
ecrire/inc/cvt_multietapes.php -text
ecrire/inc/distant.php -text
+1 −1
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -26,7 +26,7 @@ function action_session_dist()
	}

	# TODO: mode lecture de session ; n'afficher que ce qu'il faut
	# json_encode($GLOBALS['visiteur_session'])
	# json_encode($GLOBALS['visiteur_session']);
}


+92 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
<?php

/***************************************************************************\
 *  SPIP, Systeme de publication pour l'internet                           *
 *                                                                         *
 *  Copyright (c) 2001-2011                                                *
 *  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;


function autosave_clean_value($val){
	return stripslashes(urldecode($val));
}

/**
 * Reperer une demande de formulaire autosave
 * et la conditionner
 *
 * @param array $flux
 * @return array
 */
function cvtautosave_formulaire_charger($flux){
	if (isset($flux['data']['_autosave_id'])
	  AND $cle_autosave = $flux['data']['_autosave_id']){

		$form = $flux['args']['form'];
		$je_suis_poste = $flux['args']['je_suis_poste'];

		$cle_autosave = serialize($cle_autosave);
		$cle_autosave = $form."_".md5($cle_autosave);

		// si on a un backup en session et qu'on est au premier chargement, non poste
		// on restitue les donnees
		if (isset($GLOBALS['visiteur_session']['session_autosave_'.$cle_autosave])
		  AND !$je_suis_poste) {
			parse_str($GLOBALS['visiteur_session']['session_autosave_'.$cle_autosave], $vars);
			foreach ($vars as $key=>$val) {
				if (isset($flux['data'][$key]))
					$flux['data'][$key] = (is_string($val)?autosave_clean_value($val):array_map('autosave_clean_value',$val));
			}
		}

		/**
		 * Envoyer le input hidden et le bout de js qui l'utilisera
		 */
		$flux['data']['_hidden'] .= "<input type='hidden' name='autosave' class='autosaveactive' value='$cle_autosave' />"
		  .'<script type="text/javascript">/*<![CDATA[*/if (window.jQuery)(function($){$(function(){
		  $("input.autosaveactive").closest("form:not(.autosaveon)").autosave().addClass("autosaveon");
			});}(jQuery));/*]]>*/</script>';

	}
	return $flux;
}

/**
 * Quand on poste definitivement un formulaire autosave,
 * on peut vider la session autosave
 * et on vide aussi toutes les autosave de plus de 72H (delai par defaut) ou sans __timestamp (vieilles sessions)
 * @param $flux
 * @return
 */
function cvtautosave_formulaire_traiter($flux){
	// si on poste 'autosave' c'est qu'on n'a plus besoin de sauvegarder :
	// on elimine les donnees de la session
	if ($cle_autosave = _request('autosave')){
		include_spip('inc/session');
		session_set('session_autosave_'.$cle_autosave, null);

		// delai par defaut avant purge d'un backup de form : 72H
		if (!defined('_AUTOSAVE_GB_DELAY')) define('_AUTOSAVE_GB_DELAY',72*3600);
		$time_too_old = time() - _AUTOSAVE_GB_DELAY;
		// purger aussi toutes les vieilles autosave
		foreach($GLOBALS['visiteur_session'] as $k=>$v){
			if (strncmp($k,'session_autosave_',17)==0){
				$timestamp = 0;
				if (preg_match(",&__timestamp=(\d+)$,",$v,$m)){
					$timestamp = intval($m[1]);
				}
				if ($timestamp<$time_too_old)
					session_set($k, null);
			}
		}
	}
	return $flux;
}

+8 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -268,6 +268,10 @@ Le programme est n&eacute; en 2001 d'une initiative du minir&eacute;zo, un colle
		<action>cvtconf_formulaire_charger</action>
		<inclure>inc/cvt_configurer.php</inclure>
	</pipeline>
	<pipeline><nom>formulaire_charger</nom>
		<action>cvtautosave_formulaire_charger</action>
		<inclure>inc/cvt_autosave.php</inclure>
	</pipeline>
	<pipeline><nom>formulaire_verifier</nom>
		<action>cvtmulti_formulaire_verifier</action>
		<inclure>inc/cvt_multietapes.php</inclure>
@@ -276,6 +280,10 @@ Le programme est n&eacute; en 2001 d'une initiative du minir&eacute;zo, un colle
		<action>cvtconf_formulaire_traiter</action>
		<inclure>inc/cvt_configurer.php</inclure>
	</pipeline>
	<pipeline><nom>formulaire_traiter</nom>
		<action>cvtautosave_formulaire_traiter</action>
		<inclure>inc/cvt_autosave.php</inclure>
	</pipeline>
	<pipeline><nom>formulaire_admin</nom><action></action></pipeline>
	<pipeline><nom>header_prive</nom>
		<action>f_jQuery_prive</action>
+3 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -25,6 +25,9 @@
			.each(function(){
				if (!opt.confirm || confirm(opt.confirmstring)) {
					var contenu = $(this).serialize();
					// ajoutons un timestamp
					var d=new Date();
					contenu = contenu + "&__timestamp=" + d.getTime();
					$.post('spip.php', {
						'action': 'session',
						'var': 'autosave_' + $('input[name=autosave]', this).val(),