X-Git-Url: http://git.cyclocoop.org/?p=velocampus%2Fweb%2Fwww.git;a=blobdiff_plain;f=www%2Fecrire%2Finc%2Fajouter_documents.php;fp=www%2Fecrire%2Finc%2Fajouter_documents.php;h=33902b0e7ea8a669fa735bdec45b1238af784e31;hp=0000000000000000000000000000000000000000;hb=80b4d3e85f78d402ed2e73f8f5d1bf4c19962eed;hpb=aaf970bf4cdaf76689ecc10609048e18d073820c diff --git a/www/ecrire/inc/ajouter_documents.php b/www/ecrire/inc/ajouter_documents.php new file mode 100644 index 0000000..33902b0 --- /dev/null +++ b/www/ecrire/inc/ajouter_documents.php @@ -0,0 +1,554 @@ + 0 + AND $largeur < _LARGEUR_MODE_IMAGE) + return 'image'; + else + return 'document'; +} + +// +// Ajouter un document (au format $_FILES) +// +# $source, # le fichier sur le serveur (/var/tmp/xyz34) +# $nom_envoye, # son nom chez le client (portequoi.pdf) +# $type_lien, # lie a un article, une breve ou une rubrique ? +# $id_lien, # identifiant de l'article (ou rubrique) lie +# $mode, # 'image' => image en mode image +# # 'vignette' => personnalisee liee a un document + # 'document' => doc ou image en mode document + # 'distant' => lien internet +# $id_document, # pour une vignette, l'id_document de maman +# $actifs # les documents dont il faudra ouvrir la boite de dialogue + +// http://doc.spip.org/@ajouter_un_document +function ajouter_un_document($source, $nom_envoye, $type_lien, $id_lien, $mode, $id_document, &$documents_actifs, $titrer=false) { + + include_spip('inc/modifier'); + +// 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 ($mode == 'distant') { + include_spip('inc/distant'); + if ($a = recuperer_infos_distantes($source)) { + + # NB: dans les bonnes conditions (fichier autorise et pas trop gros) + # $a['fichier'] est une copie locale du fichier + + $type_image = $a['type_image']; + + unset($a['type_image']); + unset($a['body']); + + $a['date'] = date('Y-m-d H:i:s'); + $a['distant'] = 'oui'; + $a['mode'] = 'document'; + $a['fichier'] = set_spip_doc($source); + } + else { + spip_log("Echec du lien vers le document $source, abandon"); + return; + } + } else { // pas distant + + $type_image = ''; // au pire + // tester le type de document : + // - interdit a l'upload ? + // - quelle extension dans spip_types_documents ? + // - est-ce "inclus" comme une image ? + + preg_match(",^(.*)\.([^.]+)$,", $nom_envoye, $match); + @list(,$titre,$ext) = $match; + // securite : pas de . en dehors de celui separant l'extension + // sinon il est possible d'injecter du php dans un toto.php.txt + $nom_envoye = str_replace('.','-',$titre).'.'.$ext; + if ($titrer) { + $titre = preg_replace(',[[:punct:][:space:]]+,u', ' ', $titre); + } else $titre = ''; + $ext = corriger_extension(strtolower($ext)); + + $row = sql_fetsel("inclus", "spip_types_documents", "extension=" . sql_quote($ext) . " AND upload='oui'"); + + if ($row) { + $type_inclus_image = ($row['inclus'] == 'image'); + $fichier = copier_document($ext, $nom_envoye, $source); + } else { + +/* STOCKER LES DOCUMENTS INCONNUS AU FORMAT .ZIP */ + $type_inclus_image = false; + + if (!sql_countsel("spip_types_documents", "extension='zip' AND upload='oui'")) { + spip_log("Extension $ext interdite a l'upload"); + return; + } + + $ext = 'zip'; + if (!$tmp_dir = tempnam(_DIR_TMP, 'tmp_upload')) return; + spip_unlink($tmp_dir); @mkdir($tmp_dir); + $tmp = $tmp_dir.'/'.translitteration($nom_envoye); + $nom_envoye .= '.zip'; # conserver l'extension dans le nom de fichier, par exemple toto.js => toto.js.zip + deplacer_fichier_upload($source, $tmp); + include_spip('inc/pclzip'); + $source = _DIR_TMP . 'archive.zip'; + $archive = new PclZip($source); + $v_list = $archive->create($tmp, + PCLZIP_OPT_REMOVE_PATH, $tmp_dir, + PCLZIP_OPT_ADD_PATH, ''); + effacer_repertoire_temporaire($tmp_dir); + if (!$v_list) { + spip_log("Echec creation du zip "); + return; + } + $fichier = copier_document($ext, $nom_envoye, $source); + spip_unlink($source); + } + + // Prevoir traitement specifique pour videos + // (http://www.getid3.org/ peut-etre + if ($ext == "mov") { + $largeur = 0; + $hauteur = 0; + } else if ($ext == "svg") { + // recuperer les dimensions et supprimer les scripts + list($largeur,$hauteur)= traite_svg($fichier); + } else { // image ? + // Si c'est une image, recuperer sa taille et son type (detecte aussi swf) + $size_image = @getimagesize($fichier); + $largeur = intval($size_image[0]); + $hauteur = intval($size_image[1]); + $type_image = decoder_type_image($size_image[2]); + } + + // Quelques infos sur le fichier + if (!$fichier OR !@file_exists($fichier) + OR !$taille = @intval(filesize($fichier))) { + spip_log ("Echec copie du fichier $fichier"); + return; + } + + // _INTERFACE_DOCUMENTS + // Si mode == 'choix', fixer le mode image/document + if ($mode == 'choix') { + $choisir_mode_document = charger_fonction('choisir_mode_document','inc'); + $mode = $choisir_mode_document($fichier, $type_lien, $type_image, $largeur, $hauteur); + } + + + if (!$type_image) { + if (_DOC_MAX_SIZE > 0 + AND $taille > _DOC_MAX_SIZE*1024) { + spip_unlink ($fichier); + check_upload_error(6, + _T('info_logo_max_poids', + array('maxi' => taille_en_octets(_DOC_MAX_SIZE*1024), + 'actuel' => taille_en_octets($taille)))); + } + if ($mode == 'image') { + spip_log ("le format de $fichier ne convient pas pour une image"); + spip_unlink($fichier); + return; + } + } + else { // image + if (_IMG_MAX_SIZE > 0 + AND $taille > _IMG_MAX_SIZE*1024) { + spip_unlink ($fichier); + check_upload_error(6, + _T('info_logo_max_poids', + array('maxi' => taille_en_octets(_IMG_MAX_SIZE*1024), + 'actuel' => taille_en_octets($taille)))); + } + + if (_IMG_MAX_WIDTH * _IMG_MAX_HEIGHT + AND ($size_image[0] > _IMG_MAX_WIDTH + OR $size_image[1] > _IMG_MAX_HEIGHT)) { + spip_unlink ($fichier); + check_upload_error(6, + _T('info_logo_max_taille', + array( + 'maxi' => + _T('info_largeur_vignette', + array('largeur_vignette' => _IMG_MAX_WIDTH, + 'hauteur_vignette' => _IMG_MAX_HEIGHT)), + 'actuel' => + _T('info_largeur_vignette', + array('largeur_vignette' => $size_image[0], + 'hauteur_vignette' => $size_image[1])) + ))); + } + } + + // Si on veut uploader une vignette, il faut qu'elle ait ete bien lue + if ($mode == 'vignette') { + if (!$type_inclus_image) { + spip_log ("le format de $fichier ne convient pas pour une image"); # SVG + spip_unlink($fichier); + return; + } + + if (!($largeur OR $hauteur)) { + spip_log('erreur upload vignette '.$fichier); + spip_unlink($fichier); + return; + } + } elseif (!in_array($mode, array('distant', 'image', 'document'))) { + if ($type_image AND $type_inclus_image) + $mode = 'image'; + else + $mode = 'document'; + } + $a = array( + 'date' => date('Y-m-d H:i:s'), + 'distant' => 'non', + 'mode' => $mode, + 'titre'=> $titre, + 'largeur' => $largeur, + 'hauteur' => $hauteur, + 'taille' => $taille, + 'extension'=> $ext, + 'fichier' => set_spip_doc($fichier)); + } + + if (($id_document=intval($id_document)) AND $mode!='vignette') { + + // Mise a jour des descripteurs d'un vieux doc + unset($a['titre']); + unset($a['date']); + unset($a['distant']); + unset($a['mode']); + + sql_updateq('spip_documents', $a, "id_document=$id_document"); + $id = $id_document; + + } else { + // Installer le document dans la base + // attention piege semantique : les images s'installent en mode 'vignette' + // note : la fonction peut "mettre a jour un document" si on lui + // passe "mode=document" et "id_document=.." (pas utilise) + + // Envoyer aux plugins + $a = pipeline('pre_insertion', + array( + 'args' => array( + 'table' => 'spip_documents', + ), + 'data' => $a + ) + ); + + $id = sql_insertq("spip_documents", $a); + + pipeline('post_insertion', + array( + 'args' => array( + 'table' => 'spip_documents', + 'id_objet' => $id_document + ), + 'data' => $a + ) + ); + + spip_log ("ajout du document $source $nom_envoye (M '$mode' T '$type_lien' L '$id_lien' D '$id')"); + + if ($id_lien AND $id + AND preg_match('/^[a-z0-9_]+$/i', $type_lien) # securite + ) { + sql_insertq('spip_documents_liens', + array('id_document' => $id, + 'id_objet' => $id_lien, + 'objet' => $type_lien)); + } else spip_log("Pb d'insertion $id_lien $type_lien"); + + if ($id_document) { + sql_updateq("spip_documents", array("id_vignette" => $id, "mode" => 'document'), "id_document=$id_document"); + + } else $id_document = $id; + + + // Appliquer l'exif orientation + // http://trac.rezo.net/trac/spip/ticket/1494 + define('_TOURNER_SELON_EXIF', false); # par defaut non, risque memoire + if (defined('_TOURNER_SELON_EXIF') + AND _TOURNER_SELON_EXIF + AND $mode == 'document' + AND $a['distant'] == 'non' + AND $a['extension'] == 'jpg') { + include_spip('action/tourner'); + tourner_selon_exif_orientation($id_document, $fichier); + } + + } + // pour que le retour vers ecrire/ active le bon doc. + $documents_actifs[$fichier] = $id_document; + // Notifications, gestion des revisions, reindexation... + pipeline('post_edition', + array( + 'args' => array( + 'operation' => 'ajouter_document', + 'table' => 'spip_documents', + 'id_objet' => $id, + 'type_image' => $type_image + ), + 'data' => null + ) + ); + + return $id ; +} + +// http://doc.spip.org/@verifier_compactes +function verifier_compactes($zip) { + if (!$list = $zip->listContent()) return array(); + // si pas possible de decompacter: installer comme fichier zip joint + // Verifier si le contenu peut etre uploade (verif extension) + $aff_fichiers = array(); + foreach ($list as $file) { + if (accepte_fichier_upload($f = $file['stored_filename'])) + $aff_fichiers[$f] = $file; + else spip_log("chargement de $f interdit"); + } + ksort($aff_fichiers); + return $aff_fichiers; +} + +// +// Convertit le type numerique retourne par getimagesize() en extension fichier +// + +// http://doc.spip.org/@decoder_type_image +function decoder_type_image($type, $strict = false) { + switch ($type) { + case 1: + return "gif"; + case 2: + return "jpg"; + case 3: + return "png"; + case 4: + return $strict ? "" : "swf"; + case 5: + return "psd"; + case 6: + return "bmp"; + case 7: + case 8: + return "tif"; + default: + return ""; + } +} + + +// http://doc.spip.org/@traite_svg +function traite_svg($file) +{ + $texte = spip_file_get_contents($file); + + // Securite si pas admin : virer les scripts et les references externes + // sauf si on est en mode javascript 'ok' (1), cf. inc_version + if ($GLOBALS['filtrer_javascript'] < 1 + AND !autoriser('televerser','script')) { + include_spip('inc/texte'); + $new = trim(safehtml($texte)); + // petit bug safehtml + if (substr($new,0,2) == ']>') $new = ltrim(substr($new,2)); + if ($new != $texte) ecrire_fichier($file, $texte = $new); + } + + $width = $height = 150; + if (preg_match(',]+>,', $texte, $s)) { + $s = $s[0]; + if (preg_match(',\WviewBox\s*=\s*.\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+),i', $s, $r)){ + $width = $r[3]; + $height = $r[4]; + } else { + // si la taille est en centimetre, estimer le pixel a 1/64 de cm + if (preg_match(',\Wwidth\s*=\s*.(\d+)([^"\']*),i', $s, $r)){ + if ($r[2] != '%') { + $width = $r[1]; + if ($r[2] == 'cm') $width <<=6; + } + } + if (preg_match(',\Wheight\s*=\s*.(\d+)([^"\']*),i', $s, $r)){ + if ($r[2] != '%') { + $height = $r[1]; + if ($r[2] == 'cm') $height <<=6; + } + } + } + } + return array($width, $height); +} + +// +// Corrige l'extension du fichier dans quelques cas particuliers +// (a passer dans ecrire/base/typedoc) +// A noter : une extension 'pdf ' passe dans la requete de controle +// mysql> SELECT * FROM spip_types_documents WHERE extension="pdf "; +// http://doc.spip.org/@corriger_extension +function corriger_extension($ext) { + $ext = preg_replace(',[^a-z0-9],i', '', $ext); + switch ($ext) { + case 'htm': + return 'html'; + case 'jpeg': + return 'jpg'; + case 'tiff': + return 'tif'; + case 'mpeg': + return 'mpg'; + default: + return $ext; + } +} + +// 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 +// http://doc.spip.org/@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); +} + +// Afficher un formulaire de choix: decompacter et/ou garder tel quel +// et reconstruire un generer_action_auteur. +// Passer ca en squelette un de ces jours. + +// http://doc.spip.org/@liste_archive_jointe +function liste_archive_jointe($valables, $zip, $type, $id, $mode, $id_document, $hash, $redirect, $iframe_redirect) +{ + include_spip('inc/layer'); + + $arg = (intval($id) .'/' .intval($id_document) . "/$mode/$type"); + + $texte = "
+ + + + + +" . + "" . + "
". + "". + "" . + "
    " . + liste_archive_taille($valables) . + "
" + + . debut_block_depliable(false,'options_deballe_zip') + . "". + "" . + "
" + . "". + "
" + . fin_block() + + + . "
"; + + $texte = "

" . + _T('upload_fichier_zip_texte') . + "

" . + _T('upload_fichier_zip_texte2') . + "

" . + generer_form_action('joindre', $texte,' method="post"'); + + if(_request("iframe")=="iframe") { + return "

build form $iframe_redirect

" . + "
" . + $texte . + "
"; + } else { return minipres(_T('upload_fichier_zip'), $texte); } +} + +// http://doc.spip.org/@liste_archive_taille +function liste_archive_taille($files) { + $res = ''; + foreach ($files as $nom => $file) { + $date = date_interface(date("Y-m-d H:i:s", $file['mtime'])); + + $taille = taille_en_octets($file['size']); + $res .= "
  • $nom – $taille
      $date
  • \n"; + } + return $res; +} +?>