/**
 * 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;
        } 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)) {
            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();
}
/**
 * Ajouter un document (au format $_FILES)
 *
 * @param int $id_document
 *   Document à remplacer, ou pour une vignette, l'id_document de maman
 *   0 ou 'new' pour une insertion
 * @param array $file
 *   Propriétes au format $_FILE étendu :
 *
 *   - string tmp_name : source sur le serveur
 *   - string name : nom du fichier envoye
 *   - bool titrer : donner ou non un titre a partir du nom du fichier
 *   - bool distant : pour utiliser une source distante sur internet
 *   - string mode : vignette|image|documents|choix
 * @param string $objet
 *   Objet auquel associer le document
 * @param int $id_objet
 *   id_objet
 * @param string $mode
 *   Mode par défaut si pas precisé pour le document
 * @return array|bool|int|mixed|string|unknown
 *
 *   - int : l'id_document ajouté (opération réussie)
 *   - string : une erreur s'est produit, la chaine est le message d'erreur
 *
 */
function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet, $mode)
{
    $source = $file['tmp_name'];
    $nom_envoye = $file['name'];
    // passer en minuscules le nom du fichier, pour eviter les collisions
    // si le file system fait la difference entre les deux il ne detectera
    // pas que Toto.pdf et toto.pdf
    // et on aura une collision en cas de changement de file system
    $file['name'] = strtolower(translitteration($file['name']));
    // Pouvoir definir dans mes_options.php que l'on veut titrer tous les documents par d?faut
    if (!defined('_TITRER_DOCUMENTS')) {
        define('_TITRER_DOCUMENTS', false);
    }
    $titrer = isset($file['titrer']) ? $file['titrer'] : _TITRER_DOCUMENTS;
    $mode = (isset($file['mode']) and $file['mode']) ? $file['mode'] : $mode;
    include_spip('inc/modifier');
    if (isset($file['distant']) and $file['distant'] and !in_array($mode, array('choix', 'auto', 'image', 'document'))) {
        spip_log("document distant {$source} accepte sans verification, mode={$mode}", "medias" . _LOG_INFO_IMPORTANTE);
        include_spip('inc/distant');
        $file['tmp_name'] = _DIR_RACINE . copie_locale($source);
        $source = $file['tmp_name'];
        unset($file['distant']);
    }
    // Documents distants : pas trop de verifications bloquantes, mais un test
    // via une requete HEAD pour savoir si la ressource existe (non 404), si le
    // content-type est connu, et si possible recuperer la taille, voire plus.
    if (isset($file['distant']) and $file['distant']) {
        if (!tester_url_absolue($source)) {
            return _T('medias:erreur_chemin_distant', array('nom' => $source));
        }
        include_spip('inc/distant');
        if (is_array($a = renseigner_source_distante($source))) {
            $champs = $a;
            # NB: dans les bonnes conditions (fichier autorise et pas trop gros)
            # $a['fichier'] est une copie locale du fichier
            $infos = renseigner_taille_dimension_image($champs['fichier'], $champs['extension'], true);
            // on ignore erreur eventuelle sur $infos car on est distant, ca ne marche pas forcement
            if (is_array($infos)) {
                $champs = array_merge($champs, $infos);
            }
            unset($champs['type_image']);
        } else {
            spip_log("Echec du lien vers le document {$source}, abandon");
            return $a;
            // message d'erreur
        }
    } else {
        // pas distant
        $champs = array('distant' => 'non');
        $type_image = '';
        // au pire
        $champs['titre'] = '';
        if ($titrer) {
            $titre = substr($nom_envoye, 0, strrpos($nom_envoye, "."));
            // Enlever l'extension du nom du fichier
            $titre = preg_replace(',[[:punct:][:space:]]+,u', ' ', $titre);
            $champs['titre'] = preg_replace(',\\.([^.]+)$,', '', $titre);
        }
        if (!is_array($fichier = fixer_fichier_upload($file, $mode))) {
            return is_string($fichier) ? $fichier : _T("medias:erreur_upload_type_interdit", array('nom' => $file['name']));
        }
        $champs['inclus'] = $fichier['inclus'];
        $champs['extension'] = $fichier['extension'];
        $champs['fichier'] = $fichier['fichier'];
        /**
         * Récupère les informations du fichier
         * -* largeur
         * -* hauteur
         * -* type_image
         * -* taille
         * -* ses metadonnées si une fonction de metadatas/ est présente
         */
        $infos = renseigner_taille_dimension_image($champs['fichier'], $champs['extension']);
        if (is_string($infos)) {
            return $infos;
        }
        // c'est un message d'erreur !
        $champs = array_merge($champs, $infos);
        // Si mode == 'choix', fixer le mode image/document
        if (in_array($mode, array('choix', 'auto'))) {
            $choisir_mode_document = charger_fonction('choisir_mode_document', 'inc');
            $mode = $choisir_mode_document($champs, $champs['inclus'] == 'image', $objet);
        }
        $champs['mode'] = $mode;
        if (($test = verifier_taille_document_acceptable($champs)) !== true) {
            spip_unlink($champs['fichier']);
            return $test;
            // erreur sur les dimensions du fichier
        }
        unset($champs['type_image']);
        unset($champs['inclus']);
        $champs['fichier'] = set_spip_doc($champs['fichier']);
    }
    // si le media est pas renseigne, le faire, en fonction de l'extension
    if (!isset($champs['media'])) {
        $champs['media'] = sql_getfetsel('media_defaut', 'spip_types_documents', 'extension=' . sql_quote($champs['extension']));
    }
    // lier le parent si necessaire
    if ($id_objet = intval($id_objet) and $objet) {
        $champs['parents'][] = "{$objet}|{$id_objet}";
    }
    // "mettre a jour un document" si on lui
    // passe un id_document
    if ($id_document = intval($id_document)) {
        unset($champs['titre']);
        // garder le titre d'origine
        unset($champs['date']);
        // garder la date d'origine
        unset($champs['descriptif']);
        // garder la desc d'origine
        // unset($a['distant']); # on peut remplacer un doc statique par un doc distant
        // unset($a['mode']); # on peut remplacer une image par un document ?
    }
    include_spip('action/editer_document');
    // Installer le document dans la base
    if (!$id_document) {
        if ($id_document = document_inserer()) {
            spip_log("ajout du document " . $file['tmp_name'] . " " . $file['name'] . "  (M '{$mode}' T '{$objet}' L '{$id_objet}' D '{$id_document}')", 'medias');
        } else {
            spip_log("Echec insert_document() du document " . $file['tmp_name'] . " " . $file['name'] . "  (M '{$mode}' T '{$objet}' L '{$id_objet}' D '{$id_document}')", 'medias' . _LOG_ERREUR);
        }
    }
    if (!$id_document) {
        return _T('medias:erreur_insertion_document_base', array('fichier' => "<em>" . $file['name'] . "</em>"));
    }
    document_modifier($id_document, $champs);
    // permettre aux plugins de faire des modifs a l'ajout initial
    // ex EXIF qui tourne les images si necessaire
    // Ce plugin ferait quand même mieux de se placer dans metadata/jpg.php
    pipeline('post_edition', array('args' => array('table' => 'spip_documents', 'table_objet' => 'documents', 'spip_table_objet' => 'spip_documents', 'type' => 'document', 'id_objet' => $id_document, 'champs' => array_keys($champs), 'serveur' => '', 'action' => 'ajouter_document', 'operation' => 'ajouter_document'), 'data' => $champs));
    return $id_document;
}