/**
 * 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;
}
Example #2
0
function insert_document()
{
    return document_inserer();
}