[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / plugins / formidable / formulaires / formidable.php
index e2f897f..ae2b75b 100644 (file)
@@ -1,10 +1,10 @@
 <?php
 
 /**
- * Gestion de l'affichage et traitement d'un formulaire Formidable
- *
- * @package SPIP\Formidable\Formulaires
- **/
+* Gestion de l'affichage et traitement d'un formulaire Formidable
+*
+* @package SPIP\Formidable\Formulaires
+**/
 
 // Sécurité
 if (!defined('_ECRIRE_INC_VERSION')) {
@@ -12,9 +12,11 @@ if (!defined('_ECRIRE_INC_VERSION')) {
 }
 
 include_spip('inc/formidable');
+include_spip('inc/formidable_fichiers');
 include_spip('inc/saisies');
 include_spip('base/abstract_sql');
 include_spip('inc/autoriser');
+include_spip('plugins/installer');
 
 function formidable_id_formulaire($id) {
        // on utilise une static pour etre sur que si l'appel dans verifier() passe, celui dans traiter() passera aussi
@@ -44,21 +46,21 @@ function formidable_id_formulaire($id) {
 }
 
 /**
- * Chargement du formulaire CVT de Formidable.
- *
- * Genere le formulaire dont l'identifiant (numerique ou texte est indique)
- *
- * @param int|string $id
- *     Identifiant numerique ou textuel du formulaire formidable
- * @param array $valeurs
- *     Valeurs par défauts passées au contexte du formulaire
- *     Exemple : array('hidden_1' => 3) pour que champ identifie "@hidden_1@" soit prerempli
- * @param int|bool $id_formulaires_reponse
- *     Identifiant d'une réponse pour forcer la reedition de cette reponse spécifique
- *
- * @return array
- *     Contexte envoyé au squelette HTML du formulaire.
- **/
+* Chargement du formulaire CVT de Formidable.
+*
+* Genere le formulaire dont l'identifiant (numerique ou texte est indique)
+*
+* @param int|string $id
+*     Identifiant numerique ou textuel du formulaire formidable
+* @param array $valeurs
+*     Valeurs par défauts passées au contexte du formulaire
+*     Exemple : array('hidden_1' => 3) pour que champ identifie "@hidden_1@" soit prerempli
+* @param int|bool $id_formulaires_reponse
+*     Identifiant d'une réponse pour forcer la reedition de cette reponse spécifique
+*
+* @return array
+*     Contexte envoyé au squelette HTML du formulaire.
+**/
 function formulaires_formidable_charger($id, $valeurs = array(), $id_formulaires_reponse = false) {
        $contexte = array();
 
@@ -72,8 +74,7 @@ function formulaires_formidable_charger($id, $valeurs = array(), $id_formulaires
                // On ajoute un point d'entrée avec les infos de ce formulaire
                // pour d'eventuels plugins qui en ont l'utilité
                $contexte['_formidable'] = $formulaire;
-               
-               // Classes CSS 
+               // Classes CSS
                $contexte['_css'] = $formulaire['css'];
 
                // Est-ce que la personne a le droit de répondre ?
@@ -130,7 +131,9 @@ function formulaires_formidable_charger($id, $valeurs = array(), $id_formulaires
                                $contexte = formidable_definir_contexte_avec_reponse($contexte, $id_formulaires_reponse, $ok);
                                if ($ok == false) {
                                        $contexte['editable'] = false;
-                                       $contexte['message_erreur'] = _T('formidable:traiter_enregistrement_erreur_edition_reponse_inexistante');
+                                       $contexte['message_erreur'] = _T(
+                                               'formidable:traiter_enregistrement_erreur_edition_reponse_inexistante'
+                                       );
                                }
                        } else {
                                // calcul des paramètres d'anonymisation
@@ -145,8 +148,11 @@ function formulaires_formidable_charger($id, $valeurs = array(), $id_formulaires
                                if ($options
                                        and !$options['multiple']
                                        and $options['modifiable']
-                                       and $reponses = formidable_verifier_reponse_formulaire($formulaire['id_formulaire'], $options['identification'], $anonymisation)
-                               ) {
+                                       and $reponses = formidable_verifier_reponse_formulaire(
+                                               $formulaire['id_formulaire'],
+                                               $options['identification'],
+                                               $anonymisation
+                                       )) {
                                        $id_formulaires_reponse = array_pop($reponses);
                                        $contexte = formidable_definir_contexte_avec_reponse($contexte, $id_formulaires_reponse, $ok);
                                }
@@ -164,6 +170,7 @@ function formulaires_formidable_charger($id, $valeurs = array(), $id_formulaires
                                ));
                        } else {
                                $contexte['message_erreur'] = _T('formidable:traiter_enregistrement_erreur_deja_repondu');
+                               $contexte['message_erreur_class'] = 'deja_repondu';
                        }
                }
        } else {
@@ -175,6 +182,9 @@ function formulaires_formidable_charger($id, $valeurs = array(), $id_formulaires
        }
        $contexte['_hidden'] .= "\n" . '<input type="hidden" name="formidable_afficher_apres' /*.$formulaire['id_formulaire']*/ . '" value="' . $formulaire['apres'] . '"/>'; // marche pas
 
+       if ($precharger= _request('_formidable_cvtupload_precharger_fichiers')) {
+               $contexte['cvtupload_precharger_fichiers'] = $precharger;
+       }
        $contexte['formidable_afficher_apres'] = $formulaire['apres'];
 
        return $contexte;
@@ -182,25 +192,24 @@ function formulaires_formidable_charger($id, $valeurs = array(), $id_formulaires
 
 
 /**
- * Vérification du formulaire CVT de Formidable.
- *
- * Pour chaque champ posté, effectue les vérifications demandées par
- * les saisies et retourne éventuellement les erreurs de saisie.
- *
- * @param int|string $id
- *     Identifiant numerique ou textuel du formulaire formidable
- * @param array $valeurs
- *     Valeurs par défauts passées au contexte du formulaire
- *     Exemple : array('hidden_1' => 3) pour que champ identifie "@hidden_1@" soit prerempli
- * @param int|bool $id_formulaires_reponse
- *     Identifiant d'une réponse pour forcer la reedition de cette reponse spécifique
- *
- * @return array
- *     Tableau des erreurs
- **/
+* Vérification du formulaire CVT de Formidable.
+*
+* Pour chaque champ posté, effectue les vérifications demandées par
+* les saisies et retourne éventuellement les erreurs de saisie.
+*
+* @param int|string $id
+*     Identifiant numerique ou textuel du formulaire formidable
+* @param array $valeurs
+*     Valeurs par défauts passées au contexte du formulaire
+*     Exemple : array('hidden_1' => 3) pour que champ identifie "@hidden_1@" soit prerempli
+* @param int|bool $id_formulaires_reponse
+*     Identifiant d'une réponse pour forcer la reedition de cette reponse spécifique
+*
+* @return array
+*     Tableau des erreurs
+**/
 function formulaires_formidable_verifier($id, $valeurs = array(), $id_formulaires_reponse = false) {
        $erreurs = array();
-
        // On peut donner soit un id soit un identifiant
        if (!$id_formulaire = formidable_id_formulaire($id)) {
                $erreurs['message_erreur'] = _T('formidable:erreur_base');
@@ -214,7 +223,21 @@ function formulaires_formidable_verifier($id, $valeurs = array(), $id_formulaire
                $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = ' . intval($id_formulaire));
                $saisies = unserialize($formulaire['saisies']);
 
-               $erreurs = saisies_verifier($saisies);
+               $erreurs_par_fichier = array();
+               $erreurs = saisies_verifier($saisies, true, $erreurs_par_fichier);
+
+               // On supprime de $_FILES les fichiers envoyés qui ne passent pas le test de vérification
+
+               //$infos_plugins = charger_fonction('infos_plugins','plugins');
+               $plugins_actifs = liste_plugin_actifs();
+               if (isset($plugins_actifs['CVTUPLOAD'])) {
+                       include_spip('inc/cvtupload');
+                       foreach ($erreurs as $champ => $erreur) {
+                               if (isset($erreurs_par_fichier[$champ])) {
+                                       cvtupload_nettoyer_files_selon_erreurs($champ, $erreurs_par_fichier[$champ]);
+                               }
+                       }
+               }
 
                // Si on a pas déjà une erreur sur le champ unicite, on lance une verification
                if ($formulaire['unicite'] != '') {
@@ -232,7 +255,8 @@ function formulaires_formidable_verifier($id, $valeurs = array(), $id_formulaire
                                                AND R.statut = "publie"'
                                );
                                if (is_array($reponses) && count($reponses) > 0) {
-                                       $erreurs[$formulaire['unicite']] = $formulaire['message_erreur_unicite'] ? _T($formulaire['message_erreur_unicite']) : _T('formidable:erreur_unicite');
+                                       $erreurs[$formulaire['unicite']] = $formulaire['message_erreur_unicite'] ?
+                                               _T($formulaire['message_erreur_unicite']) : _T('formidable:erreur_unicite');
                                }
                        }
                }
@@ -273,7 +297,7 @@ function formulaires_formidable_traiter($id, $valeurs = array(), $id_formulaires
 
        // POST Mortem de securite : on log le $_POST pour ne pas le perdre si quelque chose se passe mal
        include_spip('inc/json');
-       $post = json_encode($_POST);
+       $post = json_encode(array('post' => $_POST, 'files' => $_FILES));
        spip_log($post, 'formidable_post'._LOG_INFO_IMPORTANTE);
 
        // On peut donner soit un id soit un identifiant
@@ -283,7 +307,13 @@ function formulaires_formidable_traiter($id, $valeurs = array(), $id_formulaires
 
        $formulaire = sql_fetsel('*', 'spip_formulaires', 'id_formulaire = ' . $id_formulaire);
        $traitements = unserialize($formulaire['traitements']);
-
+       $traitements = pipeline(
+               'formidable_traitements',
+               array(
+                       'args'=>array('id_formulaire'=>$id_formulaire),
+                       'data'=>$traitements
+               )
+       );
        // selon le choix, le formulaire se remet en route à la fin ou non
        $retours['editable'] = ($formulaire['apres']=='formulaire');
        $retours['formidable_afficher_apres'] = $formulaire['apres'];
@@ -337,7 +367,6 @@ function formulaires_formidable_traiter($id, $valeurs = array(), $id_formulaires
                                }
                        }
                } while (count($retours['traitements']) < count($traitements) and $maxiter--);
-
                // si on ne peut pas traiter correctement, alerter le webmestre
                if (count($retours['traitements']) < count($traitements)) {
                        $erreur_texte = "Impossible de traiter correctement le formulaire $id\n"
@@ -352,16 +381,103 @@ function formulaires_formidable_traiter($id, $valeurs = array(), $id_formulaires
        } else {
                $retours['message_erreur'] = _T('formidable:retour_aucun_traitement');
        }
-
+       if (isset($retours['fichiers'])) {// traitement particuliers si fichiers
+               if ($erreurs_fichiers = formidable_produire_messages_erreurs_fichiers($retours['fichiers'])) {
+                       // Inspecter les fichiers pour voir s'il y a des erreurs
+                       // Avertir l'utilisateur
+                       if (isset($retours['message_erreur'])) {
+                               $retours['message_erreur'] .= '<br />'.$erreurs_fichiers['message_public'];
+                       } else {
+                               $retours['message_erreur'] = $erreurs_fichiers['message_public'];
+                       }
+                       // Avertir le webmestre
+                       if (isset($retours['id_formulaires_reponse'])) {
+                               $erreur_fichiers_sujet = '[ERREUR] Impossible de sauvegarder les fichiers de la réponse '.$retours['id_formulaires_reponse']." au formulaire $id";
+                       } else {
+                               $erreur_fichiers_sujet = "[ERREUR] Impossible de sauvegarder les fichiers de la réponse au formulaire $id";
+                       }
+                       $erreur_fichiers_texte = "Récupérez le plus rapidement possible les fichiers temporaires suivants\n";
+                       $erreur_fichiers_texte .= $erreurs_fichiers['message_webmestre'];
+                       $envoyer_mail = charger_fonction('envoyer_mail', 'inc');
+                       $envoyer_mail($GLOBALS['meta']['email_webmaster'], $erreur_fichiers_sujet, $erreur_fichiers_texte);
+               }
+               if ($formulaire['apres'] == 'valeurs') {
+                       // Si on affiche après les valeurs des réponses, modifier _request pour les saisies de types fichiers
+                       $vignette_par_defaut = charger_fonction('vignette', 'inc/');
+                       foreach ($retours['fichiers'] as $saisie => $description) {
+                               foreach ($description as $i => $desc) {
+                                       // ajouter la vignette et l'url
+                                       if (!isset($description[$i]['erreur'])) {
+                                               $description[$i]['vignette'] = $vignette_par_defaut($desc['extension'], false);
+                                               if (isset($retours['id_formulaires_reponse'])) {// si réponse enregistrée
+                                                       $description[$i]['url'] =  formidable_generer_url_action_recuperer_fichier($id_formulaire, $retours['id_formulaires_reponse'], $saisie, $desc['fichier']);
+                                               } elseif (isset($retours['timestamp'])) { // si réponse simplement envoyée par courriel
+                                                       $description[$i]['url'] = formidable_generer_url_action_recuperer_fichier_email(
+                                                               $saisie,
+                                                               $desc['fichier'],
+                                                               array('timestamp'=>$retours['timestamp'])
+                                                       );
+                                               }
+                                       }
+                               }
+                               set_request($saisie, $description);
+                       }
+               }
+       }
+       // Si on fait une redirection
+       // Et que l'on a enregistré le résultat
+       // Alors, passer l'id de la réponse à la page
+       if (isset($retours['id_formulaires_reponse']) AND isset($retours['redirect'])) {
+               $retours['redirect'] = parametre_url($retours['redirect'], 'id_formulaires_reponse', $retours['id_formulaires_reponse'], '&');
+       }
+       // lorsqu'on affichera à nouveau le html,
+       // dire à cvt-upload de ne pas générer le html pour les résultats des saisies fichiers
+       if ($formulaire['apres']=='formulaire' and isset($retours['fichiers'])) {
+               $formidable_cvtupload_precharger_fichiers = array();
+               set_request('_fichiers', null);
+               set_request('_cvtupload_precharger_fichiers_forcer', true);
+               foreach ($retours['fichiers'] as $champ => $valeur) {
+                       $i = -1;
+                       foreach ($valeur as $id => $info) {
+                               $i++;
+                               if (isset($info['fichier'])) {
+                                       $nom_fichier = $info['fichier'];
+                               } else {
+                                       $nom_fichier = $info['nom'];
+                               }
+                               if (isset($retours['id_formulaires_reponse'])) {
+                                       $chemin_fichier = _DIR_FICHIERS_FORMIDABLE
+                                               .'formulaire_'.$retours['id_formulaire']
+                                               .'/reponse_'.$retours['id_formulaires_reponse']
+                                               .'/'.$champ
+                                               .'/'.$nom_fichier;
+                                       $formidable_cvtupload_precharger_fichiers[$champ][$i]['url'] = formidable_generer_url_action_recuperer_fichier($retours['id_formulaire'], $retours['id_formulaires_reponse'], $champ, $nom_fichier);
+                                       $formidable_cvtupload_precharger_fichiers[$champ][$i]['chemin'] = $chemin_fichier;
+                               } elseif (isset($retours['timestamp'])) {
+                                       $chemin_fichier = _DIR_FICHIERS_FORMIDABLE
+                                               .'timestamp/'
+                                               .$retours['timestamp'].'/'
+                                               .$champ.'/'
+                                               .$nom_fichier;
+                                       $formidable_cvtupload_precharger_fichiers[$champ][$i]['chemin'] = $chemin_fichier;
+                                       $formidable_cvtupload_precharger_fichiers[$champ][$i]['url'] = formidable_generer_url_action_recuperer_fichier_email(
+                                               $champ,
+                                               $nom_fichier,
+                                               array('timestamp'=>$retours['timestamp'])
+                                       );
+                               }
+                       }
+               }
+               set_request('_formidable_cvtupload_precharger_fichiers', $formidable_cvtupload_precharger_fichiers);
+       }
        // si aucun traitement, alerter le webmestre pour ne pas perdre les donnees
        if (!$erreur_texte and !count($retours['traitements'])) {
                $erreur_texte = "Aucun traitement pour le formulaire $id\n";
        }
-
        if ($erreur_texte) {
                $erreur_sujet = "[ERREUR] Traitement Formulaire $id";
                // dumper la saisie pour ne pas la perdre
-               $erreur_texte .= "\n".var_export($_REQUEST, true);
+               $erreur_texte .= "\n".var_export($_REQUEST, true)."\n".var_export($_FILES, true);
                $envoyer_mail = charger_fonction('envoyer_mail', 'inc');
                $envoyer_mail($GLOBALS['meta']['email_webmaster'], $erreur_sujet, $erreur_texte);
        }
@@ -369,7 +485,34 @@ function formulaires_formidable_traiter($id, $valeurs = array(), $id_formulaires
        return $retours;
 }
 
+/**
+ * Déclare à cvtupload les champs fichiers du formulaire
+ *
+ * @param int|string $id
+ *     Identifiant numerique ou textuel du formulaire formidable
+ * @param array $valeurs
+ *     Valeurs par défauts passées au contexte du formulaire
+ *     Exemple : array('hidden_1' => 3) pour que champ identifie "@hidden_1@" soit prerempli
+ * @param int|bool $id_formulaires_reponse
+ *     Identifiant d'une réponse pour forcer la reedition de cette reponse spécifique
+ *
+ * @return array
+ *     Tableau des champs de type fichier
+ **/
+function formulaires_formidable_fichiers($id, $valeurs = array(), $id_formulaires_reponse = false) {
+       // On peut donner soit un id soit un identifiant
+       if (!$id_formulaire = formidable_id_formulaire($id)) {
+               return array();
+       }
 
+       // On cherche les saisies du formulaire
+       if ($saisies = sql_getfetsel('saisies', 'spip_formulaires', 'id_formulaire = ' . intval($id_formulaire))) {
+               $saisies = unserialize($saisies);
+               include_spip('inc/saisies_lister');
+               $saisies_fichiers = array_keys(saisies_lister_avec_type($saisies, 'fichiers'));
+               return $saisies_fichiers;
+       }
+}
 /**
  * Ajoute dans le contexte les elements
  * donnés par une reponse de formulaire indiquée
@@ -385,6 +528,12 @@ function formulaires_formidable_traiter($id, $valeurs = array(), $id_formulaires
  *
  **/
 function formidable_definir_contexte_avec_reponse($contexte, $id_formulaires_reponse, &$ok) {
+
+       // On prépare des infos si jamais on a des champs fichiers
+       $saisies_fichiers = saisies_lister_avec_type($contexte['_saisies'], 'fichiers');// les saisies de type fichier
+       $fichiers = array();
+       $id_formulaire = $contexte['_formidable']['id_formulaire'];
+
        // On va chercher tous les champs
        $champs = sql_allfetsel(
                'nom, valeur',
@@ -392,12 +541,61 @@ function formidable_definir_contexte_avec_reponse($contexte, $id_formulaires_rep
                'id_formulaires_reponse = ' . $id_formulaires_reponse
        );
        $ok = count($champs) ? true : false;
-
-       // On remplit le contexte avec
+       // On remplit le contexte avec les résultats précédents
        foreach ($champs as $champ) {
-               $test_array = unserialize($champ['valeur']);
-               $contexte[$champ['nom']] = is_array($test_array) ? $test_array : $champ['valeur'];
+               if (array_key_exists($champ['nom'], $saisies_fichiers)) {
+                       $valeur= unserialize($champ['valeur']);
+                       $nom = $champ['nom'];
+                       $fichiers[$nom] = array();
+                       $chemin = _DIR_FICHIERS_FORMIDABLE
+                               ."formulaire_$id_formulaire/reponse_$id_formulaires_reponse/"
+                               ."$nom/";
+                       foreach ($valeur as $f => $fichier) {
+                               $fichiers[$nom][$f]= array();
+                               $param = serialize(array(
+                                       'formulaire' => $id_formulaire,
+                                       'reponse' => $id_formulaires_reponse,
+                                       'fichier' => $fichier['nom'],
+                                       'saisie' => $champ['nom']
+                               ));
+                               $fichiers[$nom][$f]['url'] =  formidable_generer_url_action_recuperer_fichier($id_formulaire, $id_formulaires_reponse, $champ['nom'], $fichier['nom']);
+                               $fichiers[$nom][$f]['chemin'] = $chemin.$fichier['nom'];
+                       }
+               } else {
+                       $test_array = filtre_tenter_unserialize_dist($champ['valeur']);
+                       $contexte[$champ['nom']] = is_array($test_array) ? $test_array : $champ['valeur'];
+               }
+       }
+       if ($fichiers != array()) {//s'il y a des fichiers dans les réponses
+               $contexte['cvtupload_precharger_fichiers'] = $fichiers;
        }
-
        return $contexte;
 }
+
+/**
+ * Produire un message d'erreur concaténant les messages d'erreurs
+ * par fichier.
+ * Fournir également une forme pour l'envoyer par webmestre
+ * @param array $fichiers
+ *             le tableau des fichiers qui a été remplie par formidable_deplacer_fichiers_produire_vue_saisie()
+ * @return array ('message_public' => 'message', 'message_webmestre' => 'message'
+**/
+function formidable_produire_messages_erreurs_fichiers($fichiers) {
+       $message_public = '';
+       $message_webmestre = '';
+       foreach ($fichiers as $champ => $description_champ) {
+               foreach ($description_champ as $n => $description) {
+                       if (isset($description['erreur'])) {
+                               $message_public .= $description['erreur']."\n";
+                               $message_webmestre .= "Pour le champ $champ[$n]:\n"
+                                       . '- Le fichier temporaire : '.$description['tmp_name']."\n"
+                                       . '- Ayant pour véritable nom : '.$description['nom']." \n";
+                       }
+               }
+       }
+       if ($message_public !='') {
+               return array('message_public'=>$message_public, 'message_webmestre'=>$message_webmestre);
+       } else {
+               return '';
+       }
+}