[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / plugins / saisies / inc / saisies.php
index ad7a3e8..8243fa6 100644 (file)
@@ -11,28 +11,6 @@ if (!defined('_ECRIRE_INC_VERSION')) {
        return;
 }
 
-/*
- * Une librairie pour manipuler ou obtenir des infos sur un tableau de saisies
- *
- * saisies_lister_par_nom()
- * saisies_lister_champs()
- * saisies_lister_valeurs_defaut()
- * saisies_charger_champs()
- * saisies_chercher()
- * saisies_supprimer()
- * saisies_inserer()
- * saisies_deplacer()
- * saisies_modifier()
- * saisies_verifier()
- * saisies_comparer()
- * saisies_generer_html()
- * saisies_generer_vue()
- * saisies_generer_nom()
- * saisies_inserer_html()
- * saisies_lister_disponibles()
- * saisies_autonomes()
- */
-
 // Différentes méthodes pour trouver les saisies
 include_spip('inc/saisies_lister');
 
@@ -50,7 +28,8 @@ include_spip('inc/saisies_afficher');
  * @return array Retourne les saisies du formulaire sinon false
  */
 function saisies_chercher_formulaire($form, $args) {
-       if ($fonction_saisies = charger_fonction('saisies', 'formulaires/'.$form, true)
+       if (
+               $fonction_saisies = charger_fonction('saisies', 'formulaires/'.$form, true)
                and $saisies = call_user_func_array($fonction_saisies, $args)
                and is_array($saisies)
                // On passe les saisies dans un pipeline normé comme pour CVT
@@ -96,9 +75,11 @@ function saisies_chercher($saisies, $id_ou_nom_ou_chemin, $retourner_chemin = fa
                                                return $retourner_chemin ? array_merge($chemin, array('saisies'), $retour) : $retour;
                                }
                        }
-               } elseif (is_array($id_ou_nom_ou_chemin)) {
+               }
+               elseif (is_array($id_ou_nom_ou_chemin)) {
                        $chemin = $id_ou_nom_ou_chemin;
                        $saisie = $saisies;
+                       
                        // On vérifie l'existence quand même
                        foreach ($chemin as $cle) {
                                if (isset($saisie[$cle])) {
@@ -107,6 +88,7 @@ function saisies_chercher($saisies, $id_ou_nom_ou_chemin, $retourner_chemin = fa
                                        return null;
                                }
                        }
+                       
                        // Si c'est une vraie saisie
                        if ($saisie['saisie'] and $saisie['options']['nom']) {
                                return $retourner_chemin ? $chemin : $saisie;
@@ -152,9 +134,11 @@ function saisies_identifier($saisies, $regenerer = false) {
        if (!is_array($saisies)) {
                return array();
        }
+       
        foreach ($saisies as $k => $saisie) {
                $saisies[$k] = saisie_identifier($saisie, $regenerer);
        }
+       
        return $saisies;
 }
 
@@ -176,6 +160,7 @@ function saisie_identifier($saisie, $regenerer = false) {
        if (isset($saisie['saisies']) and is_array($saisie['saisies'])) {
                $saisie['saisies'] = saisies_identifier($saisie['saisies'], $regenerer);
        }
+       
        return $saisie;
 }
 
@@ -184,9 +169,10 @@ function saisie_identifier($saisie, $regenerer = false) {
  *
  * @param array $formulaire Le contenu d'un formulaire décrit dans un tableau de Saisies
  * @param bool $saisies_masquees_nulles Si TRUE, les saisies masquées selon afficher_si ne seront pas verifiées, leur valeur étant forcée a NULL. Cette valeur NULL est transmise à traiter (via set_request).
+ * @param array &$erreurs_fichiers pour les saisies de type fichiers, un tableau qui va stocker champs par champs, puis fichier par fichier, les erreurs de chaque fichier, pour pouvoir ensuite éventuellement supprimer les fichiers erronées de $_FILES
  * @return array Retourne un tableau d'erreurs
  */
-function saisies_verifier($formulaire, $saisies_masquees_nulles = true) {
+function saisies_verifier($formulaire, $saisies_masquees_nulles = true, &$erreurs_fichiers = array()) {
        include_spip('inc/verifier');
        $erreurs = array();
        $verif_fonction = charger_fonction('verifier', 'inc', true);
@@ -199,32 +185,57 @@ function saisies_verifier($formulaire, $saisies_masquees_nulles = true) {
        foreach ($saisies as $saisie) {
                $obligatoire = isset($saisie['options']['obligatoire']) ? $saisie['options']['obligatoire'] : '';
                $champ = $saisie['options']['nom'];
-               $file = ($saisie['saisie'] == 'input' and isset($saisie['options']['type']) and $saisie['options']['type'] == 'file');
+               $file = (($saisie['saisie'] == 'input' and isset($saisie['options']['type']) and $saisie['options']['type'] == 'file') or $saisie['saisie'] == 'fichiers');
                $verifier = isset($saisie['verifier']) ? $saisie['verifier'] : false;
-
-               // Si le nom du champ est un tableau indexé, il faut parser !
-               if (preg_match('/([\w]+)((\[[\w]+\])+)/', $champ, $separe)) {
-                       $valeur = _request($separe[1]);
-                       preg_match_all('/\[([\w]+)\]/', $separe[2], $index);
-                       // On va chercher au fond du tableau
-                       foreach ($index[1] as $cle) {
-                               $valeur = isset($valeur[$cle]) ? $valeur[$cle] : null;
+               
+               // Cas de la saisie 'fichiers':
+               if ($saisie['saisie'] == 'fichiers') {
+                       $infos_fichiers_precedents = _request('cvtupload_fichiers_precedents');
+                       if (isset($infos_fichiers_precedents[$champ])) { // si on a déjà envoyé des infos avants
+                               $valeur = $_FILES[$champ]; // on ne met pas true, car il faudra aussi vérifier les nouveaux fichiers du même champ qui viennent d'être envoyés.
+                       } elseif (isset($_FILES[$champ]['error'])) {//si jamais on a déja envoyé quelque chose dans le précédent envoi = ok
+                               $valeur = null; //On considère que par défaut on a envoyé aucun fichiers
+                               foreach ($_FILES[$champ]['error'] as $err) {
+                                       if ($err != 4) {
+                                               //Si un seul fichier a été envoyé, même avec une erreur,
+                                               // on considère que le critère obligatoire est rempli.
+                                               // Il faudrait que verifier/fichiers.php vérifier les autres types d'erreurs.
+                                               // Voir http://php.net/manual/fr/features.file-upload.errors.php
+                                               $valeur = $_FILES[$champ];
+                                               break;
+                                       }
+                               }
+                       } elseif (!isset($_FILES[$champ])) {
+                               $valeur = null;
                        }
-               } else {
-                       // Sinon la valeur est juste celle du nom
-                       $valeur = _request($champ);
                }
-
+               // Tout type de saisie, sauf fichiers
+               else {
+                       // Si le nom du champ est un tableau indexé, il faut parser !
+                       if (preg_match('/([\w]+)((\[[\w]+\])+)/', $champ, $separe)) {
+                               $valeur = _request($separe[1]);
+                               preg_match_all('/\[([\w]+)\]/', $separe[2], $index);
+                               // On va chercher au fond du tableau
+                               foreach ($index[1] as $cle) {
+                                       $valeur = isset($valeur[$cle]) ? $valeur[$cle] : null;
+                               }
+                       } else {
+                               // Sinon la valeur est juste celle du nom
+                               $valeur = _request($champ);
+                       }
+               }
+               
                // Pour la saisie "destinataires" il faut filtrer si jamais on a mis un premier choix vide
                if ($saisie['saisie'] == 'destinataires') {
                        $valeur = array_filter($valeur);
                }
-
+               
                // On regarde d'abord si le champ est obligatoire
-               if ($obligatoire
+               if (
+                       $obligatoire
                        and $obligatoire != 'non'
                        and (
-                               ($file and !$_FILES[$champ]['name'])
+                               ($file and $valeur==null)
                                or (!$file and (
                                        is_null($valeur)
                                        or (is_string($valeur) and trim($valeur) == '')
@@ -240,18 +251,42 @@ function saisies_verifier($formulaire, $saisies_masquees_nulles = true) {
 
                // On continue seulement si ya pas d'erreur d'obligation et qu'il y a une demande de verif
                if ((!isset($erreurs[$champ]) or !$erreurs[$champ]) and is_array($verifier) and $verif_fonction) {
-                       $normaliser = null;
+                       // Si on fait une vérification de type fichiers, il n'y a pas vraiment de normalisation, mais un retour d'erreur fichiers par fichiers
+                       if ($verifier['type'] == 'fichiers') {
+                               $normaliser = array();
+                       } else {
+                               $normaliser = null;
+                       }
+                       
                        // Si le champ n'est pas valide par rapport au test demandé, on ajoute l'erreur
                        $options = isset($verifier['options']) ? $verifier['options'] : array();
                        if ($erreur_eventuelle = $verif_fonction($valeur, $verifier['type'], $options, $normaliser)) {
                                $erreurs[$champ] = $erreur_eventuelle;
+
+                               if ($verifier['type'] == 'fichiers') { // Pour les vérification/saisies de type fichiers, ajouter les erreurs détaillées par fichiers dans le tableau des erreurs détaillées par fichier
+                                       $erreurs_fichiers[$champ] = $normaliser;
+                               }
+
+                       }
                        // S'il n'y a pas d'erreur et que la variable de normalisation a été remplie, on l'injecte dans le POST
-                       } elseif (!is_null($normaliser)) {
+                       elseif (!is_null($normaliser) and $verifier['type'] != 'fichiers') {
                                set_request($champ, $normaliser);
                        }
                }
        }
-
+       
+       // Last but not least, on passe nos résultats à un pipeline
+       $erreurs = pipeline(
+               'saisies_verifier',
+               array(
+                       'args'=>array(
+                               'formulaire' => $formulaire,
+                               'saisies' => $saisies
+                       ),
+                       'data' => $erreurs
+               )
+       );
+       
        return $erreurs;
 }
 
@@ -262,6 +297,7 @@ function saisies_verifier($formulaire, $saisies_masquees_nulles = true) {
  */
 function saisies_aplatir_tableau($tab) {
        $nouveau_tab = array();
+       
        foreach ($tab as $entree => $contenu) {
                if (is_array($contenu)) {
                        foreach ($contenu as $cle => $valeur) {
@@ -271,6 +307,7 @@ function saisies_aplatir_tableau($tab) {
                        $nouveau_tab[$entree] = $contenu;
                }
        }
+       
        return $nouveau_tab;
 }
 
@@ -299,6 +336,7 @@ function saisies_chaine2tableau($chaine, $separateur = "\n") {
        if ($chaine and is_string($chaine)) {
                $tableau = array();
                $soustab = false;
+               
                // On découpe d'abord en lignes
                $lignes = explode($separateur, $chaine);
                foreach ($lignes as $i => $ligne) {
@@ -337,10 +375,12 @@ function saisies_chaine2tableau($chaine, $separateur = "\n") {
                        }
                }
                return $tableau;
-       } elseif (is_array($chaine)) {
+       }
+       elseif (is_array($chaine)) {
                // Si c'est déjà un tableau on lui applique _T_ou_typo (qui fonctionne de manière récursive avant de le renvoyer
                return _T_ou_typo($chaine, 'multi');
-       } else {
+       }
+       else {
                return array();
        }
 }
@@ -360,6 +400,7 @@ function saisies_tableau2chaine($tableau) {
        if ($tableau and is_array($tableau)) {
                $chaine = '';
                $avant_est_tableau = false;
+               
                foreach ($tableau as $cle => $valeur) {
                        if (is_array($valeur)) {
                                $avant_est_tableau = true;
@@ -378,10 +419,12 @@ function saisies_tableau2chaine($tableau) {
                $chaine = trim($chaine);
 
                return $chaine;
-       } elseif (is_string($tableau)) {
+       }
+       elseif (is_string($tableau)) {
                // Si c'est déjà une chaine on la renvoie telle quelle
                return $tableau;
-       } else {
+       }
+       else {
                return '';
        }
 }
@@ -432,9 +475,14 @@ function saisies_trouver_choix_alternatif($data, $valeur) {
        if (!is_array($data)) {
                $data = saisies_chaine2tableau($data) ;
        }
+       
        $choix_theorique = array_keys($data);
        $choix_alternatif = array_values(array_diff($valeur, $choix_theorique));
-       return $choix_alternatif[0];//on suppose que personne ne s'est amusé à proposer deux choix alternatifs
+       if (isset($choix_alternatif[0])) {
+               return $choix_alternatif[0]; //on suppose que personne ne s'est amusé à proposer deux choix alternatifs
+       } else {
+               return '';
+       }
 }
 
 /**
@@ -481,15 +529,16 @@ function saisies_generer_aide() {
  * @param array $saisies Un tableau de saisies
  * @return boolean
  */
-
 function saisies_afficher_si($saisies) {
        $saisies = saisies_lister_par_nom($saisies, true);
+       
        // Dès qu'il y a au moins une option afficher_si, on l'active
        foreach ($saisies as $saisie) {
                if (isset($saisie['options']['afficher_si'])) {
                        return true;
                }
        }
+       
        return false;
 }
 
@@ -502,11 +551,13 @@ function saisies_afficher_si($saisies) {
  */
 function saisies_afficher_si_remplissage($saisies) {
        $saisies = saisies_lister_par_nom($saisies, true);
+       
        // Dès qu'il y a au moins une option afficher_si_remplissage, on l'active
        foreach ($saisies as $saisie) {
                if (isset($saisie['options']['afficher_si_remplissage'])) {
                        return true;
                }
        }
+       
        return false;
 }