3 /***************************************************************************\
4 * SPIP, Systeme de publication pour l'internet *
6 * Copyright (c) 2001-2019 *
7 * Arnaud Martin, Antoine Pitrou, Philippe Riviere, Emmanuel Saint-James *
9 * Ce programme est un logiciel libre distribue sous licence GNU/GPL. *
10 * Pour plus de details voir le fichier COPYING.txt ou l'aide en ligne. *
11 \***************************************************************************/
14 * Gestion des documents et de leur emplacement sur le serveur
16 * @package SPIP\Core\Documents
19 if (!defined('_ECRIRE_INC_VERSION')) {
24 * Donne le chemin du fichier relatif à `_DIR_IMG`
25 * pour stockage 'tel quel' dans la base de données
29 * @param string $fichier
32 function set_spip_doc($fichier) {
33 if (strpos($fichier, _DIR_IMG
) === 0) {
34 return substr($fichier, strlen(_DIR_IMG
));
37 } // ex: fichier distant
41 * Donne le chemin complet du fichier
45 * @param string $fichier
48 function get_spip_doc($fichier) {
50 if (tester_url_absolue($fichier)) {
54 // gestion d'erreurs, fichier=''
55 if (!strlen($fichier)) {
60 strncmp($fichier, _DIR_IMG
, strlen(_DIR_IMG
)) != 0
70 * Créer un sous-répertoire IMG/$ext/ tel que IMG/pdf
72 * @uses sous_repertoire()
74 * @uses verifier_htaccess()
79 function creer_repertoire_documents($ext) {
80 $rep = sous_repertoire(_DIR_IMG
, $ext);
83 spip_log("creer_repertoire_documents '$rep' interdit");
87 // Cette variable de configuration peut etre posee par un plugin
88 // par exemple acces_restreint
89 if (isset($GLOBALS['meta']["creer_htaccess"]) and $GLOBALS['meta']["creer_htaccess"] == 'oui') {
90 include_spip('inc/acces');
91 verifier_htaccess($rep);
98 * Efface le répertoire de manière récursive !
102 function effacer_repertoire_temporaire($nom) {
103 if ($d = opendir($nom)) {
104 while (($f = readdir($d)) !== false) {
105 if (is_file("$nom/$f")) {
106 spip_unlink("$nom/$f");
108 if ($f <> '.' and $f <> '..'
109 and is_dir("$nom/$f")
111 effacer_repertoire_temporaire("$nom/$f");
122 * Copier un document `$source` un dossier `IMG/$ext/$orig.$ext`
123 * en numérotant éventuellement si un fichier de même nom existe déjà
126 * @param string $orig
127 * @param string $source
128 * @return bool|mixed|string
130 function copier_document($ext, $orig, $source) {
132 $orig = preg_replace(',\.\.+,', '.', $orig); // pas de .. dans le nom du doc
133 $dir = creer_repertoire_documents($ext);
134 $dest = preg_replace("/[^.=\w-]+/", "_",
135 translitteration(preg_replace("/\.([^.]+)$/", "",
136 preg_replace("/<[^>]*>/", '', basename($orig)))));
138 // ne pas accepter de noms de la forme -r90.jpg qui sont reserves
139 // pour les images transformees par rotation (action/documenter)
140 $dest = preg_replace(',-r(90|180|270)$,', '', $dest);
142 // Si le document "source" est deja au bon endroit, ne rien faire
143 if ($source == ($dir . $dest . '.' . $ext)) {
147 // sinon tourner jusqu'a trouver un numero correct
149 while (@file_exists
($newFile = $dir . $dest . ($n++ ?
('-' . $n) : '') . '.' . $ext)) {
153 return deplacer_fichier_upload($source, $newFile);
157 * Trouver le dossier utilisé pour upload un fichier
160 * @uses _DIR_TRANSFERT
162 * @uses sous_repertoire()
164 * @param string $type
165 * @return bool|string
167 function determine_upload($type = '') {
168 if (!function_exists('autoriser')) {
169 include_spip('inc/autoriser');
172 if (!autoriser('chargerftp')
174 ) # on ne le permet pas pour les logos
179 $repertoire = _DIR_TRANSFERT
;
180 if (!@is_dir
($repertoire)) {
181 $repertoire = str_replace(_DIR_TMP
, '', $repertoire);
182 $repertoire = sous_repertoire(_DIR_TMP
, $repertoire);
185 if (!$GLOBALS['visiteur_session']['restreint']) {
188 return sous_repertoire($repertoire, $GLOBALS['visiteur_session']['login']);
193 * Déplacer ou copier un fichier
196 * @uses spip_unlink()
198 * @param string $source
199 * Fichier source à copier
200 * @param string $dest
201 * Fichier de destination
203 * - `true` : on déplace le fichier source vers le fichier de destination
204 * - `false` : valeur par défaut. On ne fait que copier le fichier source vers la destination.
205 * @return bool|mixed|string
207 function deplacer_fichier_upload($source, $dest, $move = false) {
209 if (substr($dest, 0, strlen(_DIR_RACINE
)) == _DIR_RACINE
) {
210 $dest = _DIR_RACINE
. preg_replace(',\.\.+,', '.', substr($dest, strlen(_DIR_RACINE
)));
212 $dest = preg_replace(',\.\.+,', '.', $dest);
216 $ok = @rename
($source, $dest);
218 $ok = @copy
($source, $dest);
221 $ok = @move_uploaded_file
($source, $dest);
224 @chmod
($dest, _SPIP_CHMOD
& ~
0111);
226 $f = @fopen
($dest, 'w');
230 include_spip('inc/flock');
231 raler_fichier($dest);
236 return $ok ?
$dest : false;
243 * Renvoie `false` si pas d'erreur
244 * et `true` s'il n'y a pas de fichier à uploader.
245 * Pour les autres erreurs, on affiche le message d'erreur et on arrête l'action.
247 * @link http://php.net/manual/fr/features.file-upload.errors.php
248 * Explication sur les messages d'erreurs de chargement de fichiers.
252 * @global string $spip_lang_right
253 * @param integer $error
255 * @param bool $return
256 * @return boolean|string
258 function check_upload_error($error, $msg = '', $return = false) {
264 spip_log("Erreur upload $error -- cf. http://php.net/manual/fr/features.file-upload.errors.php");
268 case 4: /* UPLOAD_ERR_NO_FILE */
271 # on peut affiner les differents messages d'erreur
272 case 1: /* UPLOAD_ERR_INI_SIZE */
273 $msg = _T('upload_limit',
274 array('max' => ini_get('upload_max_filesize')));
276 case 2: /* UPLOAD_ERR_FORM_SIZE */
277 $msg = _T('upload_limit',
278 array('max' => ini_get('upload_max_filesize')));
280 case 3: /* UPLOAD_ERR_PARTIAL */
281 $msg = _T('upload_limit',
282 array('max' => ini_get('upload_max_filesize')));
287 $msg = _T('pass_erreur') . ' ' . $error
288 . '<br />' . propre("[->http://php.net/manual/fr/features.file-upload.errors.php]");
293 spip_log("erreur upload $error");
298 if (_request("iframe") == "iframe") {
299 echo "<div class='upload_answer upload_error'>$msg</div>";
303 include_spip('inc/minipres');
305 "<div style='text-align: " . $GLOBALS['spip_lang_right'] . "'><a href='" . rawurldecode($GLOBALS['redirect']) . "'><button type='button'>" . _T('ecrire:bouton_suivant') . "</button></a></div>");