forked from spip/medias
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
506 lines
16 KiB
506 lines
16 KiB
<?php |
|
|
|
/***************************************************************************\ |
|
* SPIP, Systeme de publication pour l'internet * |
|
* * |
|
* Copyright (c) 2001-2020 * |
|
* 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 du formulaire de téléversement de documents |
|
* |
|
* @package SPIP\Medias\Formulaires |
|
*/ |
|
if (!defined('_ECRIRE_INC_VERSION')) { |
|
return; |
|
} |
|
|
|
/** |
|
* Déterminer le mode d'upload si la valeur au chargement du formulaire est "auto" |
|
* |
|
* @param string $mode |
|
* Le mode passé au formulaire |
|
* @param int|string $id_document |
|
* L'identifiant numérique du document à remplacer ou "new" par défaut |
|
* @param string $objet |
|
* Le type d'objet sur lequel ajouter le document |
|
* @return string $mode |
|
* Le mode définitif |
|
*/ |
|
function joindre_determiner_mode($mode, $id_document, $objet) { |
|
if ($mode == 'auto') { |
|
if (intval($id_document)) { |
|
$mode = sql_getfetsel('mode', 'spip_documents', 'id_document=' . intval($id_document)); |
|
} |
|
if (!in_array($mode, array('choix', 'document', 'image'))) { |
|
$mode = 'choix'; |
|
if ($objet |
|
and !in_array(table_objet_sql($objet), explode(',', $GLOBALS['meta']['documents_objets']))) { |
|
$mode = 'image'; |
|
} |
|
} |
|
} |
|
|
|
return $mode; |
|
} |
|
|
|
/** |
|
* Chargement du formulaire |
|
* |
|
* @param int|string $id_document |
|
* L'identidiant numérique du document s'il est à remplacer, sinon "new" |
|
* @param int $id_objet |
|
* L'identifiant numérique de l'objet sur lequel on ajoute le document |
|
* @param string $objet |
|
* Le type de l'objet sur lequel on ajoute le document |
|
* @param string $mode |
|
* Le mode du document (auto,choix,document,image,vignette...), par défaut auto |
|
* @param string $galerie |
|
* Passer optionnellement une galerie jointe au form, plus utilise nativement, |
|
* on prefere la mise a jour apres upload par ajaxReload('documents') |
|
* @param bool|string $proposer_media |
|
* Doit on afficher la médiathèque ? par défaut oui |
|
* Valeurs possibles si string : false,'non','no'. |
|
* @param bool|string $proposer_ftp |
|
* Doit on afficher le ftp ? par défaut oui |
|
* Valeurs possibles si string : false,'non','no'. |
|
* @return array $valeurs |
|
* Les valeurs chargées dans le formulaire |
|
*/ |
|
function formulaires_joindre_document_charger_dist( |
|
$id_document = 'new', |
|
$id_objet = 0, |
|
$objet = '', |
|
$mode = 'auto', |
|
$galerie = false, |
|
$proposer_media = true, |
|
$proposer_ftp = true |
|
) { |
|
$valeurs = array(); |
|
$mode = joindre_determiner_mode($mode, $id_document, $objet); |
|
|
|
|
|
$valeurs['id'] = $id_document; |
|
$valeurs['_mode'] = $mode; |
|
|
|
$valeurs['url'] = 'http://'; |
|
$valeurs['fichier_upload'] = $valeurs['_options_upload_ftp'] = $valeurs['_dir_upload_ftp'] = ''; |
|
$valeurs['joindre_upload'] = $valeurs['joindre_distant'] = |
|
$valeurs['joindre_ftp'] = $valeurs['joindre_mediatheque'] = ''; |
|
|
|
// gérer le focus de la méthode d'upload lorsque le formulaire est envoyé |
|
$valeurs['methode_focus'] = _request('methode_focus'); |
|
|
|
$valeurs['editable'] = ' '; |
|
if (intval($id_document)) { |
|
$valeurs['editable'] = autoriser('modifier', 'document', $id_document) ? ' ' : ''; |
|
} |
|
|
|
$valeurs['proposer_media'] = is_string($proposer_media) ? |
|
(preg_match('/^(false|non|no)$/i', $proposer_media) ? false : true) : $proposer_media; |
|
$valeurs['proposer_ftp'] = is_string($proposer_ftp) ? |
|
(preg_match('/^(false|non|no)$/i', $proposer_ftp) ? false : true) : $proposer_ftp; |
|
|
|
# regarder si un choix d'upload FTP est vraiment possible |
|
if ( |
|
$valeurs['proposer_ftp'] |
|
and test_espace_prive() # ?? |
|
and ($mode != 'image') and ($mode != 'vignette') # si c'est pour un document |
|
//AND !$vignette_de_doc |
|
// pas pour une vignette (NB: la ligne precedente suffit, mais si on la supprime il faut conserver ce test-ci) |
|
and $GLOBALS['flag_upload'] |
|
) { |
|
include_spip('inc/documents'); |
|
if ($dir = determine_upload('documents')) { |
|
// quels sont les docs accessibles en ftp ? |
|
$valeurs['_options_upload_ftp'] = joindre_options_upload_ftp($dir, $mode); |
|
// s'il n'y en a pas, on affiche un message d'aide |
|
// en mode document, mais pas en mode image |
|
if ($valeurs['_options_upload_ftp'] or ($mode == 'document' or $mode == 'choix')) { |
|
$valeurs['_dir_upload_ftp'] = '<b>' . joli_repertoire($dir) . '</b>'; |
|
} |
|
} |
|
} |
|
// On ne propose le FTP que si on a des choses a afficher |
|
$valeurs['proposer_ftp'] = ($valeurs['_options_upload_ftp'] or $valeurs['_dir_upload_ftp']); |
|
|
|
if ($galerie) { |
|
# passer optionnellement une galerie jointe au form |
|
# plus utilise nativement, on prefere la mise a jour |
|
# apres upload par ajaxReload('documents') |
|
$valeurs['_galerie'] = $galerie; |
|
} |
|
if ($objet and $id_objet) { |
|
$valeurs['id_objet'] = $id_objet; |
|
$valeurs['objet'] = $objet; |
|
$valeurs['refdoc_joindre'] = ''; |
|
if ($valeurs['editable']) { |
|
include_spip('inc/autoriser'); |
|
$valeurs['editable'] = autoriser('joindredocument', $objet, $id_objet) ? ' ' : ''; |
|
} |
|
} |
|
|
|
return $valeurs; |
|
} |
|
|
|
/** |
|
* Vérification du formulaire |
|
* |
|
* @param int|string $id_document |
|
* L'identidiant numérique du document s'il est à remplacer, sinon "new" |
|
* @param int $id_objet |
|
* L'identifiant numérique de l'objet sur lequel on ajoute le document |
|
* @param string $objet |
|
* Le type de l'objet sur lequel on ajoute le document |
|
* @param string $mode |
|
* Le mode du document (auto,choix,document,image,vignette...), par défaut auto |
|
* @param string $galerie |
|
* Passer optionnellement une galerie jointe au form, plus utilise nativement, |
|
* on prefere la mise a jour apres upload par ajaxReload('documents') |
|
* @param bool|string $proposer_media |
|
* Doit on afficher la médiathèque ? par défaut oui |
|
* Valeurs possibles si string : false,'non','no'. |
|
* @param bool|string $proposer_ftp |
|
* Doit on afficher le ftp ? par défaut oui |
|
* Valeurs possibles si string : false,'non','no'. |
|
* @return array $erreurs |
|
* Les erreurs éventuelles dans un tableau |
|
*/ |
|
function formulaires_joindre_document_verifier_dist( |
|
$id_document = 'new', |
|
$id_objet = 0, |
|
$objet = '', |
|
$mode = 'auto', |
|
$galerie = false, |
|
$proposer_media = true, |
|
$proposer_ftp = true |
|
) { |
|
include_spip('inc/joindre_document'); |
|
|
|
$erreurs = array(); |
|
// on joint un document deja dans le site |
|
if (_request('joindre_mediatheque')) { |
|
$refdoc_joindre = intval(preg_replace(',^(doc|document|img),', '', _request('refdoc_joindre'))); |
|
if (!sql_getfetsel('id_document', 'spip_documents', 'id_document=' . intval($refdoc_joindre))) { |
|
$erreurs['message_erreur'] = _T('medias:erreur_aucun_document'); |
|
} |
|
} // sinon c'est un upload |
|
else { |
|
$files = joindre_trouver_fichier_envoye(); |
|
if (is_string($files)) { |
|
$erreurs['message_erreur'] = $files; |
|
} elseif (is_array($files)) { |
|
// erreur si on a pas trouve de fichier |
|
if (!count($files)) { |
|
$erreurs['message_erreur'] = _T('medias:erreur_aucun_fichier'); |
|
} else { |
|
// regarder si on a eu une erreur sur l'upload d'un fichier |
|
foreach ($files as $file) { |
|
if (isset($file['error']) |
|
and $test = joindre_upload_error($file['error']) |
|
) { |
|
if (is_string($test)) { |
|
$erreurs['message_erreur'] = $test; |
|
} else { |
|
$erreurs['message_erreur'] = _T('medias:erreur_aucun_fichier'); |
|
} |
|
} |
|
} |
|
|
|
// si ce n'est pas deja un post de zip confirme |
|
// regarder si il faut lister le contenu du zip et le presenter |
|
if (!count($erreurs) |
|
and !_request('joindre_zip') |
|
and $contenu_zip = joindre_verifier_zip($files) |
|
) { |
|
list($fichiers, $erreurs, $tmp_zip) = $contenu_zip; |
|
if ($fichiers) { |
|
// on passe le md5 du fichier uniquement, on le retrouvera dans zip_to_clean de la session |
|
$token_zip = md5($tmp_zip); |
|
$erreurs['message_erreur'] = ''; |
|
$erreurs['lister_contenu_archive'] = recuperer_fond( |
|
'formulaires/inc-lister_archive_jointe', |
|
array( |
|
'chemin_zip' => $token_zip, |
|
'liste_fichiers_zip' => $fichiers, |
|
'erreurs_fichier_zip' => $erreurs |
|
) |
|
); |
|
} else { |
|
$erreurs['message_erreur'] = _T('medias:erreur_aucun_fichier'); |
|
} |
|
} |
|
} |
|
} |
|
|
|
if (count($erreurs) and defined('_TMP_DIR')) { |
|
effacer_repertoire_temporaire(_TMP_DIR); |
|
} |
|
} |
|
|
|
return $erreurs; |
|
} |
|
|
|
/** |
|
* Traitement du formulaire |
|
* |
|
* @param int|string $id_document |
|
* L'identidiant numérique du document s'il est à remplacer, sinon "new" |
|
* @param int $id_objet |
|
* L'identifiant numérique de l'objet sur lequel on ajoute le document |
|
* @param string $objet |
|
* Le type de l'objet sur lequel on ajoute le document |
|
* @param string $mode |
|
* Le mode du document (auto,choix,document,image,vignette...), par défaut auto |
|
* @param string $galerie |
|
* Passer optionnellement une galerie jointe au form, plus utilise nativement, |
|
* on prefere la mise a jour apres upload par ajaxReload('documents') |
|
* @param bool|string $proposer_media |
|
* Doit on afficher la médiathèque ? par défaut oui |
|
* Valeurs possibles si string : false,'non','no'. |
|
* @param bool|string $proposer_ftp |
|
* Doit on afficher le ftp ? par défaut oui |
|
* Valeurs possibles si string : false,'non','no'. |
|
* @return array $res |
|
* Le tableau renvoyé par les CVT avec le message et editable |
|
*/ |
|
function formulaires_joindre_document_traiter_dist( |
|
$id_document = 'new', |
|
$id_objet = 0, |
|
$objet = '', |
|
$mode = 'auto', |
|
$galerie = false, |
|
$proposer_media = true, |
|
$proposer_ftp = true |
|
) { |
|
$res = array('editable' => true); |
|
$ancre = ''; |
|
// on joint un document deja dans le site |
|
if (_request('joindre_mediatheque')) { |
|
$sel = array(); |
|
$refdoc_joindre = _request('refdoc_joindre'); |
|
$refdoc_joindre = strtr($refdoc_joindre, ';,', ' '); |
|
$refdoc_joindre = preg_replace(',\b(doc|document|img),', '', $refdoc_joindre); |
|
// expliciter les intervales xxx-yyy |
|
while (preg_match(",\b(\d+)-(\d+)\b,", $refdoc_joindre, $m)) { |
|
$refdoc_joindre = str_replace($m[0], implode(' ', range($m[1], $m[2])), $refdoc_joindre); |
|
} |
|
$refdoc_joindre = explode(' ', $refdoc_joindre); |
|
include_spip('action/editer_document'); |
|
foreach ($refdoc_joindre as $j) { |
|
if ($j = intval(preg_replace(',^(doc|document|img),', '', $j))) { |
|
// lier le parent en plus |
|
$champs = array('ajout_parents' => array("$objet|$id_objet")); |
|
document_modifier($j, $champs); |
|
if (!$ancre) { |
|
$ancre = $j; |
|
} |
|
$sel[] = $j; |
|
$res['message_ok'] = _T('medias:document_attache_succes'); |
|
} |
|
} |
|
if ($sel) { |
|
$res['message_ok'] = singulier_ou_pluriel( |
|
count($sel), |
|
'medias:document_attache_succes', |
|
'medias:nb_documents_attache_succes' |
|
); |
|
} |
|
set_request('refdoc_joindre', ''); // vider la saisie |
|
} // sinon c'est un upload |
|
else { |
|
$ajouter_documents = charger_fonction('ajouter_documents', 'action'); |
|
|
|
$mode = joindre_determiner_mode($mode, $id_document, $objet); |
|
include_spip('inc/joindre_document'); |
|
$files = joindre_trouver_fichier_envoye(); |
|
|
|
$nouveaux_doc = $ajouter_documents($id_document, $files, $objet, $id_objet, $mode); |
|
|
|
if (defined('_TMP_ZIP')) { |
|
unlink(_TMP_ZIP); |
|
} |
|
if (defined('_TMP_DIR')) { |
|
effacer_repertoire_temporaire(_TMP_DIR); |
|
} |
|
|
|
// checker les erreurs eventuelles |
|
$messages_erreur = array(); |
|
$sel = array(); |
|
foreach ($nouveaux_doc as $doc) { |
|
if (!is_numeric($doc)) { |
|
$messages_erreur[] = $doc; |
|
} // cas qui devrait etre traite en amont |
|
elseif (!$doc) { |
|
$messages_erreur[] = _T('medias:erreur_insertion_document_base', array('fichier' => '<em>???</em>')); |
|
} else { |
|
if (!$ancre) { |
|
$ancre = $doc; |
|
} |
|
$sel[] = $doc; |
|
} |
|
} |
|
if (count($messages_erreur)) { |
|
$res['message_erreur'] = implode('<br />', $messages_erreur); |
|
} |
|
if ($sel) { |
|
$res['message_ok'] = singulier_ou_pluriel( |
|
count($sel), |
|
'medias:document_installe_succes', |
|
'medias:nb_documents_installe_succes' |
|
); |
|
} |
|
if ($ancre) { |
|
$res['redirect'] = "#doc$ancre"; |
|
} |
|
} |
|
if (count($sel) or isset($res['message_ok'])) { |
|
$callback = ''; |
|
if ($ancre) { |
|
$callback .= "jQuery('#doc$ancre a.editbox').eq(0).focus();"; |
|
} |
|
if (count($sel)) { |
|
// passer les ids document selectionnes aux pipelines |
|
$res['ids'] = $sel; |
|
|
|
$sel = '#doc' . implode(',#doc', $sel); |
|
$callback .= "jQuery('$sel').animateAppend();"; |
|
} |
|
$js = "if (window.jQuery) jQuery(function(){ajaxReload('documents',{callback:function(){ $callback }});});"; |
|
$js = "<script type='text/javascript'>$js</script>"; |
|
if (isset($res['message_erreur'])) { |
|
$res['message_erreur'] .= $js; |
|
} else { |
|
$res['message_ok'] .= $js; |
|
} |
|
} |
|
|
|
return $res; |
|
} |
|
|
|
/** |
|
* Retourner le contenu du select HTML d'utilisation de fichiers envoyes par le serveur |
|
* |
|
* @param string $dir |
|
* Le répertoire de recherche des documents |
|
* @param string $mode |
|
* Le mode d'ajout de document |
|
* @return string $texte |
|
* Le contenu HTML du selecteur de documents |
|
*/ |
|
function joindre_options_upload_ftp($dir, $mode = 'document') { |
|
$fichiers = preg_files($dir); |
|
$exts = $dirs = $texte_upload = array(); |
|
|
|
// en mode "charger une image", ne proposer que les inclus |
|
$inclus = ($mode == 'image' or $mode == 'vignette') |
|
? " AND inclus='image'" |
|
: ''; |
|
|
|
foreach ($fichiers as $f) { |
|
$f = preg_replace(",^$dir,", '', $f); |
|
if (preg_match(',\.([^.]+)$,', $f, $match)) { |
|
$ext = strtolower($match[1]); |
|
if (!isset($exts[$ext])) { |
|
include_spip('action/ajouter_documents'); |
|
$ext = corriger_extension($ext); |
|
if (sql_fetsel('extension', 'spip_types_documents', $a = "extension='$ext'" . $inclus)) { |
|
$exts[$ext] = 'oui'; |
|
} else { |
|
$exts[$ext] = 'non'; |
|
} |
|
} |
|
|
|
$k = 2 * substr_count($f, '/'); |
|
$n = strrpos($f, '/'); |
|
if ($n === false) { |
|
$lefichier = $f; |
|
} else { |
|
$lefichier = substr($f, $n + 1, strlen($f)); |
|
$ledossier = substr($f, 0, $n); |
|
if (!in_array($ledossier, $dirs)) { |
|
$texte_upload[] = "\n<option value=\"$ledossier\">" |
|
. str_repeat(' ', $k) |
|
. _T('medias:tout_dossier_upload', array('upload' => $ledossier)) |
|
. '</option>'; |
|
$dirs[] = $ledossier; |
|
} |
|
} |
|
|
|
if ($exts[$ext] == 'oui') { |
|
$texte_upload[] = "\n<option value=\"$f\">" |
|
. str_repeat(' ', $k + 2) |
|
. $lefichier |
|
. '</option>'; |
|
} |
|
} |
|
} |
|
|
|
$texte = join('', $texte_upload); |
|
if (count($texte_upload) > 1) { |
|
$texte = "\n<option value=\"/\" style='font-weight: bold;'>" |
|
. _T('medias:info_installer_tous_documents') |
|
. '</option>' . $texte; |
|
} |
|
|
|
return $texte; |
|
} |
|
|
|
|
|
/** |
|
* Lister les fichiers contenus dans un zip |
|
* |
|
* @param array $files |
|
* La liste des fichiers |
|
* @return string $res |
|
* La liste HTML des fichiers <li>...</li> |
|
*/ |
|
function joindre_liste_contenu_tailles_archive($files) { |
|
include_spip('inc/charsets'); # pour le nom de fichier |
|
|
|
$res = ''; |
|
if (is_array($files)) { |
|
foreach ($files as $nom => $file) { |
|
$nom = translitteration($nom); |
|
$date = date_interface(date('Y-m-d H:i:s', $file['mtime'])); |
|
$taille = taille_en_octets($file['size']); |
|
$res .= '<li title="' . attribut_html($nom) . "\"><b>$nom</b> – $taille<br /> $date</li>\n"; |
|
} |
|
} |
|
|
|
return $res; |
|
} |
|
|
|
/** |
|
* Lister les erreurs dans une archive jointe |
|
* Utilisé formulaires/inc-lister_archive_jointe.html |
|
* |
|
* @param array $erreurs |
|
* La liste des erreurs |
|
* @return string $res |
|
* Le code HTML des erreurs |
|
*/ |
|
function joindre_liste_erreurs_to_li($erreurs) { |
|
if (count($erreurs) == 1) { |
|
return '<p>' . reset($erreurs) . '</p>'; |
|
} |
|
|
|
$res = implode('</li><li>', $erreurs); |
|
if (strlen($res)) { |
|
$res = "<li>$res</li></ul>"; |
|
} |
|
if (count($erreurs) > 4) { |
|
$res = "<p style='cursor:pointer;' onclick='jQuery(this).siblings(\"ul\").toggle();return false;'>" . _T( |
|
'medias:erreurs_voir', |
|
array('nb' => count($erreurs)) |
|
) . '</p><ul class="spip none-js">' . $res . '</ul>'; |
|
} else { |
|
$res = "<ul class=\"spip\">$res</ul>"; |
|
} |
|
|
|
return $res; |
|
}
|
|
|