Newer
Older

cedric@yterium.com
a validé
<?php
/***************************************************************************\
* SPIP, Systeme de publication pour l'internet *
* *

cedric@yterium.com
a validé
* 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. *
\***************************************************************************/
/**
* Gestion de l'action ajouter_documents
*
* @package SPIP\Medias\Action

cedric@yterium.com
a validé
**/

cedric@yterium.com
a validé
if (!defined("_ECRIRE_INC_VERSION")) {
return;
}

cedric@yterium.com
a validé
include_spip('inc/getdocument');
include_spip('inc/documents');

cedric@yterium.com
a validé
include_spip('inc/choisir_mode_document'); // compat core
include_spip('inc/renseigner_document');

cedric@yterium.com
a validé
/**
* Ajouter des documents
*
* @param int $id_document
* Document à remplacer, ou pour une vignette, l'id_document de maman
* @param array $files
* Tableau de taleau de propriété pour chaque document à insérer
* @param string $objet
* Objet auquel associer le document
* @param int $id_objet
* @param string $mode
* Mode par défaut si pas precisé pour le document

cedric@yterium.com
a validé
function action_ajouter_documents_dist($id_document, $files, $objet, $id_objet, $mode) {
$ajouter_un_document = charger_fonction('ajouter_un_document', 'action');

cedric@yterium.com
a validé
$ajoutes = array();

cedric@yterium.com
a validé

cedric@yterium.com
a validé
// on ne peut mettre qu'un seul document a la place d'un autre ou en vignette d'un autre

cedric@yterium.com
a validé
if (intval($id_document)) {

cedric@yterium.com
a validé
$ajoutes[] = $ajouter_un_document($id_document, reset($files), $objet, $id_objet, $mode);

cedric@yterium.com
a validé
} else {
foreach ($files as $file) {

cedric@yterium.com
a validé
$ajoutes[] = $ajouter_un_document('new', $file, $objet, $id_objet, $mode);
}

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
return $ajoutes;

cedric@yterium.com
a validé
}
/**

cedric@yterium.com
a validé
* Ajouter un document (au format $_FILES)

cedric@yterium.com
a validé
*
* Document à remplacer, ou pour une vignette, l'id_document de maman

cedric@yterium.com
a validé
*
* - 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
* Mode par défaut si pas precisé pour le document
*
* - int : l'id_document ajouté (opération réussie)
* - string : une erreur s'est produit, la chaine est le message d'erreur

cedric@yterium.com
a validé
*

cedric@yterium.com
a validé
*/

