Newer
Older
/**
* SPIP, Système de publication pour l'internet
*
* Copyright © avec tendresse depuis 2001
* Arnaud Martin, Antoine Pitrou, Philippe Rivière, Emmanuel Saint-James
*
* Ce programme est un logiciel libre distribué sous licence GNU/GPL.
*/
/**
* Gestion des documents et de leur emplacement sur le serveur
cerdic
a validé
*
cerdic
a validé
if (!defined('_ECRIRE_INC_VERSION')) {
return;
}
* Donne le chemin du fichier relatif à `_DIR_IMG`
* pour stockage 'tel quel' dans la base de données
cerdic
a validé
*
* @param string $fichier
* @return string
*/
marcimat
a validé
function set_spip_doc(?string $fichier): string {
if ($fichier && str_starts_with($fichier, (string) _DIR_IMG)) {
return substr($fichier, strlen((string) _DIR_IMG));
cerdic
a validé
} else {
marcimat
a validé
// ex: fichier distant
return $fichier ?? '';
cerdic
a validé
*
*
* @param string $fichier
* @return bool|string
*/
marcimat
a validé
function get_spip_doc(?string $fichier) {
RastaPopoulos
a validé
$fichier_demande = $fichier;
marcimat
a validé
if ($fichier === null) {
return false;
}
// fichier distant
cerdic
a validé
if (tester_url_absolue($fichier)) {
return $fichier;
cerdic
a validé
}
// gestion d'erreurs, fichier=''
cerdic
a validé
if (!strlen($fichier)) {
return false;
cerdic
a validé
}
if (!str_starts_with($fichier, (string) _DIR_IMG)) {
marcimat
a validé
$fichier = _DIR_IMG . $fichier;
}
RastaPopoulos
a validé
$fichier = pipeline('get_spip_doc', ['args' => ['fichier' => $fichier_demande], 'data' => $fichier]);
// fichier normal
cerdic
a validé
*
* @uses sous_repertoire()
* @uses _DIR_IMG
* @uses verifier_htaccess()
cerdic
a validé
*
* @return string
*/
function creer_repertoire_documents($ext) {
$rep = sous_repertoire(_DIR_IMG, $ext);
spip_logger()->info("creer_repertoire_documents '$rep' interdit");
// Cette variable de configuration peut etre posee par un plugin
// par exemple acces_restreint
// sauf pour logo/ utilise pour stocker les logoon et logooff
&& $GLOBALS['meta']['creer_htaccess'] == 'oui'
&& $ext !== 'logo'
include_spip('inc/acces');
verifier_htaccess($rep);
*
* @param string $nom
*/
function effacer_repertoire_temporaire($nom) {
gilles.vincent
a validé
if ($d = opendir($nom)) {
while (($f = readdir($d)) !== false) {
if (is_file("$nom/$f")) {
spip_unlink("$nom/$f");
} else {
if ($f != '.' && $f != '..' && is_dir("$nom/$f")) {
gilles.vincent
a validé
effacer_repertoire_temporaire("$nom/$f");
}
cerdic
a validé
}
}
* Copier un document `$source`
* dans un dossier `IMG/$ext/$orig.$ext` ou `IMG/$subdir/$orig.$ext` si `$subdir` est fourni
* en numérotant éventuellement si un fichier de même nom existe déjà
*
* @param string $ext
* @param string $orig
* @param string $source
* @param string $subdir
function copier_document($ext, $orig, $source, $subdir = null) {
$orig = preg_replace(',\.\.+,', '.', $orig); // pas de .. dans le nom du doc
$dir = creer_repertoire_documents($subdir ?: $ext);
$dest = preg_replace('/<[^>]*>/', '', basename($orig));
$dest = translitteration($dest);
$dest = preg_replace('/[^.=\w-]+/', '_', (string) $dest);
// ne pas accepter de noms de la forme -r90.jpg qui sont reserves
// pour les images transformees par rotation (action/documenter)
$dest = preg_replace(',-r(90|180|270)$,', '', $dest);
while (preg_match(',\.(\w+)$,', $dest, $m)) {
if (
!function_exists('verifier_upload_autorise')
|| !($r = verifier_upload_autorise($dest))
|| !empty($r['autozip'])
$dest = substr($dest, 0, -strlen($m[0])) . '_' . $m[1];
break;
$dest = substr($dest, 0, -strlen($m[0]));
}
}
// Si le document "source" est deja au bon endroit, ne rien faire
cerdic
a validé
if ($source == ($dir . $dest . '.' . $ext)) {
cerdic
a validé
}
// sinon tourner jusqu'a trouver un numero correct
$n = 0;
cerdic
a validé
while (@file_exists($newFile = $dir . $dest . ($n++ ? ('-' . $n) : '') . '.' . $ext)) {
;
}
return deplacer_fichier_upload($source, $newFile);
* @uses autoriser()
* @uses _DIR_TRANSFERT
* @uses _DIR_TMP
* @uses sous_repertoire()
cerdic
a validé
*
* @param string $type
* @return bool|string
*/
gilles.vincent
a validé
function determine_upload($type = '') {
cerdic
a validé
if (!function_exists('autoriser')) {
include_spip('inc/autoriser');
cerdic
a validé
}
) { # on ne le permet pas pour les logos
return false;
cerdic
a validé
}
$repertoire = _DIR_TRANSFERT;
if (!@is_dir($repertoire)) {
$repertoire = str_replace(_DIR_TMP, '', (string) $repertoire);
$repertoire = sous_repertoire(_DIR_TMP, $repertoire);
}
cerdic
a validé
if (!$GLOBALS['visiteur_session']['restreint']) {
return $repertoire;
cerdic
a validé
} else {
return sous_repertoire($repertoire, $GLOBALS['visiteur_session']['login']);
cerdic
a validé
}
cerdic
a validé
*
* - `true` : on déplace le fichier source vers le fichier de destination
* - `false` : valeur par défaut. On ne fait que copier le fichier source vers la destination.
gilles.vincent
a validé
function deplacer_fichier_upload($source, $dest, $move = false) {
if (str_starts_with($dest, (string) _DIR_RACINE)) {
$dest = _DIR_RACINE . preg_replace(',\.\.+,', '.', substr($dest, strlen((string) _DIR_RACINE)));
cerdic
a validé
} else {
cerdic
a validé
}
$ok = $move ? @rename($source, $dest) : @copy($source, $dest);
cerdic
a validé
if (!$ok) {
$ok = @move_uploaded_file($source, $dest);
}
if ($ok) {
cerdic
a validé
} else {
$f = @fopen($dest, 'w');
cerdic
a validé
fclose($f);
} else {
include_spip('inc/flock');
raler_fichier($dest);
}
cerdic
a validé
/**
* Erreurs d'upload
*
* Renvoie `false` si pas d'erreur
* et `true` s'il n'y a pas de fichier à uploader.
* Pour les autres erreurs, on affiche le message d'erreur et on arrête l'action.
cerdic
a validé
*
* @link http://php.net/manual/fr/features.file-upload.errors.php
* Explication sur les messages d'erreurs de chargement de fichiers.
* @uses propre()
* @uses minipres()
cerdic
a validé
*
* @global string $spip_lang_right
* @param integer $error
* @param string $msg
* @param bool $return
* @return boolean|string
*/
gilles.vincent
a validé
function check_upload_error($error, $msg = '', $return = false) {
cerdic
a validé
if (!$error) {
return false;
}
spip_logger()->info("Erreur upload $error -- cf. http://php.net/manual/fr/features.file-upload.errors.php");
switch ($error) {
case 4: /* UPLOAD_ERR_NO_FILE */
return true;
# on peut affiner les differents messages d'erreur
case 1: /* UPLOAD_ERR_INI_SIZE */
$msg = _T(
'upload_limit',
['max' => ini_get('upload_max_filesize')]
);
break;
case 2: /* UPLOAD_ERR_FORM_SIZE */
$msg = _T(
'upload_limit',
['max' => ini_get('upload_max_filesize')]
);
break;
case 3: /* UPLOAD_ERR_PARTIAL */
$msg = _T(
'upload_limit',
['max' => ini_get('upload_max_filesize')]
);
break;
default: /* autre */
cerdic
a validé
if (!$msg) {
$msg = _T('pass_erreur') . ' ' . $error
. '<br>' . propre('[->http://php.net/manual/fr/features.file-upload.errors.php]');
cerdic
a validé
}
break;
}
spip_logger()->info("erreur upload $error");
cerdic
a validé
if ($return) {
return $msg;
cerdic
a validé
}
cerdic
a validé
echo "<div class='upload_answer upload_error'>$msg</div>";
exit;
"<div style='text-align: " . $GLOBALS['spip_lang_right'] . "'><a href='" . attribut_url(rawurldecode((string) $GLOBALS['redirect'])) . "'><button type='button'>" . _T('ecrire:bouton_suivant') . '</button></a></div>'
/**
* Corrige l'extension du fichier dans quelques cas particuliers
*
* @note
* Une extension 'pdf ' passe dans la requête de contrôle
* mysql> SELECT * FROM spip_types_documents WHERE extension="pdf ";
*
* @todo
* À passer dans base/typedoc
*
* @param string $ext
* @return string
*/
function corriger_extension($ext) {
$ext = preg_replace(',[^a-z0-9],i', '', $ext);
return match ($ext) {
'htm' => 'html',
'jpeg' => 'jpg',
'tiff' => 'tif',
'aif' => 'aiff',
'mpeg' => 'mpg',
default => $ext,
};