[SPIP][PLUGINS] v3.0-->v3.2
[lhc/web/www.git] / www / plugins-dist / medias / inc / joindre_document.php
index 090038f..63324e7 100644 (file)
-<?php\r
-\r
-/***************************************************************************\\r
- *  SPIP, Systeme de publication pour l'internet                           *\r
- *                                                                         *\r
- *  Copyright (c) 2001-2016                                                *\r
- *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *\r
- *                                                                         *\r
- *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *\r
- *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *\r
-\***************************************************************************/\r
-\r
-if (!defined("_ECRIRE_INC_VERSION")) return;\r
-\r
-\r
-/**\r
- * Recuperer le nom du fichier selon le mode d'upload choisi\r
- * et mettre cela au format $_FILES\r
- * \r
- * Renvoie une liste de fichier ou un message en cas d'erreur\r
- *\r
- * @return string/array\r
- */\r
-function joindre_trouver_fichier_envoye(){\r
-       static $files = array();\r
-       // on est appele deux fois dans un hit, resservir ce qu'on a trouve a la verif\r
-       // lorsqu'on est appelle au traitement\r
-       \r
-       if (count($files))\r
-               return $files;\r
-       \r
-       if (_request('joindre_upload')){\r
-               $post = isset($_FILES) ? $_FILES : $GLOBALS['HTTP_POST_FILES'];\r
-               $files = array();\r
-               if (is_array($post)){\r
-                       include_spip('action/ajouter_documents');\r
-                 foreach ($post as $file) {\r
-                       if (is_array($file['name'])){\r
-                               while (count($file['name'])){\r
-                                               $test=array(\r
-                                                       'error'=>array_shift($file['error']),\r
-                                                       'name'=>array_shift($file['name']),\r
-                                                       'tmp_name'=>array_shift($file['tmp_name']),\r
-                                                       'type'=>array_shift($file['type']),\r
-                                                       );\r
-                                               if (!($test['error'] == 4)){\r
-                                                       if (is_string($err = joindre_upload_error($test['error'])))\r
-                                                               return $err; // un erreur upload\r
-                                                       if (!is_array(verifier_upload_autorise($test['name'])))\r
-                                                               return _T('medias:erreur_upload_type_interdit',array('nom'=>$test['name']));\r
-                                                       $files[]=$test;\r
-                                               }\r
-                               }\r
-                       }\r
-                       else {\r
-                               //UPLOAD_ERR_NO_FILE\r
-                                       if (!($file['error'] == 4)){\r
-                                               if (is_string($err = joindre_upload_error($file['error'])))\r
-                                                       return $err; // un erreur upload\r
-                                               if (!is_array(verifier_upload_autorise($file['name'])))\r
-                                                       return _T('medias:erreur_upload_type_interdit',array('nom'=>$file['name']));\r
-                                               $files[]=$file;\r
-                                       }\r
-                       }\r
-                       }\r
-                       if (!count($files))\r
-                               return _T('medias:erreur_indiquez_un_fichier');\r
-               }\r
-               return $files;\r
-       }\r
-       elseif (_request('joindre_distant')){\r
-               $path = _request('url');\r
-               if (!strlen($path) OR $path=='http://')\r
-                       return _T('medias:erreur_indiquez_un_fichier');\r
-               include_spip('action/ajouter_documents');\r
-               $infos = renseigner_source_distante($path);\r
-               if (!is_array($infos))\r
-                       return $infos; // message d'erreur\r
-               else\r
-                       return array(\r
-                               array(\r
-                                       'name' => basename($path),\r
-                                       'tmp_name' => $path,\r
-                                       'distant' => true,\r
-                               )\r
-                       );\r
-       }\r
-       elseif (_request('joindre_ftp')){\r
-               $path = _request('cheminftp');\r
-               if (!$path || strstr($path, '..')) return _T('medias:erreur_indiquez_un_fichier');\r
-               \r
-               include_spip('inc/documents');  \r
-               include_spip('inc/actions');\r
-               $upload = determine_upload();\r
-               if ($path != '/' AND $path != './') $upload .= $path;\r
-       \r
-               if (!is_dir($upload))\r
-                 // seul un fichier est demande\r
-                 return array(\r
-                       array (\r
-                               'name' => basename($upload),\r
-                                       'tmp_name' => $upload\r
-                               )\r
-                       );\r
-               else {\r
-                 // on upload tout un repertoire\r
-                 $files = array();\r
-                 foreach (preg_files($upload) as $fichier) {\r
-                               $files[]= array (\r
-                                       'name' => basename($fichier),\r
-                                       'tmp_name' => $fichier\r
-                               );\r
-                 }\r
-                 return $files;\r
-               }\r
-       }\r
-       elseif (_request('joindre_zip') and $token_zip = _request('chemin_zip')) {\r
-\r
-               $zip_to_clean = (isset($GLOBALS['visiteur_session']['zip_to_clean']) ? unserialize($GLOBALS['visiteur_session']['zip_to_clean']) : array());\r
-               if (!$zip_to_clean or !isset($zip_to_clean[$token_zip]) or !$path = $zip_to_clean[$token_zip]){\r
-                       return _T('avis_operation_impossible');\r
-               }\r
-\r
-               include_spip('inc/documents'); //pour creer_repertoire_documents\r
-               define('_tmp_zip', $path);\r
-               define('_tmp_dir', creer_repertoire_documents(md5($path.$GLOBALS['visiteur_session']['id_auteur'])));\r
-               if (_tmp_dir == _DIR_IMG)\r
-                       return _T('avis_operation_impossible');\r
-               \r
-               $files = array();\r
-               if (_request('options_upload_zip')=='deballe')\r
-                       $files = joindre_deballer_lister_zip($path,_tmp_dir);\r
-         \r
-               // si le zip doit aussi etre conserve, l'ajouter\r
-               if (_request('options_upload_zip')=='upload' OR _request('options_deballe_zip_conserver')){\r
-               $files[] = array(\r
-                               'name' => basename($path),\r
-                               'tmp_name' => $path,\r
-               );\r
-         }\r
-\r
-         return $files;\r
-               \r
-       }\r
-\r
-       return array();\r
-}\r
-\r
-\r
-// Erreurs d'upload\r
-// renvoie false si pas d'erreur\r
-// et true si erreur = pas de fichier\r
-// pour les autres erreurs renvoie le message d'erreur\r
-function joindre_upload_error($error) {\r
-\r
-       if (!$error) return false;\r
-       spip_log("Erreur upload $error -- cf. http://php.net/manual/fr/features.file-upload.errors.php");\r
-       switch ($error) {\r
-                       \r
-               case 4: /* UPLOAD_ERR_NO_FILE */\r
-                       return true;\r
-\r
-               # on peut affiner les differents messages d'erreur\r
-               case 1: /* UPLOAD_ERR_INI_SIZE */\r
-                       $msg = _T('medias:upload_limit',\r
-                       array('max' => ini_get('upload_max_filesize')));\r
-                       break;\r
-               case 2: /* UPLOAD_ERR_FORM_SIZE */\r
-                       $msg = _T('medias:upload_limit',\r
-                       array('max' => ini_get('upload_max_filesize')));\r
-                       break;\r
-               case 3: /* UPLOAD_ERR_PARTIAL  */\r
-                       $msg = _T('medias:upload_limit',\r
-                       array('max' => ini_get('upload_max_filesize')));\r
-                       break;\r
-               case 6: /* UPLOAD_ERR_NO_TMP_DIR  */\r
-                       $msg = _T('medias:erreur_dossier_tmp_manquant');\r
-                       break;\r
-               case 7: /* UPLOAD_ERR_CANT_WRITE */\r
-                       $msg = _T('medias:erreur_ecriture_fichier');\r
-\r
-               default: /* autre */\r
-                       if (!$msg)\r
-                       $msg = _T('pass_erreur').' '. $error\r
-                       . '<br />' . propre("[->http://php.net/manual/fr/features.file-upload.errors.php]");\r
-                       break;\r
-       }\r
-\r
-       spip_log ("erreur upload $error");\r
-       return $msg;\r
-       \r
-}\r
-\r
-/**\r
- * Verifier si le fichier poste est un zip\r
- * Si on sait le deballer, proposer les options necessaires\r
- *\r
- * @param array $files\r
- * @return string\r
- */\r
-function joindre_verifier_zip($files){\r
-       if (function_exists('gzopen')\r
-        AND (count($files) == 1)\r
-        AND !isset($files[0]['distant'])\r
-        AND \r
-         (preg_match('/\.zip$/i', $files[0]['name']) \r
-          OR (isset($files[0]['type']) AND $files[0]['type'] == 'application/zip'))\r
-         ){\r
-       \r
-         // on pose le fichier dans le repertoire zip \r
-         // (nota : copier_document n'ecrase pas un fichier avec lui-meme\r
-         // ca autorise a boucler)\r
-         include_spip('inc/getdocument');\r
-               $desc = $files[0];\r
-               $zip = copier_document("zip",\r
-                                       $desc['name'],\r
-                                       $desc['tmp_name']\r
-                               );\r
-               \r
-               // Est-ce qu'on sait le lire ?\r
-               include_spip('inc/pclzip');\r
-               if ($zip\r
-                       AND $archive = new PclZip($zip)\r
-                 AND $contenu = joindre_decrire_contenu_zip($archive)\r
-                       AND $tmp = sous_repertoire(_DIR_TMP,"zip")\r
-                 AND rename($zip, $tmp = $tmp.basename($zip))\r
-                 ){\r
-                       $zip_to_clean = (isset($GLOBALS['visiteur_session']['zip_to_clean'])?unserialize($GLOBALS['visiteur_session']['zip_to_clean']):array());\r
-                       $zip_to_clean[md5($tmp)] = $tmp;\r
-                       session_set('zip_to_clean',serialize($zip_to_clean));\r
-                       $contenu[] = $tmp;\r
-                       return $contenu;\r
-                }\r
-       }\r
-       \r
-       // ce n'est pas un zip sur lequel il faut demander plus de precisions\r
-       return false;\r
-}\r
-\r
-/**\r
- * Verifier et decrire les fichiers de l'archive, en deux listes :\r
- * - une liste des noms de fichiers ajoutables\r
- * - une liste des erreurs (fichiers refuses)\r
- *\r
- * @param object $zip\r
- * @return array\r
- */\r
-function joindre_decrire_contenu_zip($zip) {\r
-       include_spip('action/ajouter_documents');\r
-       // si pas possible de decompacter: installer comme fichier zip joint\r
-       if (!$list = $zip->listContent()) return false;\r
-\r
-       // Verifier si le contenu peut etre uploade (verif extension)\r
-       $fichiers = array();\r
-       $erreurs = array();\r
-       foreach ($list as $file) {\r
-               if (accepte_fichier_upload($f = $file['stored_filename']))\r
-                       $fichiers[$f] = $file;\r
-               else\r
-                       // pas de message pour les dossiers et fichiers caches\r
-                       if (substr($f,-1)!=='/' AND substr(basename($f),0,1)!=='.')\r
-                               $erreurs[] = _T('medias:erreur_upload_type_interdit',array('nom'=>$f));\r
-       }\r
-\r
-       // si aucun fichier uploadable : installer comme fichier zip joint\r
-       if (!count($fichiers))\r
-               return false;\r
-\r
-       ksort($fichiers);\r
-       return array($fichiers,$erreurs);\r
-}\r
-\r
-\r
-\r
-// https://code.spip.net/@joindre_deballes\r
-function joindre_deballer_lister_zip($path,$tmp_dir) {\r
-  include_spip('inc/pclzip');\r
-       $archive = new PclZip($path);\r
-       $archive->extract(\r
-               PCLZIP_OPT_PATH, _tmp_dir,\r
-               PCLZIP_CB_PRE_EXTRACT, 'callback_deballe_fichier'\r
-       );\r
-       if ($contenu = joindre_decrire_contenu_zip($archive)){\r
-               $files = array();\r
-               $fichiers = reset($contenu);            \r
-               foreach($fichiers as $fichier){\r
-                       $f = basename($fichier['filename']);\r
-                       $files[] = array('tmp_name'=>$tmp_dir. $f,'name'=>$f,'titrer'=>_request('options_deballe_zip_titrer'),'mode'=>_request('options_deballe_zip_mode_document')?'document':null);\r
-               }\r
-               return $files;\r
-       }\r
-       return _T('avis_operation_impossible');\r
-}\r
-\r
-if (!function_exists('fixer_extension_document')){\r
-/**\r
- * Cherche dans la base le type-mime du tableau representant le document\r
- * et corrige le nom du fichier ; retourne array(extension, nom corrige)\r
- * s'il ne trouve pas, retourne '' et le nom inchange\r
- *\r
- * @param unknown_type $doc\r
- * @return unknown\r
- */\r
-// https://code.spip.net/@fixer_extension_document\r
-function fixer_extension_document($doc) {\r
-       $extension = '';\r
-       $name = $doc['name'];\r
-       if (preg_match(',\.([^.]+)$,', $name, $r)\r
-        AND $t = sql_fetsel("extension", "spip_types_documents",       "extension=" . sql_quote(corriger_extension($r[1])))\r
-        ) {\r
-               $extension = $t['extension'];\r
-               $name = preg_replace(',\.[^.]*$,', '', $doc['name']).'.'.$extension;\r
-       }\r
-       else if ($t = sql_fetsel("extension", "spip_types_documents",   "mime_type=" . sql_quote($doc['type']))) {\r
-               $extension = $t['extension'];\r
-               $name = preg_replace(',\.[^.]*$,', '', $doc['name']).'.'.$extension;\r
-       }\r
-\r
-       return array($extension,$name);\r
-}\r
-}\r
-\r
-//\r
-// Gestion des fichiers ZIP\r
-//\r
-// https://code.spip.net/@accepte_fichier_upload\r
-\r
-function accepte_fichier_upload ($f) {\r
-       if (!preg_match(",.*__MACOSX/,", $f)\r
-       AND !preg_match(",^\.,", basename($f))) {\r
-       include_spip('action/ajouter_documents');\r
-               $ext = corriger_extension((strtolower(substr(strrchr($f, "."), 1))));\r
-               return sql_countsel('spip_types_documents', "extension=" . sql_quote($ext) . " AND upload='oui'");\r
-       }\r
-}\r
-\r
-# callback pour le deballage d'un zip telecharge\r
-# http://www.phpconcept.net/pclzip/man/en/?options-pclzip_cb_pre_extractfunction\r
-// https://code.spip.net/@callback_deballe_fichier\r
-\r
-function callback_deballe_fichier($p_event, &$p_header) {\r
-       if (accepte_fichier_upload($p_header['filename'])) {\r
-               $p_header['filename'] = _tmp_dir . basename($p_header['filename']);\r
-               return 1;\r
-       } else {\r
-               return 0;\r
-       }\r
-}\r
-\r
-?>\r
+<?php
+
+/***************************************************************************\
+ *  SPIP, Systeme de publication pour l'internet                           *
+ *                                                                         *
+ *  Copyright (c) 2001-2016                                                *
+ *  Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James  *
+ *                                                                         *
+ *  Ce programme est un logiciel libre distribue sous licence GNU/GPL.     *
+ *  Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne.   *
+\***************************************************************************/
+
+if (!defined('_ECRIRE_INC_VERSION')) {
+       return;
+}
+
+
+/**
+ * Recuperer le nom du fichier selon le mode d'upload choisi
+ * et mettre cela au format $_FILES
+ *
+ * Renvoie une liste de fichier ou un message en cas d'erreur
+ *
+ * @return string/array
+ */
+function joindre_trouver_fichier_envoye() {
+       static $files = array();
+       // on est appele deux fois dans un hit, resservir ce qu'on a trouve a la verif
+       // lorsqu'on est appelle au traitement
+
+       if (count($files)) {
+               return $files;
+       }
+
+       if (_request('joindre_upload')) {
+               $post = isset($_FILES) ? $_FILES : $GLOBALS['HTTP_POST_FILES'];
+               $files = array();
+               if (is_array($post)) {
+                       include_spip('action/ajouter_documents');
+                       foreach ($post as $file) {
+                               if (is_array($file['name'])) {
+                                       while (count($file['name'])) {
+                                               $test = array(
+                                                       'error' => array_shift($file['error']),
+                                                       'name' => array_shift($file['name']),
+                                                       'tmp_name' => array_shift($file['tmp_name']),
+                                                       'type' => array_shift($file['type']),
+                                               );
+                                               if (!($test['error'] == 4)) {
+                                                       if (is_string($err = joindre_upload_error($test['error']))) {
+                                                               return $err;
+                                                       } // un erreur upload
+                                                       if (!is_array(verifier_upload_autorise($test['name']))) {
+                                                               return _T('medias:erreur_upload_type_interdit', array('nom' => $test['name']));
+                                                       }
+                                                       $files[] = $test;
+                                               }
+                                       }
+                               } else {
+                                       //UPLOAD_ERR_NO_FILE
+                                       if (!($file['error'] == 4)) {
+                                               if (is_string($err = joindre_upload_error($file['error']))) {
+                                                       return $err;
+                                               } // un erreur upload
+                                               if (!is_array(verifier_upload_autorise($file['name']))) {
+                                                       return _T('medias:erreur_upload_type_interdit', array('nom' => $file['name']));
+                                               }
+                                               $files[] = $file;
+                                       }
+                               }
+                       }
+                       if (!count($files)) {
+                               return _T('medias:erreur_indiquez_un_fichier');
+                       }
+               }
+
+               return $files;
+       } elseif (_request('joindre_distant')) {
+               $path = _request('url');
+               if (!strlen($path) or $path == 'http://') {
+                       return _T('medias:erreur_indiquez_un_fichier');
+               }
+               include_spip('action/ajouter_documents');
+               $infos = renseigner_source_distante($path);
+               if (!is_array($infos)) {
+                       return $infos;
+               } // message d'erreur
+               else {
+                       return array(
+                               array(
+                                       'name' => basename($path),
+                                       'tmp_name' => $path,
+                                       'distant' => true,
+                               )
+                       );
+               }
+       } elseif (_request('joindre_ftp')) {
+               $path = _request('cheminftp');
+               if (!$path || strstr($path, '..')) {
+                       return _T('medias:erreur_indiquez_un_fichier');
+               }
+
+               include_spip('inc/documents');
+               include_spip('inc/actions');
+               $upload = determine_upload();
+               if ($path != '/' and $path != './') {
+                       $upload .= $path;
+               }
+
+               if (!is_dir($upload)) {
+                       // seul un fichier est demande
+                       return array(
+                               array(
+                                       'name' => basename($upload),
+                                       'tmp_name' => $upload
+                               )
+                       );
+               } else {
+                       // on upload tout un repertoire
+                       $files = array();
+                       foreach (preg_files($upload) as $fichier) {
+                               $files[] = array(
+                                       'name' => basename($fichier),
+                                       'tmp_name' => $fichier
+                               );
+                       }
+
+                       return $files;
+               }
+       } elseif (_request('joindre_zip') and $token_zip = _request('chemin_zip')) {
+               $zip_to_clean = (isset($GLOBALS['visiteur_session']['zip_to_clean']) ?
+                       unserialize($GLOBALS['visiteur_session']['zip_to_clean']) : array());
+               if (!$zip_to_clean
+                       or !isset($zip_to_clean[$token_zip])
+                       or !$path = $zip_to_clean[$token_zip]) {
+                       return _T('avis_operation_impossible');
+               }
+
+               include_spip('inc/documents'); //pour creer_repertoire_documents
+               define('_TMP_ZIP', $path);
+               define('_TMP_DIR', creer_repertoire_documents(md5($path . $GLOBALS['visiteur_session']['id_auteur'])));
+               if (_TMP_DIR == _DIR_IMG) {
+                       return _T('avis_operation_impossible');
+               }
+
+               $files = array();
+               if (_request('options_upload_zip') == 'deballe') {
+                       $files = joindre_deballer_lister_zip($path, _TMP_DIR);
+               }
+
+               // si le zip doit aussi etre conserve, l'ajouter
+               if (_request('options_upload_zip') == 'upload' or _request('options_deballe_zip_conserver')) {
+                       $files[] = array(
+                               'name' => basename($path),
+                               'tmp_name' => $path,
+                       );
+               }
+               return $files;
+       }
+
+       return array();
+}
+
+
+// Erreurs d'upload
+// renvoie false si pas d'erreur
+// et true si erreur = pas de fichier
+// pour les autres erreurs renvoie le message d'erreur
+function joindre_upload_error($error) {
+
+       if (!$error) {
+               return false;
+       }
+       spip_log("Erreur upload $error -- cf. http://php.net/manual/fr/features.file-upload.errors.php");
+       switch ($error) {
+               case 4: /* UPLOAD_ERR_NO_FILE */
+                       return true;
+
+               # on peut affiner les differents messages d'erreur
+               case 1: /* UPLOAD_ERR_INI_SIZE */
+                       $msg = _T(
+                               'medias:upload_limit',
+                               array('max' => ini_get('upload_max_filesize'))
+                       );
+                       break;
+               case 2: /* UPLOAD_ERR_FORM_SIZE */
+                       $msg = _T(
+                               'medias:upload_limit',
+                               array('max' => ini_get('upload_max_filesize'))
+                       );
+                       break;
+               case 3: /* UPLOAD_ERR_PARTIAL  */
+                       $msg = _T(
+                               'medias:upload_limit',
+                               array('max' => ini_get('upload_max_filesize'))
+                       );
+                       break;
+               case 6: /* UPLOAD_ERR_NO_TMP_DIR  */
+                       $msg = _T('medias:erreur_dossier_tmp_manquant');
+                       break;
+               case 7: /* UPLOAD_ERR_CANT_WRITE */
+                       $msg = _T('medias:erreur_ecriture_fichier');
+                       break;
+               default: /* autre */
+                       if (!$msg) {
+                               $msg = _T('pass_erreur') . ' ' . $error
+                                       . '<br />' . propre('[->http://php.net/manual/fr/features.file-upload.errors.php]');
+                       }
+                       break;
+       }
+       spip_log("erreur upload $error");
+       return $msg;
+}
+
+/**
+ * Verifier si le fichier poste est un zip
+ * Si on sait le deballer, proposer les options necessaires
+ *
+ * @param array $files
+ * @return string
+ */
+function joindre_verifier_zip($files) {
+       if (function_exists('gzopen')
+               and (count($files) == 1)
+               and !isset($files[0]['distant'])
+               and
+               (preg_match('/\.zip$/i', $files[0]['name'])
+                       or (isset($files[0]['type']) and $files[0]['type'] == 'application/zip'))
+       ) {
+               // on pose le fichier dans le repertoire zip
+               // (nota : copier_document n'ecrase pas un fichier avec lui-meme
+               // ca autorise a boucler)
+               include_spip('inc/getdocument');
+               $desc = $files[0];
+               $zip = copier_document(
+                       'zip',
+                       $desc['name'],
+                       $desc['tmp_name']
+               );
+
+               // Est-ce qu'on sait le lire ?
+               include_spip('inc/pclzip');
+               if ($zip
+                       and $archive = new PclZip($zip)
+                       and $contenu = joindre_decrire_contenu_zip($archive)
+                       and $tmp = sous_repertoire(_DIR_TMP, 'zip')
+                       and rename($zip, $tmp = $tmp . basename($zip))
+               ) {
+                       $zip_to_clean = (isset($GLOBALS['visiteur_session']['zip_to_clean']) ?
+                               unserialize($GLOBALS['visiteur_session']['zip_to_clean']) : array());
+                       $zip_to_clean[md5($tmp)] = $tmp;
+                       session_set('zip_to_clean', serialize($zip_to_clean));
+                       $contenu[] = $tmp;
+
+                       return $contenu;
+               }
+       }
+
+       // ce n'est pas un zip sur lequel il faut demander plus de precisions
+       return false;
+}
+
+/**
+ * Verifier et decrire les fichiers de l'archive, en deux listes :
+ * - une liste des noms de fichiers ajoutables
+ * - une liste des erreurs (fichiers refuses)
+ *
+ * @param object $zip
+ * @return array
+ */
+function joindre_decrire_contenu_zip($zip) {
+       include_spip('action/ajouter_documents');
+       // si pas possible de decompacter: installer comme fichier zip joint
+       if (!$list = $zip->listContent()) {
+               return false;
+       }
+
+       // Verifier si le contenu peut etre uploade (verif extension)
+       $fichiers = array();
+       $erreurs = array();
+       foreach ($list as $file) {
+               if (accepte_fichier_upload($f = $file['stored_filename'])) {
+                       $fichiers[$f] = $file;
+               } else // pas de message pour les dossiers et fichiers caches
+               {
+                       if (substr($f, -1) !== '/' and substr(basename($f), 0, 1) !== '.') {
+                               $erreurs[] = _T('medias:erreur_upload_type_interdit', array('nom' => $f));
+                       }
+               }
+       }
+
+       // si aucun fichier uploadable : installer comme fichier zip joint
+       if (!count($fichiers)) {
+               return false;
+       }
+
+       ksort($fichiers);
+
+       return array($fichiers, $erreurs);
+}
+
+
+// https://code.spip.net/@joindre_deballes
+function joindre_deballer_lister_zip($path, $tmp_dir) {
+       include_spip('inc/pclzip');
+       $archive = new PclZip($path);
+       $archive->extract(
+               PCLZIP_OPT_PATH,
+               _TMP_DIR,
+               PCLZIP_CB_PRE_EXTRACT,
+               'callback_deballe_fichier'
+       );
+       if ($contenu = joindre_decrire_contenu_zip($archive)) {
+               $files = array();
+               $fichiers = reset($contenu);
+               foreach ($fichiers as $fichier) {
+                       $f = basename($fichier['filename']);
+                       $files[] = array(
+                               'tmp_name' => $tmp_dir . $f,
+                               'name' => $f,
+                               'titrer' => _request('options_deballe_zip_titrer'),
+                               'mode' => _request('options_deballe_zip_mode_document') ? 'document' : null
+                       );
+               }
+
+               return $files;
+       }
+
+       return _T('avis_operation_impossible');
+}
+
+if (!function_exists('fixer_extension_document')) {
+       /**
+        * Cherche dans la base le type-mime du tableau representant le document
+        * et corrige le nom du fichier ; retourne array(extension, nom corrige)
+        * s'il ne trouve pas, retourne '' et le nom inchange
+        *
+        * @param unknown_type $doc
+        * @return unknown
+        */
+// https://code.spip.net/@fixer_extension_document
+       function fixer_extension_document($doc) {
+               $extension = '';
+               $name = $doc['name'];
+               if (preg_match(',\.([^.]+)$,', $name, $r)
+                       and $t = sql_fetsel(
+                               'extension',
+                               'spip_types_documents',
+                               'extension=' . sql_quote(corriger_extension($r[1]))
+                       )
+               ) {
+                       $extension = $t['extension'];
+                       $name = preg_replace(',\.[^.]*$,', '', $doc['name']) . '.' . $extension;
+               } else {
+                       if ($t = sql_fetsel('extension', 'spip_types_documents', 'mime_type=' . sql_quote($doc['type']))) {
+                               $extension = $t['extension'];
+                               $name = preg_replace(',\.[^.]*$,', '', $doc['name']) . '.' . $extension;
+                       }
+               }
+
+               return array($extension, $name);
+       }
+}
+
+//
+// Gestion des fichiers ZIP
+//
+// https://code.spip.net/@accepte_fichier_upload
+
+function accepte_fichier_upload($f) {
+       if (!preg_match(',.*__MACOSX/,', $f)
+               and !preg_match(',^\.,', basename($f))
+       ) {
+               include_spip('action/ajouter_documents');
+               $ext = corriger_extension((strtolower(substr(strrchr($f, '.'), 1))));
+
+               return sql_countsel(
+                       'spip_types_documents',
+                       'extension=' . sql_quote($ext) . " AND upload='oui'"
+               );
+       }
+}
+
+# callback pour le deballage d'un zip telecharge
+# http://www.phpconcept.net/pclzip/man/en/?options-pclzip_cb_pre_extractfunction
+// https://code.spip.net/@callback_deballe_fichier
+
+function callback_deballe_fichier($p_event, &$p_header) {
+       if (accepte_fichier_upload($p_header['filename'])) {
+               $p_header['filename'] = _TMP_DIR . basename($p_header['filename']);
+
+               return 1;
+       } else {
+               return 0;
+       }
+}