From 4da796fbac9f4c62279c8d961d7b0d1d4d85a5b9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ma=C3=AFeul=20Rouquette?= <maieul@maieul.net>
Date: Tue, 10 May 2022 16:15:02 +0200
Subject: [PATCH] =?UTF-8?q?D=C3=A9but=20pour=20le=20passage=20du=20stockag?=
 =?UTF-8?q?e=20de=20`serialize`=20=C3=A0=20`json=5Fencode()`.=20-=20Le=20f?=
 =?UTF-8?q?iltre=20`|tenter=5Funserialize`=20est=20d=C3=A9pr=C3=A9ci=C3=A9?=
 =?UTF-8?q?.=20-=20Il=20est=20remplac=C3=A9=20par=20`|formidable=5Fdeseria?=
 =?UTF-8?q?lize`.=20-=20Ce=20filtre=20peut=20recevoir=20au=20choix=20:=20?=
 =?UTF-8?q?=20=20*=20Un=20tableau,=20qu'il=20retourne=20tel=20quel=20=20?=
 =?UTF-8?q?=20*=20Un=20tableau=20serializ=C3=A9=20via=20`json=5Fencode`=20?=
 =?UTF-8?q?=20=20*=20Un=20tableau=20serializ=C3=A9=20via=20`serialize`=20-?=
 =?UTF-8?q?=20Dans=20les=20deux=20dernier=20cas,=20il=20renvoie=20la=20ver?=
 =?UTF-8?q?sion=20deserializ=C3=A9,=20en=20cas=20de=20r=C3=A9ussite,=20sin?=
 =?UTF-8?q?on=20l'argument=20pass=C3=A9.?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Exemple

````
include_spip('formidable_fonctions');
'filtre');
$a = ['a' => 'a'];

$a = json_encode($a);
var_dump($a);

$a = formidable_deserialize($a);
var_dump($a);

$a = serialize($a);
var_dump($a);

$a = formidable_deserialize($a);
var_dump($a);

$a = serialize($a).'plop';//Serialisation corrompu
var_dump($a);

$a = formidable_deserialize($a);
var_dump($a);
````

Ainsi, pas besoin de convertir tous les formulaires de `serialize`  à
`json_encode`  à la mise à jour du plugin formidable :
on peut le faire au fur à mesure qu'on modifie les champs/traitements
d'un formulaire.

On utilisera donc ce filtre à chaque fois que l'on veut déchiffrer
depuis la BDD :
- * traitements d'un formulaire
- * saisies d'un formulaire
- * réponse d'un champ multivalué (ex: checkbox)
---
 CHANGELOG.md                                  | 10 ++++
 afficher_diff/array_serialized.php            |  6 +--
 controleurs/formulaires_reponses_champ.php    | 11 +++--
 echanger/formulaire/yaml.php                  |  5 +-
 filtre/tenter_unserialize.php                 | 16 +++++++
 formidable_autorisations.php                  |  3 +-
 formidable_fonctions.php                      | 48 +++++++++++++++++--
 formidable_pipelines.php                      |  3 +-
 formulaires/editer_formulaire_champs.php      | 14 +++---
 formulaires/editer_formulaire_traitements.php |  7 +--
 formulaires/exporter_formulaire_analyse.php   | 13 ++---
 formulaires/exporter_formulaire_reponses.php  | 18 +++----
 formulaires/formidable.php                    | 29 ++++++-----
 genie/formidable_effacer_enregistrements.php  |  4 +-
 http/collectionjson/inc-formulaire.html       |  4 +-
 inc/formidable.php                            | 24 +---------
 modeles/formulaire_aide_memoire.html          |  2 +-
 modeles/formulaire_analyse.html               |  6 +--
 modeles/formulaires_reponse.html              |  4 +-
 prive/squelettes/contenu/formulaire.html      |  2 +-
 20 files changed, 143 insertions(+), 86 deletions(-)
 create mode 100644 filtre/tenter_unserialize.php

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68157c66..61130e26 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,11 @@
 
 - Lors de la construction du formulaire, vérifier à la fin si les champs conditionnant des affichages sont bien présents, retourner un message d'erreur dans le cas contraire
 - #105 Ajout des pipelines `formidable_pre_raccourcis_arobases` et `formidable_post_raccourcis_arobases` pour ajustement les traitements avant/après l'interprétation des raccourcis `@champs@`
+- #99 #111 Ajout du filtre `|formidable_deserialize` qui reçoit au choix :
+ * Un tableau déjà déserializé
+ * Un tableau serializé via `json_encode()`
+ * Un tableau serializé via `serialize()`
+ Et renvoie le tableau deserializé, ou la valeur reçue en cas d'échec.
 
 ### Changed
 
@@ -36,6 +41,11 @@
 ### Removed
 
 - #105 pipeline `formidable_affiche_resume_reponse` supprimé, remplacée par `formidable_pre_raccourcis_arobases` et  `formidable_post_raccourcis_arobases`
+
+### Deprecated
+
+- Filtre `tenter_unserialize`, utiliser à la place `formidable_deserialize`
+
 ### Fixed
 
 - #114 Afficher correctement les erreurs lors de la saisie d'une configuration de formulaire
