Valider 2cf619fc rédigé par marcimat's avatar marcimat
Parcourir les fichiers

Ajouter une méthode pour supprimer les fichiers finaux du cache lorsqu’ils...

Ajouter une méthode pour supprimer les fichiers finaux du cache lorsqu’ils étaient réinjectés dans $_FILES mais que le $_FILES a été vidé de cet élément par la suite.
C’est ce que fait Formidable lorsqu’un fichier ne lui convient pas. De la sorte, lorsqu’il ré-affiche le formulaire, lors de la vérification qui indique l’erreur, le fichier n’est plus présent (c’est le comportement qu’attend formidable)
(alors que bigup le ré-affichait en proposant de l’annuler donc).

Pour cela, on sauvegarde la liste des champs/fichiers qu’on a injectés dans Files, et à la vérification et au traitement, on compare cela avec le $_FILES actuel.
parent b3908018
Chargement en cours
Chargement en cours
Chargement en cours
Chargement en cours
+29 −15
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -129,7 +129,8 @@ function bigup_formulaire_receptionner($flux) {
	if (_request('bigup_retrouver_fichiers')) {
		$bigup = bigup_get_bigup($flux);
		$bigup->gerer_fichiers_postes(); // les fichiers postés sans JS
		$bigup->reinserer_fichiers(_request('bigup_reinjecter_uniquement'));
		$liste = $bigup->reinserer_fichiers(_request('bigup_reinjecter_uniquement'));
		$bigup->surveiller_fichiers($liste);
	}
	return $flux;
}
@@ -137,15 +138,18 @@ function bigup_formulaire_receptionner($flux) {
/**
 * Branchement sur verifier
 * 
 * Si on a demandé la suppression d'un fichier, le faire
 * - Si on a demandé la suppression d'un fichier, le faire
 * - Nettoyer les fichiers injectés effacés de $_FILES.
 *
 * @param array $flux
 * @return array
**/
function bigup_formulaire_verifier($flux) {
	// enlever un fichier dont on demande sa suppression
	if ($identifiant = _request('bigup_enlever_fichier')) {
	$identifiant = _request('bigup_enlever_fichier');
	if ($identifiant or _request('bigup_retrouver_fichiers')) {
		$bigup = bigup_get_bigup($flux);
		// enlever un fichier dont on demande sa suppression
		if ($identifiant) {
			if ($bigup->supprimer_fichiers($identifiant)) {
				// on n'affiche pas les autres erreurs
				$flux['data'] = [];
@@ -153,6 +157,10 @@ function bigup_formulaire_verifier($flux) {
				$flux['data']['message_ok'] = 'Fichier effacé';
				$flux['data']['_erreur'] = true;
			}
		} else {
			// nettoyer nos fichiers réinsérés s'ils ont été enlevés de $_FILES
			$bigup->verifier_fichiers_surveilles();
		}
	}
	return $flux;
}
@@ -161,19 +169,25 @@ function bigup_formulaire_verifier($flux) {
/**
 * Branchement sur traiter
 *
 * Si on a effectué les traitements sans erreur,
 * - Si on a effectué les traitements sans erreur,
 * tous les fichiers restants doivent disparaître
 * du cache.
 * - Nettoyer les fichiers injectés effacés de $_FILES.
 *
 * @param array $flux
 * @return array
 **/
function bigup_formulaire_traiter($flux) {
	// à voir si on cherche systématiquement
	// ou uniquement lorsqu'on a demander à recuperer les fichiers
	if (empty($flux['data']['message_erreur']) and _request('bigup_retrouver_fichiers')) {
	if (_request('bigup_retrouver_fichiers')) {
		$bigup = bigup_get_bigup($flux);
		// à voir si on cherche systématiquement
		// ou uniquement lorsqu'on a demandé à recuperer les fichiers
		if (empty($flux['data']['message_erreur'])) {
			$bigup->supprimer_fichiers(_request('bigup_reinjecter_uniquement'));
		} else {
			// nettoyer nos fichiers réinsérés s'ils ont été enlevés de $_FILES
			$bigup->verifier_fichiers_surveilles();
		}
	}
	return $flux;
}
+56 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -94,6 +94,62 @@ class Bigup {
		return $liste;
	}

	/**
	 * Pour une liste (champ => description de fichier) donné, déclenche
	 * un mécanisme qui permettra de vérifier que ces fichiers sont toujours présents
	 * dans $_FILES au moment des vérifications et des traitements.
	 * Le cas échéant, les enlèvera de $_FILES.
	 *
	 * @param array $liste
	 *     Liste de descriptions de fichiers
	 * @return bool
	 *     True si des fichiers ont été mis en surveillance, false sinon.
	 */
	public function surveiller_fichiers($liste) {
		if (!$liste) {
			return false;
		}
		$surveiller = [];
		foreach ($liste as $champ => $descriptions) {
			$surveiller[$champ] = array_column($descriptions, 'tmp_name');
		}
		// Théoriquement on ne passe pas plusieurs fois ici lors d'un hit
		// seulement lorsqu'on poste 1 formulaire. Pas besoin de gérér
		// plusieurs variables.
		set_request('bigup_surveiller_fichiers', $surveiller);
		return true;
	}

	/**
	 * Enlève les fichiers surveillés par bigup qui ont été enlevés de `$_FILES`
	 *
	 * Cela signifie probablement que le fichier ne convenait pas au formulaire
	 * qui le demandait. En tout cas c'est comme cela que fait Formidable
	 * avec les fichiers qu'il reçoit qui ne lui conviennent pas.
	 *
	 * @param array $liste
	 *     Liste de descriptions de fichiers
	 */
	public function verifier_fichiers_surveilles() {
		$surveiller = _request('bigup_surveiller_fichiers');
		if (!$surveiller) {
			return true;
		}
		foreach ($surveiller as $champ => $fichiers) {
			foreach ($fichiers as $i => $fichier) {
				if (!Files::contient($champ, $fichier)) {
					GestionRepertoires::supprimer_repertoire(dirname($fichier));
					unset($surveiller[$champ][$i]);
				}
			}
			if (!count($surveiller[$champ])) {
				unset($surveiller[$champ]);
			}
		}
		set_request('bigup_surveiller_fichiers', $surveiller);

		return true;
	}

	/**
	 * Efface tous ou certains fichiers envoyés pour ce formulaire par un auteur.
+77 −0
Numéro de ligne d'origine Numéro de ligne de diff Ligne de diff
@@ -20,6 +20,83 @@ class Files {

	use LogTrait;

	/**
	 * Indique si ce chemin de fichier est présent pour ce champ dans $_FILES
	 * @param string $champ
	 *     Valeur de l'attribut name du champ.
	 * @param stsring $chemin
	 *     Chemin du fichier dans le cache
	 * @return bool
	 *     true si le fichier est présent, false sinon.
	 */
	public static function contient($champ, $chemin) {
		if (!$champ or !$chemin) {
			return false;
		}
		$arborescence = explode('[', str_replace(']', '', $champ));
		$racine = array_shift($arborescence);

		// si la racine n'existe pas déjà… partir.
		if (empty($_FILES[$racine]['tmp_name'])) {
			return false;
		}

		$debut = $_FILES[$racine]['tmp_name'];
		return self::contient_arborescence($arborescence, $debut, $chemin);
	}

	/**
	 * Recherche dans une arborescence de tableau (si elle existe) la valeur indiquée.
	 *
	 * Notamment peut servir à rechercher un chemin de fichier dans une
	 * sous clé de `$_FILES` lorsque `[]` était présent dans le nom du champ.
	 *
	 * Les chaines vides dans le tableau d'arborescence transmis sont considérées
	 * comme pouvant être n'importe quel entier dans le tableau.
	 * Ie: si on a '', on recherchera dans `$tableau[0]` ou `$tableau[1]`, etc.
	 * s'ils existent.
	 *
	 * @param array $arborescence
	 *     Tableau ['', 'truc'] si recherche du champ '[][truc]'
	 * @param string $tableau
	 *     Le tableau de recherche
	 * @param string $valeur
	 *     La valeur cherchée
	 */
	public static function contient_arborescence($arborescence, $tableau, $valeur) {
		$a = array_shift($arborescence);
		if ($a === null) {
			return $tableau == $valeur;
		}

		// champ[truc][0]
		if (strlen($a)) {
			if (empty($tableau[$a])) {
				return false;
			}
			return self::contient_arborescence($arborescence, $tableau[$a], $valeur);
		}

		// sinon champ avec [] vides
		if (!is_array($tableau)) {
			return false;
		}
		// si c'était le dernier []
		if (!count($arborescence)) {
			return (false !== array_search($valeur, $tableau));
		} else {
			// champ[][truc]
			foreach ($tableau as $k => $t) {
				if (is_int($k)) {
					$ok = self::contient_arborescence($arborescence, $tableau[$k], $valeur);
					if ($ok) {
						return true;
					}
				}
			}
			return false;
		}
	}

	/**
	 * Intégrer le fichier indiqué dans `$FILES`