cedric@yterium.com
a validé
function action_ajouter_un_document_dist($id_document, $file, $objet, $id_objet, $mode) {

marcimat@rezo.net
a validé

cedric@yterium.com
a validé
$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']));

cedric@yterium.com
a validé

cedric@yterium.com
a validé
// Pouvoir definir dans mes_options.php que l'on veut titrer tous les documents par d?faut

cedric@yterium.com
a validé
if (!defined('_TITRER_DOCUMENTS')) {
define('_TITRER_DOCUMENTS', false);
}

cedric@yterium.com
a validé

cedric@yterium.com
a validé
$titrer = isset($file['titrer']) ? $file['titrer'] : _TITRER_DOCUMENTS;

marcimat@rezo.net
a validé
$mode = ((isset($file['mode']) and $file['mode']) ? $file['mode'] : $mode);

cedric@yterium.com
a validé
include_spip('inc/modifier');

marcimat@rezo.net
a validé
if (isset($file['distant']) and $file['distant'] and !in_array($mode, array('choix', 'auto', 'image', 'document'))) {

cedric@yterium.com
a validé
spip_log("document distant $source accepte sans verification, mode=$mode","medias"._LOG_INFO_IMPORTANTE);

cedric@yterium.com
a validé
include_spip('inc/distant');
$file['tmp_name'] = _DIR_RACINE . copie_locale($source);
$source = $file['tmp_name'];
unset($file['distant']);
}

cedric@yterium.com
a validé

cedric@yterium.com
a validé
// 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.

marcimat@rezo.net
a validé
if (isset($file['distant']) and $file['distant']) {

cedric@yterium.com
a validé
if (!tester_url_absolue($source)){
return _T('medias:erreur_chemin_distant', array('nom' => $source));
}

cedric@yterium.com
a validé
include_spip('inc/distant');

cedric@yterium.com
a validé
if (is_array($a = renseigner_source_distante($source))) {

cedric@yterium.com
a validé

cedric@yterium.com
a validé
$champs = $a;

cedric@yterium.com
a validé
# NB: dans les bonnes conditions (fichier autorise et pas trop gros)
# $a['fichier'] est une copie locale du fichier

cedric@yterium.com
a validé
$infos = renseigner_taille_dimension_image($champs['fichier'], $champs['extension'], true);

cedric@yterium.com
a validé
// on ignore erreur eventuelle sur $infos car on est distant, ca ne marche pas forcement

cedric@yterium.com
a validé
if (is_array($infos)) {

cedric@yterium.com
a validé
$champs = array_merge($champs, $infos);
}

cedric@yterium.com
a validé
unset($champs['type_image']);

cedric@yterium.com
a validé
} // on ne doit plus arriver ici, car l'url distante a ete verifiee a la saisie !

cedric@yterium.com
a validé
else {
spip_log("Echec du lien vers le document $source, abandon");

cedric@yterium.com
a validé

cedric@yterium.com
a validé
return $a; // message d'erreur

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
} else { // pas distant

cedric@yterium.com
a validé

cedric@yterium.com
a validé
$champs = array(
'distant' => 'non'
);

cedric@yterium.com
a validé

cedric@yterium.com
a validé
$type_image = ''; // au pire

cedric@yterium.com
a validé
$champs['titre'] = '';

cedric@yterium.com
a validé
if ($titrer) {
$titre = substr($nom_envoye, 0, strrpos($nom_envoye, ".")); // Enlever l'extension du nom du fichier

cedric@yterium.com
a validé
$titre = preg_replace(',[[:punct:][:space:]]+,u', ' ', $titre);

cedric@yterium.com
a validé
$champs['titre'] = preg_replace(',\.([^.]+)$,', '', $titre);

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
if (!is_array($fichier = fixer_fichier_upload($file, $mode))) {
return is_string($fichier) ? $fichier : _T("medias:erreur_upload_type_interdit", array('nom' => $file['name']));
}

cedric@yterium.com
a validé
$champs['inclus'] = $fichier['inclus'];
$champs['extension'] = $fichier['extension'];
$champs['fichier'] = $fichier['fichier'];

cedric@yterium.com
a validé
/**
* Récupère les informations du fichier
* -* largeur
* -* hauteur
* -* type_image
* -* taille
* -* ses metadonnées si une fonction de metadatas/ est présente
*/

cedric@yterium.com
a validé
$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);

cedric@yterium.com
a validé

cedric@yterium.com
a validé
// Si mode == 'choix', fixer le mode image/document

cedric@yterium.com
a validé
if (in_array($mode, array('choix', 'auto'))) {
$choisir_mode_document = charger_fonction('choisir_mode_document', 'inc');

cedric@yterium.com
a validé
$mode = $choisir_mode_document($champs, $champs['inclus'] == 'image', $objet);

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
$champs['mode'] = $mode;

cedric@yterium.com
a validé

cedric@yterium.com
a validé
if (($test = verifier_taille_document_acceptable($champs)) !== true) {

cedric@yterium.com
a validé
spip_unlink($champs['fichier']);

cedric@yterium.com
a validé

cedric@yterium.com
a validé
return $test; // erreur sur les dimensions du fichier

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
unset($champs['type_image']);
unset($champs['inclus']);
$champs['fichier'] = set_spip_doc($champs['fichier']);
}

cedric@yterium.com
a validé
// si le media est pas renseigne, le faire, en fonction de l'extension

cedric@yterium.com
a validé
if (!isset($champs['media'])) {
$champs['media'] = sql_getfetsel('media_defaut', 'spip_types_documents',
'extension=' . sql_quote($champs['extension']));

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé

cedric@yterium.com
a validé
// lier le parent si necessaire

marcimat@rezo.net
a validé
if ($id_objet = intval($id_objet) and $objet) {

cedric@yterium.com
a validé
$champs['parents'][] = "$objet|$id_objet";

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
// "mettre a jour un document" si on lui
// passe un id_document

cedric@yterium.com
a validé
if ($id_document = intval($id_document)) {

cedric@yterium.com
a validé
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 ?

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
include_spip('action/editer_document');

cedric@yterium.com
a validé
// Installer le document dans la base

cedric@yterium.com
a validé
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>"));

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
document_modifier($id_document, $champs);

cedric@yterium.com
a validé
// 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

cedric@yterium.com
a validé
pipeline('post_edition',
array(
'args' => array(

cedric@yterium.com
a validé
'table' => 'spip_documents', // compatibilite
'table_objet' => 'documents',
'spip_table_objet' => 'spip_documents',

cedric@yterium.com
a validé
'type' => 'document',

cedric@yterium.com
a validé
'id_objet' => $id_document,
'champs' => array_keys($champs),
'serveur' => '', // serveur par defaut, on ne sait pas faire mieux pour le moment
'action' => 'ajouter_document',
'operation' => 'ajouter_document', // compat <= v2.0

cedric@yterium.com
a validé
),

cedric@yterium.com
a validé
'data' => $champs

cedric@yterium.com
a validé
)
);

cedric@yterium.com
a validé
return $id_document;

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
/**
* Corrige l'extension du fichier dans quelques cas particuliers

cedric@yterium.com
a validé
*
* @note
* Une extension 'pdf ' passe dans la requête de contrôle
* mysql> SELECT * FROM spip_types_documents WHERE extension="pdf ";

cedric@yterium.com
a validé
*
* @todo
* À passer dans base/typedoc

cedric@yterium.com
a validé
*

cedric@yterium.com
a validé
* @param string $ext
* @return string
*/
function corriger_extension($ext) {
$ext = preg_replace(',[^a-z0-9],i', '', $ext);
switch ($ext) {
case 'htm':

cedric@yterium.com
a validé
$ext = 'html';

cedric@yterium.com
a validé
break;
case 'jpeg':

cedric@yterium.com
a validé
$ext = 'jpg';

cedric@yterium.com
a validé
break;
case 'tiff':

cedric@yterium.com
a validé
$ext = 'tif';

cedric@yterium.com
a validé
break;

cedric@yterium.com
a validé
$ext = 'aiff';
case 'mpeg':

cedric@yterium.com
a validé
$ext = 'mpg';
break;

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé

cedric@yterium.com
a validé
return $ext;
}

cedric@yterium.com
a validé

cedric@yterium.com
a validé
/**
* Vérifie la possibilité d'uploader une extension

cedric@yterium.com
a validé
*
* Vérifie aussi si l'extension est autorisée pour le mode demandé
* si on connait le mode à ce moment là
*
* @param string $source
* Nom du fichier
* @param string $mode
* Mode d'inclusion du fichier, si connu
* @return array|bool|string
*
* - array : extension acceptée (tableau descriptif).
* Avec un index 'autozip' si il faut zipper
* - false ou message d'erreur si l'extension est refusée

cedric@yterium.com
a validé
*/

cedric@yterium.com
a validé
function verifier_upload_autorise($source, $mode = '') {
$infos = array('fichier' => $source);

cedric@yterium.com
a validé
if (preg_match(",\.([a-z0-9]+)(\?.*)?$,i", $source, $match)

marcimat@rezo.net
a validé
and $ext = $match[1]

cedric@yterium.com
a validé
) {
$ext = corriger_extension(strtolower($ext));
if ($res = sql_fetsel("extension,inclus,media_defaut as media", "spip_types_documents",
"extension=" . sql_quote($ext) . " AND upload='oui'")
) {
$infos = array_merge($infos, $res);
}

cedric@yterium.com
a validé
if (!$res) {
if ($res = sql_fetsel("extension,inclus,media_defaut as media", "spip_types_documents",
"extension='zip' AND upload='oui'")
) {
$infos = array_merge($infos, $res);
$res['autozip'] = true;
}
}

marcimat@rezo.net
a validé
if ($mode and $res) {
// verifier en fonction du mode si une fonction est proposee

cedric@yterium.com
a validé
if ($verifier_document_mode = charger_fonction("verifier_document_mode_" . $mode, "inc", true)) {
$check = $verifier_document_mode($infos); // true ou message d'erreur sous forme de chaine

cedric@yterium.com
a validé
if ($check !== true) {

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé

marcimat@rezo.net
a validé
if (!$res or is_string($res)) {

cedric@yterium.com
a validé
spip_log("Upload $source interdit ($res)", _LOG_INFO_IMPORTANTE);

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
/**

cedric@yterium.com
a validé
*
* - le document existe et n'est pas de taille 0 ?

cedric@yterium.com
a validé
* - interdit a l'upload ?
* - quelle extension dans spip_types_documents ?
* - est-ce "inclus" comme une image ?

cedric@yterium.com
a validé
*

cedric@yterium.com
a validé
*
* @param array $file
* Au format $_FILES
* @param string $mode
* Mode d'inclusion du fichier, si connu

cedric@yterium.com
a validé
* @return array
*/

cedric@yterium.com
a validé
function fixer_fichier_upload($file, $mode = '') {

cedric@yterium.com
a validé
* On vérifie que le fichier existe et qu'il contient quelque chose

cedric@yterium.com
a validé
if (is_array($row = verifier_upload_autorise($file['name'], $mode))) {
if (!isset($row['autozip'])) {
$row['fichier'] = copier_document($row['extension'], $file['name'], $file['tmp_name']);
/**
* On vérifie que le fichier a une taille
* si non, on le supprime et on affiche une erreur
*/

cedric@yterium.com
a validé
if ($row['fichier'] && (!$taille = @intval(filesize(get_spip_doc($row['fichier']))))) {
spip_log("Echec copie du fichier " . $file['tmp_name'] . " (taille de fichier indéfinie)");

cedric@yterium.com
a validé
return _T('medias:erreur_copie_fichier', array('nom' => $file['tmp_name']));
} else {

cedric@yterium.com
a validé
}
}
// creer un zip comme demande
// pour encapsuler un fichier dont l'extension n'est pas supportee

cedric@yterium.com
a validé
else {

cedric@yterium.com
a validé

cedric@yterium.com
a validé
if (!$tmp_dir = tempnam(_DIR_TMP, 'tmp_upload')) {

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
spip_unlink($tmp_dir);
@mkdir($tmp_dir);

cedric@yterium.com
a validé
$tmp = $tmp_dir . '/' . translitteration($file['name']);

cedric@yterium.com
a validé
$file['name'] .= '.' . $ext; # conserver l'extension dans le nom de fichier, par exemple toto.js => toto.js.zip
// deplacer le fichier tmp_name dans le dossier tmp
deplacer_fichier_upload($file['tmp_name'], $tmp, true);
include_spip('inc/pclzip');

cedric@yterium.com
a validé
$source = _DIR_TMP . basename($tmp_dir) . '.' . $ext;
$archive = new PclZip($source);
$v_list = $archive->create($tmp,

cedric@yterium.com
a validé
PCLZIP_OPT_REMOVE_PATH, $tmp_dir,
PCLZIP_OPT_ADD_PATH, '');
effacer_repertoire_temporaire($tmp_dir);
if (!$v_list) {
spip_log("Echec creation du zip ");

cedric@yterium.com
a validé

cedric@yterium.com
a validé
$row['fichier'] = copier_document($row['extension'], $file['name'], $source);
/**
* On vérifie que le fichier a une taille
* si non, on le supprime et on affiche une erreur
*/

cedric@yterium.com
a validé
if ($row['fichier'] && (!$taille = @intval(filesize(get_spip_doc($row['fichier']))))) {
spip_log("Echec copie du fichier " . $file['tmp_name'] . " (taille de fichier indéfinie)");

cedric@yterium.com
a validé
return _T('medias:erreur_copie_fichier', array('nom' => $file['tmp_name']));
} else {

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé
} else {
return $row;
} // retourner le message d'erreur

cedric@yterium.com
a validé
}
/**
* Verifier si le fichier respecte les contraintes de tailles

cedric@yterium.com
a validé
*

cedric@yterium.com
a validé
function verifier_taille_document_acceptable(&$infos) {

cedric@yterium.com
a validé
// si ce n'est pas une image
if (!$infos['type_image']) {

marcimat@rezo.net
a validé
if (defined('_DOC_MAX_SIZE') and _DOC_MAX_SIZE > 0 and $infos['taille'] > _DOC_MAX_SIZE * 1024) {

cedric@yterium.com
a validé
return _T('medias:info_doc_max_poids',
array(

marcimat@rezo.net
a validé
'maxi' => taille_en_octets(_DOC_MAX_SIZE * 1024),

cedric@yterium.com
a validé
'actuel' => taille_en_octets($infos['taille'])
)
);
}

cedric@yterium.com
a validé
} // si c'est une image

cedric@yterium.com
a validé
else {

marcimat@rezo.net
a validé
if ((defined('_IMG_MAX_WIDTH') and _IMG_MAX_WIDTH and $infos['largeur'] > _IMG_MAX_WIDTH)
or (defined('_IMG_MAX_HEIGHT') and _IMG_MAX_HEIGHT and $infos['hauteur'] > _IMG_MAX_HEIGHT)

cedric@yterium.com
a validé
) {

marcimat@rezo.net
a validé
$max_width = (defined('_IMG_MAX_WIDTH') and _IMG_MAX_WIDTH) ? _IMG_MAX_WIDTH : '*';
$max_height = (defined('_IMG_MAX_HEIGHT') and _IMG_MAX_HEIGHT) ? _IMG_MAX_HEIGHT : '*';

cedric@yterium.com
a validé
// pas la peine d'embeter le redacteur avec ca si on a active le calcul des miniatures
// on met directement a la taille maxi a la volee

marcimat@rezo.net
a validé
if (isset($GLOBALS['meta']['creer_preview']) and $GLOBALS['meta']['creer_preview'] == 'oui') {

cedric@yterium.com
a validé
include_spip('inc/filtres');
$img = filtrer('image_reduire', $infos['fichier'], $max_width, $max_height);
$img = extraire_attribut($img, 'src');
$img = supprimer_timestamp($img);

marcimat@rezo.net
a validé
if (@file_exists($img) and $img !== $infos['fichier']) {

cedric@yterium.com
a validé
spip_unlink($infos['fichier']);
@rename($img, $infos['fichier']);
$size = @getimagesize($infos['fichier']);
$infos['largeur'] = $size[0];
$infos['hauteur'] = $size[1];
$infos['taille'] = @filesize($infos['fichier']);
}
}

cedric@yterium.com
a validé

marcimat@rezo.net
a validé
if ((defined('_IMG_MAX_WIDTH') and _IMG_MAX_WIDTH and $infos['largeur'] > _IMG_MAX_WIDTH)
or (defined('_IMG_MAX_HEIGHT') and _IMG_MAX_HEIGHT and $infos['hauteur'] > _IMG_MAX_HEIGHT)

cedric@yterium.com
a validé
) {

cedric@yterium.com
a validé
return _T('medias:info_image_max_taille',

cedric@yterium.com
a validé
array(

cedric@yterium.com
a validé
'maxi' =>
_T('info_largeur_vignette',

cedric@yterium.com
a validé
array(
'largeur_vignette' => $max_width,
'hauteur_vignette' => $max_height
)),

cedric@yterium.com
a validé
'actuel' =>
_T('info_largeur_vignette',

cedric@yterium.com
a validé
array(
'largeur_vignette' => $infos['largeur'],
'hauteur_vignette' => $infos['hauteur']
))

cedric@yterium.com
a validé
));
}
}

marcimat@rezo.net
a validé
if (defined('_IMG_MAX_SIZE') and _IMG_MAX_SIZE > 0 and $infos['taille'] > _IMG_MAX_SIZE * 1024) {

cedric@yterium.com
a validé
return _T('medias:info_image_max_poids',
array(

marcimat@rezo.net
a validé
'maxi' => taille_en_octets(_IMG_MAX_SIZE * 1024),

cedric@yterium.com
a validé
'actuel' => taille_en_octets($infos['taille']
)
)
);
}

cedric@yterium.com
a validé
}
// verifier en fonction du mode si une fonction est proposee

cedric@yterium.com
a validé
if ($verifier_document_mode = charger_fonction("verifier_document_mode_" . $infos['mode'], "inc", true)) {

cedric@yterium.com
a validé
}

cedric@yterium.com
a validé

cedric@yterium.com
a validé
return true;