diff --git a/afficher_diff/array_serialized.php b/afficher_diff/array_serialized.php
index 08cd4a0c..0956bd2e 100644
--- a/afficher_diff/array_serialized.php
+++ b/afficher_diff/array_serialized.php
@@ -18,9 +18,9 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 function afficher_diff_array_serialized($champ, $old, $new, $format = 'diff') {
 	// Pour le diff de saisies, faire comme un diff de yaml
 	include_spip('inc/yaml');
-	$tenter_unserialize = charger_fonction('tenter_unserialize', 'filtre/');
-	$new = $tenter_unserialize($new);
-	$old = $tenter_unserialize($old);
+	include_spip('formidable_fonctions');
+	$new = formidable_deserialize($new);
+	$old = formidable_deserialize($old);
 	if (is_array($new)) {
 		$new = yaml_encode($new);
 	} else {
diff --git a/controleurs/formulaires_reponses_champ.php b/controleurs/formulaires_reponses_champ.php
index c27ae697..73073ed9 100644
--- a/controleurs/formulaires_reponses_champ.php
+++ b/controleurs/formulaires_reponses_champ.php
@@ -9,6 +9,8 @@
  */
 function controleurs_formulaires_reponses_champ_dist($regs, $c = null) {
 	include_spip('inc/saisies');
+	include_spip('formidable_fonctions');
+
 	list(,$crayon, $type, $champ, $id) = $regs;
 	$id_formulaires_reponses_champ = $regs[4];
 
@@ -27,7 +29,10 @@ function controleurs_formulaires_reponses_champ_dist($regs, $c = null) {
 
 	$nom = $data['nom'];
 	$valeur = $data['valeur'];
-	$saisie = saisies_chercher(unserialize($data['saisies']), $nom);
+	$saisie = saisies_chercher(
+		formidable_deserialize($data['saisies']),
+	 	$nom
+	);
 	$valeur = $data['valeur'];
 
 	$n = new Crayon(
@@ -41,11 +46,11 @@ function controleurs_formulaires_reponses_champ_dist($regs, $c = null) {
 	unset($saisie['options']['explication']);
 	unset($saisie['options']['class']);
 	unset($saisie['options']['conteneur_class']);
+
 	// Crayons utilise son propre formalisme pour le 'name' des saisies.
 	$nom_crayons = 'content_' . $key . '_valeur';
 	$saisie['options']['nom'] = $nom_crayons;
-	include_spip('inc/formidable');
-	$valeur = filtre_tenter_unserialize_dist($valeur);// Pour une raison mystérieuse, charger_fonction déclenche une erreur (!)
+	$valeur = formidable_deserialize($valeur);
 	$contexte = array('_saisies' => array($saisie), $nom_crayons =>  $valeur);
 	$html = $n->formulaire($contexte);
 
diff --git a/echanger/formulaire/yaml.php b/echanger/formulaire/yaml.php
index 56db6002..ecad9e01 100644
--- a/echanger/formulaire/yaml.php
+++ b/echanger/formulaire/yaml.php
@@ -7,6 +7,7 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 
 function echanger_formulaire_yaml_exporter_dist($id_formulaire) {
 	include_spip('base/abstract_sql');
+	include_spip('formidable_fonctions');
 	include_spip('inc/yaml');
 	$id_formulaire = intval($id_formulaire);
 	$export = '';
@@ -20,8 +21,8 @@ function echanger_formulaire_yaml_exporter_dist($id_formulaire) {
 		);
 
 		// On décompresse les trucs sérialisés
-		$formulaire['saisies'] = unserialize($formulaire['saisies']);
-		$formulaire['traitements'] = unserialize($formulaire['traitements']);
+		$formulaire['saisies'] = formidable_deserialize($formulaire['saisies']);
+		$formulaire['traitements'] = formidable_deserialize($formulaire['traitements']);
 
 		// On envode en yaml
 		$export = yaml_encode($formulaire);
diff --git a/filtre/tenter_unserialize.php b/filtre/tenter_unserialize.php
new file mode 100644
index 00000000..4a9d86e1
--- /dev/null
+++ b/filtre/tenter_unserialize.php
@@ -0,0 +1,16 @@
+<?php
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+	return;
+}
+
+/**
+ * @deprecated
+ * @see `filtre_formidable_deserialize_dist()`
+ * @param string|array $texte
+ * @return array|string
+**/
+function filtre_tenter_deserialize_dist($texte) {
+	include_spip('formidable_fonctions');
+	return formidable_deserialize($texte);
+}
diff --git a/formidable_autorisations.php b/formidable_autorisations.php
index c1a3bac0..a25c810f 100644
--- a/formidable_autorisations.php
+++ b/formidable_autorisations.php
@@ -157,7 +157,8 @@ function autoriser_formulaire_repondre_dist($faire, $type, $id, $qui, $opt) {
 		$formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = '.$id);
 	}
 
-	$traitements = unserialize($formulaire['traitements']);
+	include_spip('formidable_fonctions');
+	$traitements = formidable_deserialize($formulaire['traitements']);
 
 	// S'il n'y a pas d'enregistrement, c'est forcément bon
 	if (!isset($traitements['enregistrement']) or !($options = $traitements['enregistrement'])) {
diff --git a/formidable_fonctions.php b/formidable_fonctions.php
index 0fa36105..ccb55eec 100644
--- a/formidable_fonctions.php
+++ b/formidable_fonctions.php
@@ -13,6 +13,7 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 include_spip('inc/formidable');
 include_spip('public/formidable_criteres');
 
+include_spip('filtre/tenter_unserialize');// Obsolète
 /**
  * #VOIR_REPONSE{checkbox_2} dans une boucle (FORMULAIRES_REPONSES)
  *
@@ -55,11 +56,11 @@ function balise_VOIR_REPONSE_dist($p) {
 function calculer_voir_reponse($id_formulaires_reponse, $id_formulaire, $nom, $sql_serveur = '', $type_retour = null, $sans_reponse = null) {
 	static $formulaires_saisies = array();
 	static $reponses_valeurs = array();
-	$tenter_unserialize = charger_fonction('tenter_unserialize', 'filtre/');
+	include_spip('formidable_fonctions');
 
 	// Si pas déjà présent, on cherche les saisies de ce formulaire
 	if (!isset($formulaires_saisies[$id_formulaire])) {
-		$formulaires_saisies[$id_formulaire] = unserialize(
+		$formulaires_saisies[$id_formulaire] = formidable_deserialize(
 			sql_getfetsel('saisies',//select
 			'spip_formulaires',//from
 			'id_formulaire = '.intval($id_formulaire),//where
@@ -86,7 +87,7 @@ function calculer_voir_reponse($id_formulaires_reponse, $id_formulaire, $nom, $s
 			foreach ($champs as $champ) {
 				$reponses_valeurs[$id_formulaires_reponse][$champ['nom']] = array(
 					'valeur' =>  formidable_ajouter_action_recuperer_fichier(
-						$tenter_unserialize($champ['valeur']),
+						formidable_deserialize($champ['valeur']),
 						$champ['nom'],
 						$formulaires_saisies[$id_formulaire],
 						$id_formulaire,
@@ -151,6 +152,8 @@ function affiche_resume_reponse($id_formulaires_reponse, $id_formulaire = null,
 	static $modeles_resume = array();
 	static $saisies_form = array();
 
+	include_spip('formidable_fonctions');
+
 	if (is_null($id_formulaire)) {
 		$id_formulaire = sql_getfetsel(
 			'id_formulaire',
@@ -161,9 +164,9 @@ function affiche_resume_reponse($id_formulaires_reponse, $id_formulaire = null,
 
 	if (is_null($modele_resume) and !isset($modeles_resume[$id_formulaire])) {
 		$row = sql_fetsel('saisies, traitements', 'spip_formulaires', 'id_formulaire='.intval($id_formulaire));
-		$saisies = unserialize($row['saisies']);
+		$saisies = formidable_deserialize($row['saisies']);
 		$saisies_form[$id_formulaire] = $saisies;
-		$traitements = unserialize($row['traitements']);
+		$traitements = formidable_deserialize($row['traitements']);
 		if (isset($traitements['enregistrement']['resume_reponse'])) {
 			$modeles_resume[$id_formulaire] = $traitements['enregistrement']['resume_reponse'];
 		} else {
@@ -288,3 +291,38 @@ function formidable_afficher_statut_si_different_de($statut,$not_in = array()) {
 
 	return '';
 }
+
+/**
+ * Tente de déserialiser un texte
+ *
+ * Si le paramètre est un tableau, retourne le tableau,
+ * Si c'est une chaîne, tente de la désérialiser
+ *	- d'abord depuis du JSON
+ *	- puis depuis de la serialsation par défaut
+ * Si échec, retourne la chaîne
+ * retourne la chaîne.
+ *
+ * @filtre
+ *
+ * @param string|array $texte
+ *	 Le texte (possiblement sérializé) ou un tableau
+ * @return array|string
+ *	 Tableau, texte désérializé ou texte
+**/
+function formidable_deserialize($texte) {
+	// Cas 1. Deja tableau
+	if (is_array($texte)) {
+		return $texte;
+	}
+	// Cas 2. Tableau serializé en json
+	$tmp = json_decode($texte, true);
+	if (is_array($tmp)) {
+		return $tmp;
+	}
+	// Cas 3. Tableau serializé en PHP, si jamais ca echout on renvoie le texte
+	$tmp = @unserialize($texte);
+	if (is_array($tmp)) {
+		return $tmp;
+	}
+	return $texte;
+}
diff --git a/formidable_pipelines.php b/formidable_pipelines.php
index e27756a7..301b8041 100644
--- a/formidable_pipelines.php
+++ b/formidable_pipelines.php
@@ -362,7 +362,8 @@ function formidable_crayons_verifier($flux) {
 		['spip_formulaires_reponses_champs AS c', 'spip_formulaires_reponses AS r', 'spip_formulaires AS f'],
 		["id_formulaires_reponses_champ = $id",  'r.id_formulaires_reponse = c.id_formulaires_reponse', 'f.id_formulaire = r.id_formulaire']
 	);
-	$saisies = unserialize($data['saisies']);
+	include_spip('formidable_fonctions');
+	$saisies = formidable_deserialize($data['saisies']);
 	$saisie = saisies_chercher($saisies, $data['nom']);
 	if (saisies_saisie_est_tabulaire($saisie)) {
 		$atrouver = 'content_'.$flux['args']['wid'].'_valeur';
diff --git a/formulaires/editer_formulaire_champs.php b/formulaires/editer_formulaire_champs.php
index 26ff718e..c1b2ef9c 100644
--- a/formulaires/editer_formulaire_champs.php
+++ b/formulaires/editer_formulaire_champs.php
@@ -9,19 +9,20 @@ function formulaires_editer_formulaire_champs_charger($id_formulaire) {
 	$id_formulaire = intval($id_formulaire);
 	$contexte = array();
 	$contexte['id_formulaire'] = $id_formulaire;
+	include_spip('formidable_fonctions');
 
 	// On teste si le formulaire existe
 	if ($id_formulaire
 		and $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = '.$id_formulaire)
 		and autoriser('editer', 'formulaire', $id_formulaire)
 	) {
-		$saisies = unserialize($formulaire['saisies']);
+		$saisies = formidable_deserialize($formulaire['saisies']);
 
 		// Est-ce qu'on restaure une révision ?
 		if ($id_version = _request('id_version')) {
 			include_spip('inc/revisions');
 			$old = recuperer_version($id_formulaire, 'formulaire', $id_version);
-			$saisies = unserialize($old['saisies']);
+			$saisies = formidable_deserialize($old['saisies']);
 		}
 		if (!is_array($saisies)) {
 			$saisies = array();
@@ -157,7 +158,7 @@ function formulaires_editer_formulaire_champs_charger($id_formulaire) {
 function formulaires_editer_formulaire_champs_verifier($id_formulaire) {
 	include_spip('inc/saisies');
 	$erreurs = array();
-
+	include_spip('formidable_fonctions');
 	// Si c'est pas une confirmation ni une annulation, ni un revert
 	if (!_request('enregistrer_confirmation')
 		and !($annulation = _request('annulation'))
@@ -182,7 +183,7 @@ function formulaires_editer_formulaire_champs_verifier($id_formulaire) {
 		// Attention à s'assurer que tout les elements du tableau soit bien soit des tableaux, soit un string
 		// En effet, le md5 du formulaire_initial est calculé à partir de ce qui est passé au squelette
 		// Or dès qu'une valeur est passée à un squelette, elle est changé en string, à cause du mode de compilation (?)
-		$saisies_anciennes = unserialize($saisies_anciennes);
+		$saisies_anciennes = formidable_deserialize($saisies_anciennes);
 		$saisies_anciennes_str = $saisies_anciennes;
 		array_walk_recursive($saisies_anciennes_str, 'formidable_array_walk_recursive_strval');
 		$md5_saisies_anciennes = md5(serialize($saisies_anciennes_str));
@@ -227,6 +228,7 @@ function formulaires_editer_formulaire_champs_traiter($id_formulaire) {
 	include_spip('inc/saisies');
 	$retours = array();
 	$id_formulaire = intval($id_formulaire);
+	include_spip('formidable_fonctions');
 
 	if (_request('revert')) {
 		session_set("constructeur_formulaire_formidable_$id_formulaire");
@@ -238,7 +240,7 @@ function formulaires_editer_formulaire_champs_traiter($id_formulaire) {
 		$saisies_nouvelles = session_get("constructeur_formulaire_formidable_$id_formulaire");
 
 		// On récupère les anciennes saisies
-		$saisies_anciennes = unserialize(sql_getfetsel(
+		$saisies_anciennes = formidable_deserialize(sql_getfetsel(
 			'saisies',
 			'spip_formulaires',
 			'id_formulaire = '.$id_formulaire
@@ -255,7 +257,7 @@ function formulaires_editer_formulaire_champs_traiter($id_formulaire) {
 			session_set("constructeur_formulaire_formidable_$id_formulaire");
 			session_set("constructeur_formulaire_formidable_$id_formulaire".'_md5_formulaire_initial');
 			// On va chercher les traitements
-			$traitements = unserialize(sql_getfetsel(
+			$traitements = formidable_deserialize(sql_getfetsel(
 				'traitements',
 				'spip_formulaires',
 				'id_formulaire = '.$id_formulaire
diff --git a/formulaires/editer_formulaire_traitements.php b/formulaires/editer_formulaire_traitements.php
index 638a10e8..5718ad40 100644
--- a/formulaires/editer_formulaire_traitements.php
+++ b/formulaires/editer_formulaire_traitements.php
@@ -11,19 +11,20 @@ include_spip('inc/formidable_fichiers');
 function formulaires_editer_formulaire_traitements_charger($id_formulaire) {
 	$contexte = array();
 	$id_formulaire = intval($id_formulaire);
+	include_spip('formidable_fonctions');
 
 	// On teste si le formulaire existe
 	if ($id_formulaire
 		and $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = '.$id_formulaire)
 		and autoriser('editer', 'formulaire', $id_formulaire)
 	) {
-		$traitements = unserialize($formulaire['traitements']);
+		$traitements = formidable_deserialize($formulaire['traitements']);
 		if ($id_version = _request('id_version')) {
 			include_spip('inc/revisions');
 			$old = recuperer_version($id_formulaire, 'formulaire', $id_version);
-			$traitements = unserialize($old['traitements']);
+			$traitements = formidable_deserialize($old['traitements']);
 		}
-		$saisies = unserialize($formulaire['saisies']);
+		$saisies = formidable_deserialize($formulaire['saisies']);
 		if (!is_array($traitements)) {
 			$traitements = array();
 		}
diff --git a/formulaires/exporter_formulaire_analyse.php b/formulaires/exporter_formulaire_analyse.php
index b2146d92..164c5173 100644
--- a/formulaires/exporter_formulaire_analyse.php
+++ b/formulaires/exporter_formulaire_analyse.php
@@ -40,6 +40,7 @@ function formulaires_exporter_formulaire_analyse_traiter($id_formulaire = 0) {
  */
 function action_exporter_analyse_reponses($id_formulaire, $delim = ',') {
 	// on ne fait des choses seulements si le formulaire existe et qu'il a des enregistrements
+	include_spip('formidable_fonctions');
 	$ok = false;
 	if ($id_formulaire > 0
 		and $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = '.$id_formulaire)
@@ -50,10 +51,10 @@ function action_exporter_analyse_reponses($id_formulaire, $delim = ',') {
 		include_spip('inc/filtres');
 		$reponses_completes = array();
 
-		$saisies = saisies_lister_par_nom(unserialize($formulaire['saisies']), false);
+		$saisies = saisies_lister_par_nom(formidable_deserialize($formulaire['saisies']), false);
 
 		// exclure les champs non analysés
-		$traitement = unserialize($formulaire['traitements']);
+		$traitement = formidable_deserialize($formulaire['traitements']);
 		foreach (explode('|', $traitement['enregistrement']['analyse_exclure_champs']) as $exclure) {
 			unset($saisies[$exclure]);
 		}
@@ -69,9 +70,7 @@ function action_exporter_analyse_reponses($id_formulaire, $delim = ',') {
 
 		$valeurs = array();
 		while ($r = sql_fetch($res)) {
-			$valeurs[$r['nom']][] = is_array(unserialize($r['valeur']))
-				? unserialize($r['valeur'])
-				: $r['valeur'];
+			$valeurs[$r['nom']][] =  formidable_deserialize($r['valeur']);
 		}
 
 		foreach ($saisies as $nom => $saisie) {
@@ -80,9 +79,7 @@ function action_exporter_analyse_reponses($id_formulaire, $delim = ',') {
 				'spip_formulaires_reponses_champs',
 				'id_formulaires_reponse = '.intval($reponse['id_formulaires_reponse']).' and nom = '.sql_quote($nom)
 			);
-			if (is_array(unserialize($valeur))) {
-				$valeur = unserialize($valeur);
-			}
+			$valeur = formidable_deserialize($valeur);
 
 			$reponse_complete[] = formidable_analyser_saisie($saisie, $valeurs, 0, true);
 		}
diff --git a/formulaires/exporter_formulaire_reponses.php b/formulaires/exporter_formulaire_reponses.php
index cc1e5271..549c9320 100644
--- a/formulaires/exporter_formulaire_reponses.php
+++ b/formulaires/exporter_formulaire_reponses.php
@@ -12,10 +12,11 @@ include_spip('inc/config');
 function formulaires_exporter_formulaire_reponses_charger($id_formulaire = 0) {
 	$contexte                  = array();
 	$contexte['id_formulaire'] = intval($id_formulaire);
+	include_spip('formidable_fonctions');
 
 	// Vérifier si le formulaire dispose de champs "fichiers", pour proposer de ne pas les joindre à l'export
 	$saisies = sql_getfetsel('saisies','spip_formulaires','id_formulaire = '.intval($id_formulaire));
-	$saisies_par_type = saisies_lister_par_type(unserialize($saisies), false);
+	$saisies_par_type = saisies_lister_par_type(formidable_deserialize($saisies), false);
 	if(isset($saisies_par_type['fichiers'])){
 		$contexte['fichiers'] = true;
 	}
@@ -139,6 +140,7 @@ function preparer_formulaire_reponses($formulaire, $reponses, $statut_reponses,
 	include_spip('inc/saisies');
 	include_spip('facteur_fonctions');
 	include_spip('inc/filtres');
+	include_spip('formidable_fonctions');
 
 	$id_formulaire = $formulaire['id_formulaire'];
 	$reponses_completes = array();
@@ -159,7 +161,7 @@ function preparer_formulaire_reponses($formulaire, $reponses, $statut_reponses,
 		$titres[] = _T('formidable:reponse_statut');
 	}
 
-	$saisies = saisies_lister_par_nom(unserialize($formulaire['saisies']), false);
+	$saisies = saisies_lister_par_nom(formidable_deserialize($formulaire['saisies']), false);
 	foreach ($saisies as $nom => $saisie) {
 		if ($saisie['saisie'] != 'explication') {    // on exporte tous les champs sauf explications
 			$options = $saisie['options'];
@@ -213,7 +215,7 @@ function preparer_formulaire_reponses($formulaire, $reponses, $statut_reponses,
 	unset($_reponses_valeurs);
 
 	// Ensuite tous les champs
-	$tenter_unserialize = charger_fonction('tenter_unserialize', 'filtre/');
+	include_spip('formidable_fonctions');
 
 	// On parcourt chaque réponse
 	foreach ($reponses as $i => $reponse) {
@@ -244,7 +246,7 @@ function preparer_formulaire_reponses($formulaire, $reponses, $statut_reponses,
 
 				// Saisie de type fichier ?
 				if (!$ignorer_fichiers && $saisie['saisie'] == 'fichiers') {
-					$_valeurs = $tenter_unserialize($valeurs[$nom]);
+					$_valeurs = formidable_deserialize($valeurs[$nom]);
 					//tester s'il y a des saisies parmi les fichiers
 					if (is_array($_valeurs) and $_valeurs) {
 						$chemin = _DIR_FICHIERS_FORMIDABLE . 'formulaire_' . $id_formulaire . '/reponse_' . $reponse['id_formulaires_reponse'];
@@ -296,15 +298,13 @@ function preparer_formulaire_reponses($formulaire, $reponses, $statut_reponses,
  */
 function formidable_generer_valeur_texte_saisie($valeur, $saisie, $cle_ou_valeur = 'valeur') {
 	static $resultats = array();
-	static $tenter_unserialize = null;
-	if (is_null($tenter_unserialize)) {
-		$tenter_unserialize = charger_fonction('tenter_unserialize', 'filtre/');
-	}
+	include_spip('formidable_fonctions');
+
 
 	$hash = ($saisie['saisie'] . ':'  . serialize($saisie['options']) . ':' . $valeur);
 
 	if (!isset($resultats[$hash])) {
-		$valeur = $tenter_unserialize($valeur);
+		$valeur = formidable_deserialize($valeur);
 		// Il faut éviter de passer par là… ça prend du temps…
 		$resultats[$hash] = facteur_mail_html2text(
 			recuperer_fond(
diff --git a/formulaires/formidable.php b/formulaires/formidable.php
index bf60bd21..4a236964 100644
--- a/formulaires/formidable.php
+++ b/formulaires/formidable.php
@@ -61,12 +61,12 @@ function formidable_id_formulaire($id) {
 **/
 function formulaires_formidable_saisies_dist($id, $valeurs = array(), $id_formulaires_reponse = false) {
 	$saisies = array();
-
+	include_spip('formidable_fonctions');
 	if (
 		$id_formulaire = formidable_id_formulaire($id)
 		and $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = ' . intval($id_formulaire))
 	) {
-		$saisies = unserialize($formulaire['saisies']);
+		$saisies = formidable_deserialize($formulaire['saisies']);
 
 		// Si on est en train de réafficher les valeurs postées,
 		// ne pas afficher les saisies hidden
@@ -107,6 +107,7 @@ function formulaires_formidable_saisies_dist($id, $valeurs = array(), $id_formul
 **/
 function formulaires_formidable_charger_dist($id, $valeurs = array(), $options_appel = [], $deprecated_url_redirect = false, $deprecated_forcer_modif = false) {
 	$contexte = array();
+	include_spip('formidable_fonctions');
 
 	// Retrocompatiblité
 	if (!is_array($options_appel)) {
@@ -133,7 +134,7 @@ function formulaires_formidable_charger_dist($id, $valeurs = array(), $options_a
 
 		// Est-ce que la personne a le droit de répondre ?
 		if (autoriser('repondre', 'formulaire', $formulaire['id_formulaire'], null, array('formulaire' => $formulaire))) {
-			$traitements = unserialize($formulaire['traitements']);
+			$traitements = formidable_deserialize($formulaire['traitements']);
 
 			$contexte['mechantrobot'] = '';
 
@@ -204,7 +205,7 @@ function formulaires_formidable_charger_dist($id, $valeurs = array(), $options_a
 	$contexte['formidable_afficher_apres'] = $formulaire['apres'];
 	// Si le formulaire via d'être posté, ne pas preremplir le nouveau formulaire avec les valeurs postées
 	if ($formulaire['apres'] == 'formulaire' and _request('formidable_traiter_ok')) {
-		foreach (saisies_lister_par_nom(unserialize($formulaire['saisies'])) as $nom => $valeur)	{
+		foreach (saisies_lister_par_nom(formidable_deserialize($formulaire['saisies'])) as $nom => $valeur)	{
 			set_request($nom, null);
 		}
 		set_request('cvtupload_etapes_files', null);
@@ -328,15 +329,16 @@ function formulaires_formidable_verifier_etape_dist($etape, $id, $valeurs = arra
  */
 function formulaires_formidable_verifier_traitements($id, $valeurs = array(), $options_appel = [], $etapes = array(), $etape = null) {
 	$erreurs = array();
-
 	$id_formulaires_reponse = $options_appel['id_formulaires_reponse'] ?? false;
+	include_spip('formidable_fonctions');
 
 	if (
 		$id_formulaire = formidable_id_formulaire($id)
 		and $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = ' . intval($id_formulaire))
-		and $traitements = unserialize($formulaire['traitements'])
+		and $traitements = formidable_deserialize($formulaire['traitements'])
 		and is_array($traitements)
 	) {
+		$saisies = formidable_deserialize($formulaire['saisies']);
 		// Pour chaque traitement choisi, on cherche s'il propose une fonction de vérification propre à ses besoins
 		foreach ($traitements as $type_traitement => $options) {
 			if ($verifier_traitement = charger_fonction('verifier', "traiter/$type_traitement", true)) {
@@ -392,6 +394,7 @@ function formulaires_formidable_verifier_traitements($id, $valeurs = array(), $o
  **/
 function formulaires_formidable_traiter_dist($id, $valeurs = [], $options_appel = [], $deprecated_url_redirect = false, $deprecated_forcer_modif = false) {
 	$retours = array();
+	include_spip('formidable_fonctions');
 
 	// Retrocompatiblité
 	if (!is_array($options_appel)) {
@@ -417,8 +420,8 @@ function formulaires_formidable_traiter_dist($id, $valeurs = [], $options_appel
 	}
 
 	$formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = ' . $id_formulaire);
-	$saisies = unserialize($formulaire['saisies']);
-	$traitements = unserialize($formulaire['traitements']);
+	$saisies = formidable_deserialize($formulaire['saisies']);
+	$traitements = formidable_deserialize($formulaire['traitements']);
 
 	// On met à null les (sous-)saisies masquées par afficher_si
 	formidable_saisies_afficher_si_masquees_set_request_null();
@@ -659,6 +662,7 @@ function formulaires_formidable_traiter_dist($id, $valeurs = [], $options_appel
  *     Tableau des champs de type fichier
  **/
 function formulaires_formidable_fichiers($id, $valeurs = array(), $id_formulaires_reponse = false) {
+	include_spip('formidable_fonctions');
 	// On peut donner soit un id soit un identifiant
 	if (!$id_formulaire = formidable_id_formulaire($id)) {
 		return array();
@@ -666,7 +670,7 @@ function formulaires_formidable_fichiers($id, $valeurs = array(), $id_formulaire
 
 	// On cherche les saisies du formulaire
 	if ($saisies = sql_getfetsel('saisies', 'spip_formulaires', 'id_formulaire = ' . intval($id_formulaire))) {
-		$saisies = unserialize($saisies);
+		$saisies = formidable_deserialize($saisies);
 		include_spip('inc/saisies_lister');
 		$saisies_fichiers = array_keys(saisies_lister_avec_type($saisies, 'fichiers'));
 		return $saisies_fichiers;
@@ -687,13 +691,14 @@ function formulaires_formidable_fichiers($id, $valeurs = array(), $id_formulaire
  *
  **/
 function formidable_definir_contexte_avec_reponse($contexte, $id_formulaires_reponse, &$ok) {
+	include_spip('formidable_fonctions');
 
 	if ($id_formulaires_reponse == false) {
 		$ok = true;
 		return $contexte;
 	}
 	// On prépare des infos si jamais on a des champs fichiers
-	$saisies = unserialize($contexte['_formidable']['saisies']);
+	$saisies = formidable_deserialize($contexte['_formidable']['saisies']);
 	$saisies_fichiers = saisies_lister_avec_type($saisies, 'fichiers');// les saisies de type fichier
 	$fichiers = array();
 	$id_formulaire = $contexte['_formidable']['id_formulaire'];
@@ -708,7 +713,7 @@ function formidable_definir_contexte_avec_reponse($contexte, $id_formulaires_rep
 	// On remplit le contexte avec les résultats précédents
 	foreach ($champs as $champ) {
 		if (array_key_exists($champ['nom'], $saisies_fichiers)) {
-			$valeur= unserialize($champ['valeur']);
+			$valeur= formidable_deserialize($champ['valeur']);
 			$nom = $champ['nom'];
 			$fichiers[$nom] = array();
 			$chemin = _DIR_FICHIERS_FORMIDABLE
@@ -722,7 +727,7 @@ function formidable_definir_contexte_avec_reponse($contexte, $id_formulaires_rep
 				}
 			}
 		} else {
-			$test_array = filtre_tenter_unserialize_dist($champ['valeur']);
+			$test_array = formidable_deserialize($champ['valeur']);
 			$contexte[$champ['nom']] = is_array($test_array) ? $test_array : $champ['valeur'];
 		}
 	}
diff --git a/genie/formidable_effacer_enregistrements.php b/genie/formidable_effacer_enregistrements.php
index 4adc61c6..7d8a7d45 100644
--- a/genie/formidable_effacer_enregistrements.php
+++ b/genie/formidable_effacer_enregistrements.php
@@ -6,13 +6,15 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 }
 
 include_spip('inc/formidable_fichiers');
+
 /**
  * Effacer régulièrement les enregistrements obsolètes
 **/
 function genie_formidable_effacer_enregistrements($t) {
 	$res = sql_select('id_formulaire,traitements', 'spip_formulaires');
+	include_spip('formidable_fonctions');
 	while ($result = sql_fetch($res)) {
-		$traitements = unserialize($result['traitements']);
+		$traitements = formidable_deserialize($result['traitements']);
 		$id_formulaire = $result['id_formulaire'];
 		if (isset($traitements['enregistrement']['effacement'])
 			and $traitements['enregistrement']['effacement'] == 'on'
diff --git a/http/collectionjson/inc-formulaire.html b/http/collectionjson/inc-formulaire.html
index 58e222d9..e08bc07c 100644
--- a/http/collectionjson/inc-formulaire.html
+++ b/http/collectionjson/inc-formulaire.html
@@ -26,8 +26,8 @@
 	[(#SET{item, [(#GET{item}|push_table_valeur{data, [(#ARRAY{name,titre, value,#TITRE, prompt,<:info_titre:>})]})]})]
 	[(#SET{item, [(#GET{item}|push_table_valeur{data, [(#ARRAY{name,descriptif, value,#DESCRIPTIF, prompt,<:info_descriptif:>})], #DESCRIPTIF})]})]
 	[(#SET{item, [(#GET{item}|push_table_valeur{data, [(#ARRAY{name,message_retour, value,[(#MESSAGE_RETOUR|propre)], prompt,<:formidable:editer_message_ok:>})], #MESSAGE_RETOUR})]})]
-	[(#SET{item, [(#GET{item}|push_table_valeur{data, [(#ARRAY{name,saisies, array,[(#SAISIES|unserialize)], prompt,<:formidable:champs:>})], #SAISIES})]})]
-	[(#SET{item, [(#GET{item}|push_table_valeur{data, [(#ARRAY{name,traitements, array,[(#TRAITEMENTS|unserialize)], prompt,<:formidable:voir_traitements:>})], #TRAITEMENTS})]})]
+	[(#SET{item, [(#GET{item}|push_table_valeur{data, [(#ARRAY{name,saisies, array,[(#SAISIES|formidable_deserialize)], prompt,<:formidable:champs:>})], #SAISIES})]})]
+	[(#SET{item, [(#GET{item}|push_table_valeur{data, [(#ARRAY{name,traitements, array,[(#TRAITEMENTS|formidable_deserialize)], prompt,<:formidable:voir_traitements:>})], #TRAITEMENTS})]})]
 ]
 
 [(#REM) Des champs au contenu BRUT qui peut être modifié ]
diff --git a/inc/formidable.php b/inc/formidable.php
index ac51f551..fd862fbe 100644
--- a/inc/formidable.php
+++ b/inc/formidable.php
@@ -391,29 +391,6 @@ function analyser_saisie($saisie) {
 }
 
 
-/**
- * Tente de déserialiser un texte
- *
- * Si le paramètre est un tableau, retourne le tableau,
- * Si c'est une chaîne, tente de la désérialiser, sinon
- * retourne la chaîne.
- *
- * @filtre
- *
- * @param string|array $texte
- *	 Le texte (possiblement sérializé) ou un tableau
- * @return array|string
- *	 Tableau, texte désérializé ou texte
-**/
-function filtre_tenter_unserialize_dist($texte) {
-	if (is_array($texte)) {
-		return $texte;
-	}
-	if ($tmp = @unserialize($texte)) {
-		return $tmp;
-	}
-	return $texte;
-}
 
 
 /**
@@ -709,3 +686,4 @@ function formidable_array_walk_recursive_strval(&$value, $key) {
 		$value = strval($value);
 	}
 }
+
diff --git a/modeles/formulaire_aide_memoire.html b/modeles/formulaire_aide_memoire.html
index 627578d4..34a577bd 100644
--- a/modeles/formulaire_aide_memoire.html
+++ b/modeles/formulaire_aide_memoire.html
@@ -10,7 +10,7 @@
 		<dd><:formidable:editer_message_ok:></dd>
 	</dl>
 	[(#ENV{source}|!={sessions}|oui)
-		#SET{saisies,#SAISIES*|unserialize}
+		#SET{saisies,#SAISIES*|formidable_deserialize}
 	]
 </BOUCLE_formulaire>
 <BOUCLE_session(CONDITION) {si #GET{source}|=={session}}>
diff --git a/modeles/formulaire_analyse.html b/modeles/formulaire_analyse.html
index ca28fdf6..1dd85fee 100644
--- a/modeles/formulaire_analyse.html
+++ b/modeles/formulaire_analyse.html
@@ -1,12 +1,12 @@
 <BOUCLE_formulaire(FORMULAIRES){id_formulaire}>
-#SET{exclure_champs,#TRAITEMENTS|unserialize|table_valeur{enregistrement}|table_valeur{analyse_exclure_champs}|explode{|}}
+#SET{exclure_champs,#TRAITEMENTS|formidable_deserialize|table_valeur{enregistrement}|table_valeur{analyse_exclure_champs}|explode{|}}
 <div class='formidable_analyse'>
 [(#REM) On fait un tableau qui contient toutes les réponses, classées par champ, sauf pour les champs qui sont à ne pas prendre en compte ]
 #SET{valeurs,#ARRAY}
 #SET{reponses_total,0}
 <BOUCLE_reponses(FORMULAIRES_REPONSES){id_formulaire}>
 <BOUCLE_champs(FORMULAIRES_REPONSES_CHAMPS){id_formulaires_reponse}{nom ?= #ENV{nom}}{!nom IN #GET{exclure_champs}}>
-#SET_MERGE{liste_valeurs, #GET{valeurs}|table_valeur{#NOM}|sinon{#ARRAY}, #ARRAY{0,#VALEUR|tenter_unserialize}}
+#SET_MERGE{liste_valeurs, #GET{valeurs}|table_valeur{#NOM}|sinon{#ARRAY}, #ARRAY{0,#VALEUR|formidable_deserialize}}
 #SET_MERGE{valeurs, #ARRAY{#NOM,#GET{liste_valeurs}}}
 </BOUCLE_champs>
 </BOUCLE_reponses>
@@ -18,7 +18,7 @@
 	<strong class='nombre_reponse'><:formidable:reponse_aucune:></strong>
 <//B_reponses>
 
-<BOUCLE_saisies(DATA){source tableau, #SAISIES|unserialize|saisies_lister_par_nom}>
+<BOUCLE_saisies(DATA){source tableau, #SAISIES|formidable_deserialize|saisies_lister_par_nom}>
 [(#VAL{saisie}|array_key_exists{#VALEUR}|oui)
   [(#CLE|=={#ENV{nom,#CLE}}|oui)
 	[(#CLE|in_array{#GET{exclure_champs}}|non)
diff --git a/modeles/formulaires_reponse.html b/modeles/formulaires_reponse.html
index 494af6ee..c8b58395 100644
--- a/modeles/formulaires_reponse.html
+++ b/modeles/formulaires_reponse.html
@@ -1,11 +1,11 @@
 <BOUCLE_reponse(FORMULAIRES_REPONSES){tout}{id_formulaires_reponse}>
 
 <BOUCLE_formulaire(FORMULAIRES){tout}{id_formulaire}>
-#SET{saisies,#SAISIES|unserialize}
+#SET{saisies,#SAISIES|formidable_deserialize}
 </BOUCLE_formulaire>
 #SET{valeurs,#ARRAY}
 <BOUCLE_champs(FORMULAIRES_REPONSES_CHAMPS){id_formulaires_reponse}>
-#SET_MERGE{valeurs,#ARRAY{#NOM,#VALEUR|tenter_unserialize|formidable_ajouter_action_recuperer_fichier{#NOM,#GET{saisies},#ID_FORMULAIRE,#ID_FORMULAIRES_REPONSE}}
+#SET_MERGE{valeurs,#ARRAY{#NOM,#VALEUR|formidable_deserialize|formidable_ajouter_action_recuperer_fichier{#NOM,#GET{saisies},#ID_FORMULAIRE,#ID_FORMULAIRES_REPONSE}}
 </BOUCLE_champs>
 
 #VOIR_SAISIES{#GET{saisies}, #GET{valeurs}}
diff --git a/prive/squelettes/contenu/formulaire.html b/prive/squelettes/contenu/formulaire.html
index 7493d064..20557596 100644
--- a/prive/squelettes/contenu/formulaire.html
+++ b/prive/squelettes/contenu/formulaire.html
@@ -22,7 +22,7 @@
 		|concat{<:formidable:traitements_actives:>},'sobre traitements mini'})]
 	<B_traitements>
 		<ul class='spip'>
-			<BOUCLE_traitements(DATA){source tableau, #TRAITEMENTS|unserialize|sinon{#ARRAY}}>
+			<BOUCLE_traitements(DATA){source tableau, #TRAITEMENTS|formidable_deserialize|sinon{#ARRAY}}>
 				<li>[(#GET{traitements_disponibles}|table_valeur{#CLE}|table_valeur{titre})]</li>
 			</BOUCLE_traitements>
 		</ul>
-- 
GitLab