diff --git a/action/formidable_recuperer_fichier_par_email.php b/action/formidable_recuperer_fichier_par_email.php index 910d0e226c931c912f4831cfc291ec448c968b38..491dd5d3b95da06801e957f1b982df733fd81a69 100644 --- a/action/formidable_recuperer_fichier_par_email.php +++ b/action/formidable_recuperer_fichier_par_email.php @@ -18,11 +18,25 @@ function action_formidable_recuperer_fichier_par_email() { OR $hash==_action_auteur("$action-$arg", '', $pass, 'alea_ephemere_ancien')) { $arg = unserialize($arg); - $chemin_fichier = _DIR_FICHIERS_FORMIDABLE - ."formulaire_".$arg['formulaire'] - ."/reponse_".$arg['reponse'] - ."/".$arg['saisie'] - ."/".$arg['fichier']; + // Construire le chemin du fichier, en fonction de ce qu'on reçoit + if (isset($arg['reponse'])) { + $chemin_fichier = _DIR_FICHIERS_FORMIDABLE + ."formulaire_".$arg['formulaire'] + ."/reponse_".$arg['reponse'] + ."/".$arg['saisie'] + ."/".$arg['fichier']; + } elseif (isset($arg['timestamp'])) { + $chemin_fichier = _DIR_FICHIERS_FORMIDABLE + . "timestamp/" + . $arg['timestamp']."/" + . $arg['saisie']."/" + . $arg['fichier']; + } else { + include_spip('inc/minipres'); + echo minipres(_T("formidable:erreur_fichier_introuvable")); + } + + // Vérifier que le fichier existe, qu'il n'est pas trop vieux, et l'envoyer le cas échéant if (@file_exists($chemin_fichier)){ $f = $arg['fichier']; $date = filemtime($chemin_fichier); diff --git a/inc/formidable_fichiers.php b/inc/formidable_fichiers.php index 9990b3cad34a8da941fc8ed27d9aa520066766f9..9606dcd3465fba216b38597e1a491e680d83a6ad 100644 --- a/inc/formidable_fichiers.php +++ b/inc/formidable_fichiers.php @@ -74,31 +74,51 @@ function formidable_creer_dossier_formulaire($id_formulaire, $forcer=false) { * * @param string $fichier l'adresse temporaire du fichier * @param string $nom le nom du fichiera - * @param int $id_formulaire l'identifiant du formulaire * @param string $champ le champ concerné - * @param int $id_formulaires_reponse l'identifiant de la réponse + * formidable_deplacer_fichier_emplacement_definitif * @return string $nom_definitif le nom définitif du fichier tel que stocké dans son dossier, vide s'il y a eu un souci lors du déplacement (dans ce cas un courriel sera envoyé au webmestre) * **/ -function formidable_deplacer_fichier_emplacement_definitif($fichier, $nom, $id_formulaire, $champ, $id_formulaires_reponse = null){ - +function formidable_deplacer_fichier_emplacement_definitif($fichier, $nom, $champ, $options){ + if (isset($options['id_formulaire'])) { + $id_formulaire = $options['id_formulaire']; + $dossier_formulaire = "formulaire_$id_formulaire"; + } + else {// si c'est pas set, c'est qu'il y a une erreur + return ''; + } + + if (isset($options['id_formulaires_reponse'])) { + $dossier_reponse = "reponse_".$options['id_formulaires_reponse']; + } elseif (isset($options['timestamp'])){ + $dossier_reponse = "reponse_".$options['timestamp']; + } else { // si ni timestamp, ni id_formulaires_reponse => erreur + return ''; + } // déterminer l'extension $path_info = pathinfo($nom); $basename = $path_info['basename']; $extension = $path_info['extension']; + if (!isset($options['timestamp'])) { // si on enregistre la réponse en base - // d'abord, créer si besoin le dossier pour le formulaire, si on a une erreur, on ne déplace pas le fichier - if (formidable_creer_dossier_formulaire($id_formulaire, true) != '') { - return ''; - } - // puis on créer le dossier pour la réponse - $dossier_formulaire = "formulaire_$id_formulaire"; - $dossier_reponse = "reponse_$id_formulaires_reponse"; - $dossier_reponse = sous_repertoire(_DIR_FICHIERS_FORMIDABLE.$dossier_formulaire."/", $dossier_reponse,false,true); + // d'abord, créer si besoin le dossier pour le formulaire, si on a une erreur, on ne déplace pas le fichier + if (formidable_creer_dossier_formulaire($id_formulaire, true) != '') { + return ''; + } + + // puis on créer le dossier pour la réponse + $dossier_reponse = sous_repertoire(_DIR_FICHIERS_FORMIDABLE.$dossier_formulaire."/", $dossier_reponse,false,true); - // puis le dossier pour le champ - $dossier_champ = sous_repertoire($dossier_reponse,$champ,false,true); - $appendice_nom = 0; + // puis le dossier pour le champ + $dossier_champ = sous_repertoire($dossier_reponse,$champ,false,true); + $appendice_nom = 0; + } else { // si on enregistre sous forme de timestamp + sous_repertoire(_DIR_FICHIERS,'',true,true); + sous_repertoire(_DIR_FICHIERS_FORMIDABLE,'',true,true); + $dossier = sous_repertoire(_DIR_FICHIERS_FORMIDABLE, 'timestamp', false, true); + $dossier = sous_repertoire($dossier, $options['timestamp'],false,true); + $dossier_champ = sous_repertoire($dossier,$champ,false,true); + } // S'assurer qu'il n'y a pas un fichier du même nom à destination $chemin_final = $dossier_champ.$nom; @@ -141,3 +161,46 @@ function formidable_retourner_fichier($chemin, $f) { readfile($chemin); exit; } +/** + * Déplacer un fichier temporaire à son emplacement définif. + * Produire un tableau de description des fichiers déplacés. + * Le tout à partir de la description d'une saisies 'fichiers' + * @param array $saisie la description de la saisie fichiers + * @param array $options des options, dépendante du type de traitement, qui permettent d'indiquer où l'on déplace le fichier + * return array un tableau de "vue" de la saisie +**/ +function formidable_deplacer_fichiers_produire_vue_saisie($saisie, $options) { + $nb_fichiers_max = $saisie['options']['nb_fichiers']; // on va parcourir $_FILES en nous limitant aux nombres de fichiers définies par la saisie, pour éviter les éventuelles ajout supplémentaire de fichiers par modif du html + $champ = $saisie['options']['nom']; + if (!isset($_FILES[$champ])) {//précaution + return null; + } + $description_fichiers = array(); + $mon_file = $_FILES[$champ]; + $i = 0; + while ($i < $nb_fichiers_max) { + if ($mon_file['error'][$i] == 0) { // la saisie fichiers est forcément structurée sous la forme d'un tableau, on peut donc vérifier qu'il n'y a pas d'erreur facilement + $description = array(); // tableau pour stocker la description de ce fichier + + // les infos qu'on peut récuperer directement de $files + $description['taille'] = $mon_file['size'][$i]; + $description['mime'] = $mon_file['type'][$i]; + + // l'adresse du nouveau fichier, sans le chemin + if ($nouveau_nom = formidable_deplacer_fichier_emplacement_definitif( + $mon_file['tmp_name'][$i], + $mon_file['name'][$i], + $champ, + $options + ) + ) { + $description['nom'] = $nouveau_nom; + $description['extension'] = pathinfo($nouveau_nom, PATHINFO_EXTENSION); + } + $description_fichiers[] = $description;//on ajoute la description au tableau global + + } + $i++; + } + return $description_fichiers; +} diff --git a/traiter/email.php b/traiter/email.php index 1ca8d278170ee0258e4d03921d0a096c916c3636..5a761a7c709c087856b8d5209a1e92411f7e85f0 100644 --- a/traiter/email.php +++ b/traiter/email.php @@ -79,10 +79,10 @@ function traiter_email_dist($args, $retours) { // On parcourt les champs pour générer le tableau des valeurs $valeurs = array(); - $saisies_fichiers = array_keys(saisies_lister_avec_type($saisies,'fichiers'));// On utilise pas formulaires_formidable_fichiers, car celui-ci retourne les saisies fichiers du formulaire dans la base… or, on sait-jamais, il peut y avoir eu une modification entre le moment où l'utilisateur a vu le formulaire et maintenant + $saisies_fichiers = saisies_lister_avec_type($saisies,'fichiers');// On utilise pas formulaires_formidable_fichiers, car celui-ci retourne les saisies fichiers du formulaire dans la base… or, on sait-jamais, il peut y avoir eu une modification entre le moment où l'utilisateur a vu le formulaire et maintenant foreach ($champs as $champ) { - if (in_array($champ, $saisies_fichiers)) {// si on a affaire à une saisie de type fichiers, on traite à part - $valeurs[$champ] = traiter_email_fichiers($champ, $formulaire['id_formulaire'], $retours,$timestamp); + if (array_key_exists($champ, $saisies_fichiers)) {// si on a affaire à une saisie de type fichiers, on traite à part + $valeurs[$champ] = traiter_email_fichiers($saisies_fichiers[$champ], $champ, $formulaire['id_formulaire'], $retours, $timestamp); } else { $valeurs[$champ] = _request($champ); } @@ -327,23 +327,35 @@ function formidable_traiter_email_destinataire_selon_champ($description) { * - S'il y a eu un enregistement avant, ne déplace pas le fichier * - S'il n'y a pas eu d'enregistrement avant, déplace le fichier dans un dossier nommé en fonction du timestamp du traitement * - Renvoie un tableau décrivant les fichiers, avec une url d'action sécurisée valable seulement '_FORMIDABLE_EXPIRATION_FICHIERS_EMAIL' - * - * @param string $saisie le nom de la saisie + * @param array $saisie la description de la saisie + * @param string $nom le nom de la saisie * @param int|string $id_formulaire le formulaire concerné * @param array $retours ce qu'a envoyé le précédent traitement * @param int $timestamp un timestamp correspondant au début du processus de création du courriel * @return array un tableau décrivant la saisie **/ -function traiter_email_fichiers($saisie, $id_formulaire, $retours,$timestamp){ +function traiter_email_fichiers($saisie, $nom, $id_formulaire, $retours, $timestamp){ //Initialisation $id_formulaire = strval($id_formulaire);//précaution $vue = array(); - if ($id_formulaires_reponse = $retours['id_formulaires_reponse']) { // cas simple: les réponses ont été enregistrées - if (isset($retours['fichiers'][$saisie])) { // petite précaution - $vue = ajouter_action_recuperer_fichier_par_email($retours['fichiers'][$saisie], $saisie, $id_formulaire, $id_formulaires_reponse, $timestamp); + if (isset($retours['id_formulaires_reponse']) and $id_formulaires_reponse = $retours['id_formulaires_reponse']) { // cas simple: les réponses ont été enregistrées + if (isset($retours['fichiers'][$nom])) { // petite précaution + $options = array( + 'id_formulaire' => $id_formulaire, + 'id_formulaires_reponse' => $retours['id_formulaires_reponse'] + ); + $vue = ajouter_action_recuperer_fichier_par_email($retours['fichiers'][$nom], $nom, $options); } + } else { // si les réponses n'ont pas été enregistrées + $vue = formidable_deplacer_fichiers_produire_vue_saisie($saisie,array('id_formulaire'=>$id_formulaire,'timestamp'=>$timestamp)); + $options = array( + 'id_formulaire' => $id_formulaire, + 'timestamp' => $timestamp + ); + $vue = ajouter_action_recuperer_fichier_par_email($vue, $nom, $options); } + return $vue; } @@ -355,26 +367,34 @@ function traiter_email_fichiers($saisie, $id_formulaire, $retours,$timestamp){ * Ajoute également une vignette correspondent à l'extention * @param array $saisie_a_modifier * @param string $nom_saisie - * @param int|string $id_formulaire - * @param int|string $id_formulaires_reponse - * @param int $timestamp + * @param array $options options qui décrit l'endroit où est stocké le fichier * return array $saisie_a_modifier **/ -function ajouter_action_recuperer_fichier_par_email($saisie_a_modifier, $nom_saisie, $id_formulaire, $id_formulaires_reponse, $timestamp) { - $id_formulaire = strval($id_formulaire); - $id_formulaires_reponse = strval($id_formulaires_reponse); +function ajouter_action_recuperer_fichier_par_email($saisie_a_modifier, $nom_saisie, $options) { $vignette_par_defaut = charger_fonction('vignette', 'inc/'); $pass = secret_du_site(); $action = "formidable_recuperer_fichier_par_email"; $delai = secondes_en_jour(_FORMIDABLE_EXPIRATION_FICHIERS_EMAIL); foreach ($saisie_a_modifier as $i => $valeur){ - $arg = serialize(array( - 'formulaire' => $id_formulaire, - 'reponse' => $id_formulaires_reponse, - 'fichier' => $valeur['nom'], - 'saisie' => $nom_saisie - )); + if (isset($options['id_formulaires_reponse'])) {//si reponses enregistrées + $arg = serialize(array( + 'formulaire' => strval($options['id_formulaire']), + 'reponse' => strval($options['id_formulaires_reponse']), + 'fichier' => $valeur['nom'], + 'saisie' => $nom_saisie + )); + } elseif (isset($options['timestamp'])) {//si par timestamp + $arg = serialize(array( + 'formulaire' => strval($options['id_formulaire']), + 'timestamp' => strval($options['timestamp']), + 'fichier' => $valeur['nom'], + 'saisie' => $nom_saisie + )); + } else { //si ni timestamp, ni réponse enregistré -> on passe notre chemin + continue; + } + $hash = _action_auteur("$action-$arg", '', $pass, 'alea_ephemere'); $url = generer_url_action($action, "arg=$arg&hash=$hash", true, true); $saisie_a_modifier[$i]['url'] = $url; diff --git a/traiter/enregistrement.php b/traiter/enregistrement.php index 8e2399a595fc8de678a326a6771a6908a34a3083..76ccfe00b3b3981cb034d82e98dd831a0a455dc5 100644 --- a/traiter/enregistrement.php +++ b/traiter/enregistrement.php @@ -203,38 +203,5 @@ function traiter_enregistrement_update_dist($id_formulaire, $traitement, $saisie **/ function traiter_enregistrement_fichiers($saisie, $id_formulaire, $id_formulaires_reponse){ include_spip('inc/formidable_fichiers'); - $nb_fichiers_max = $saisie['options']['nb_fichiers']; // on va parcourir $_FILES en nous limitant aux nombres de fichiers définies par la saisie, pour éviter les éventuelles ajout supplémentaire de fichiers par modif du html - $champ = $saisie['options']['nom']; - if (!isset($_FILES[$champ])) {//précaution - return null; - } - $description_fichiers = array(); - $mon_file = $_FILES[$champ]; - $i = 0; - while ($i < $nb_fichiers_max) { - if ($mon_file['error'][$i] == 0) { // la saisie fichiers est forcément structurée sous la forme d'un tableau, on peut donc vérifier qu'il n'y a pas d'erreur facilement - $description = array(); // tableau pour stocker la description de ce fichier - - // les infos qu'on peut récuperer directement de $files - $description['taille'] = $mon_file['size'][$i]; - $description['mime'] = $mon_file['type'][$i]; - - // l'adresse du nouveau fichier, sans le chemin - if ($nouveau_nom = formidable_deplacer_fichier_emplacement_definitif( - $mon_file['tmp_name'][$i], - $mon_file['name'][$i], - $id_formulaire, - $champ, - $id_formulaires_reponse - ) - ) { - $description['nom'] = $nouveau_nom; - $description['extension'] = pathinfo($nouveau_nom, PATHINFO_EXTENSION); - } - $description_fichiers[] = $description;//On ajoute la description au tableau global - - } - $i++; - } - return $description_fichiers; + return formidable_deplacer_fichiers_produire_vue_saisie($saisie,array('id_formulaire'=>$id_formulaire,'id_formulaires_reponse'=>$id_formulaires_reponse)); }