28 changed files with 903 additions and 774 deletions
@ -0,0 +1,26 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
function action_archive_mf_supprimer() { |
||||
|
||||
// Securisation de l'argument nom de l'archive |
||||
$securiser_action = charger_fonction('securiser_action', 'inc'); |
||||
$chemin_archive = $securiser_action(); |
||||
|
||||
// Si l'archive n'est pas accessible on renvoie une erreur |
||||
if (!@is_readable($chemin_archive)) { |
||||
spip_log("L'archive ${chemin_archive} n'est pas accessible pour le téléchargement", 'mes_fichiers' . _LOG_ERREUR); |
||||
redirige_par_entete(generer_url_ecrire('mes_fichiers', 'etat=nok_supp', true)); |
||||
} |
||||
|
||||
// Autorisation |
||||
if (!autoriser('webmestre')) { |
||||
include_spip('inc/minipres'); |
||||
echo minipres(); |
||||
exit; |
||||
} |
||||
|
||||
include_spip('inc/flock'); |
||||
supprimer_fichier($chemin_archive); |
||||
} |
@ -0,0 +1,34 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
function action_archive_mf_telecharger() { |
||||
|
||||
// Securisation de l'argument nom de l'archive |
||||
$securiser_action = charger_fonction('securiser_action', 'inc'); |
||||
$chemin_archive = $securiser_action(); |
||||
|
||||
// Si l'archive n'est pas accessible on renvoie une erreur |
||||
if (!@is_readable($chemin_archive)) { |
||||
spip_log("L'archive ${chemin_archive} n'est pas accessible pour le téléchargement", 'mes_fichiers' . _LOG_ERREUR); |
||||
redirige_par_entete(generer_url_ecrire('mes_fichiers', 'etat=nok_tele', true)); |
||||
} |
||||
|
||||
// Autorisation |
||||
if (!autoriser('webmestre')) { |
||||
include_spip('inc/minipres'); |
||||
echo minipres(); |
||||
exit; |
||||
} |
||||
|
||||
// Telechargement du fichier d'archive |
||||
header('Content-Description: File Transfer'); |
||||
header('Content-type: application/zip'); |
||||
header('Content-Disposition: attachment; filename="' . basename($chemin_archive) . '"'); |
||||
header('Content-Transfer-Encoding: binary'); |
||||
header('Pragma: public'); |
||||
header('Expires: 0'); |
||||
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0'); |
||||
header('Content-Length: ' . filesize($chemin_archive)); |
||||
readfile($chemin_archive); |
||||
} |
@ -1,46 +0,0 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
function action_mes_fichiers_sauver() { |
||||
|
||||
// Securisation: aucun argument attendu |
||||
|
||||
// Autorisation |
||||
if (!autoriser('sauvegarder')) { |
||||
include_spip('inc/minipres'); |
||||
echo minipres(); |
||||
exit; |
||||
} |
||||
|
||||
$liste = _request('a_sauver'); |
||||
if (is_null($liste)) { |
||||
$liste = array(); |
||||
} |
||||
|
||||
$sauver = charger_fonction('mes_fichiers_sauver', 'inc'); |
||||
$erreur = $sauver($liste); |
||||
|
||||
if (_request('redirect')) { |
||||
// TODO : verifier si ce cas est encore utilise |
||||
if ($erreur) { |
||||
$redirect = parametre_url( |
||||
urldecode(_request('redirect')), |
||||
'etat', |
||||
'nok_sauve', |
||||
'&' |
||||
); |
||||
} else { |
||||
$redirect = parametre_url( |
||||
urldecode(_request('redirect')), |
||||
'etat', |
||||
'ok_sauve', |
||||
'&' |
||||
); |
||||
} |
||||
include_spip('inc/headers'); |
||||
redirige_par_entete($redirect); |
||||
} else { |
||||
return $erreur; |
||||
} |
||||
} |
@ -1,33 +0,0 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
function action_mes_fichiers_telecharger() { |
||||
|
||||
// Securisation de l'argument nom de l'archive |
||||
$securiser_action = charger_fonction('securiser_action', 'inc'); |
||||
$arg = $securiser_action(); |
||||
|
||||
// Si l'archive n'est pas accessible on renvoie une erreur |
||||
if (!@is_readable($arg)) { |
||||
spip_log("L'archive ${arg} n'est pas accessible pour le téléchargement", 'mes_fichiers' . _LOG_ERREUR); |
||||
redirige_par_entete(generer_url_ecrire('mes_fichiers', 'etat=nok_tele', true)); |
||||
} |
||||
|
||||
// Autorisation |
||||
if (!autoriser('sauvegarder')) { |
||||
include_spip('inc/minipres'); |
||||
echo minipres(); |
||||
exit; |
||||
} |
||||
|
||||
// Telechargement du fichier |
||||
header('Content-type: application/force-download;'); |
||||
header('Content-Transfer-Encoding: application/zip'); |
||||
header('Content-Length: ' . filesize($arg)); |
||||
header('Content-Disposition: attachment; filename="' . basename($arg) . '"'); |
||||
header('Pragma: no-cache'); |
||||
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, public'); |
||||
header('Expires: 0'); |
||||
readfile($arg); |
||||
} |
@ -0,0 +1,63 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
function formulaires_archive_mf_creer_charger_dist() { |
||||
|
||||
// On charge la liste de tous fichiers/dossiers pouvant être archivés sans filtrer par la taille max |
||||
include_spip('inc/mes_fichiers'); |
||||
$liste = mes_fichiers_lister(); |
||||
|
||||
// Taille max des fichiers/dossiers autorisés |
||||
$megaoctets_max = intval(lire_config('mes_fichiers/taille_max_rep', '75')); |
||||
// Convertir la taille max de Mo en octets pour comparaison |
||||
$octets_max = taille_convertir_en_octets($megaoctets_max); |
||||
|
||||
// On prépare la liste des fichiers/dossiers pour un affichage simple dans le formulaire |
||||
include_spip('mes_fichiers_fonctions'); |
||||
$chemins = []; |
||||
foreach ($liste as $_chemin) { |
||||
// Calcul de la taille des fichiers/dossiers |
||||
$octets = mes_fichiers_lire_taille($_chemin); |
||||
$chemins[$_chemin]['taille'] = mes_fichiers_afficher_taille($octets); |
||||
$chemins[$_chemin]['disable'] = ($octets_max > 0) && ($octets > $octets_max); |
||||
} |
||||
|
||||
return [ |
||||
'_fichiers' => $chemins, |
||||
'limite_max' => mes_fichiers_afficher_taille($octets_max), |
||||
'editable' => autoriser('sauvegarder') |
||||
]; |
||||
} |
||||
|
||||
function formulaires_archive_mf_creer_verifier_dist() { |
||||
|
||||
// Initialisation des erreurs de saisie |
||||
$erreurs = []; |
||||
|
||||
// Il devient obligatoire de saisir une liste non vide à archiver |
||||
if (!_request('a_sauver')) { |
||||
$erreurs['a_sauver'] = _T('info_obligatoire'); |
||||
} |
||||
|
||||
return $erreurs; |
||||
} |
||||
|
||||
function formulaires_archive_mf_creer_traiter_dist() { |
||||
|
||||
// Récupération de la liste des fichiers à archiver |
||||
$chemins = _request('a_sauver'); |
||||
|
||||
// Lancement de l'archivage |
||||
include_spip('inc/mes_fichiers_archive_mf'); |
||||
$erreur = archive_mf_creer($chemins); |
||||
|
||||
if ($erreur) { |
||||
$retour['message_erreur'] = _T('mes_fichiers:message_sauvegarde_nok', ['erreur' => $erreur]); |
||||
} else { |
||||
$retour['message_ok'] = _T('mes_fichiers:message_sauvegarde_ok'); |
||||
} |
||||
|
||||
return $retour; |
||||
} |
@ -1,46 +0,0 @@
|
||||
<?php |
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
function formulaires_mes_fichiers_sauver_charger_dist() { |
||||
|
||||
// On charge la liste des fichiers pouvant être archivés |
||||
include_spip('inc/mes_fichiers_utils'); |
||||
return [ |
||||
'_fichiers' => mes_fichiers_a_sauver(), |
||||
'editable' => autoriser('sauvegarder') |
||||
]; |
||||
} |
||||
|
||||
function formulaires_mes_fichiers_sauver_verifier_dist() { |
||||
|
||||
// Initialisation des erreurs de saisie |
||||
$erreurs = []; |
||||
|
||||
// Il devient obligatoire de saisir une liste non vide à archiver |
||||
if (!_request('a_sauver')) { |
||||
$erreurs['a_sauver'] = _T('info_obligatoire'); |
||||
} |
||||
|
||||
return $erreurs; |
||||
} |
||||
|
||||
function formulaires_mes_fichiers_sauver_traiter_dist() { |
||||
|
||||
// Récupération de la liste des fichiers à archiver |
||||
$chemins = _request('a_sauver'); |
||||
|
||||
// Lancement de l'archivage |
||||
$archiver = charger_fonction('mes_fichiers_sauver', 'inc'); |
||||
$erreur = $archiver($chemins); |
||||
|
||||
if ($erreur) { |
||||
$retour['message_erreur'] = _T('mes_fichiers:message_sauvegarde_nok', ['erreur' => $erreur]); |
||||
} else { |
||||
$retour['message_ok'] = _T('mes_fichiers:message_sauvegarde_ok'); |
||||
} |
||||
|
||||
return $retour; |
||||
} |
@ -0,0 +1,18 @@
|
||||
<?php |
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
/** |
||||
* Nettoyage journalier des archives obsolètes. |
||||
* |
||||
* @param timestamp $last |
||||
*/ |
||||
function genie_archive_mf_nettoyer_dist($last) { |
||||
|
||||
// On supprime les archives obsolètes en fonction de la duree de conservation. |
||||
include_spip('inc/mes_fichiers_archive_mf'); |
||||
archive_mf_nettoyer(['auteur' => 'cron']); |
||||
|
||||
return 1; |
||||
} |
@ -1,17 +0,0 @@
|
||||
<?php |
||||
|
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
/** |
||||
* Nettoyage journalier des fichiers obsoletes. |
||||
* |
||||
* @param timestamp $last |
||||
*/ |
||||
function genie_mes_fichiers_cleaner_dist($last) { |
||||
// On supprime les fichiers obsoletes en fonction de la duree de conservation |
||||
$supprimer_obsoletes = charger_fonction('mes_fichiers_cleaner', 'inc'); |
||||
$supprimer_obsoletes(array('auteur' => 'cron')); |
||||
|
||||
return 1; |
||||
} |
@ -0,0 +1,300 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
/** |
||||
* Renvoie la liste des fichiers et repertoires pouvant être sauvegarder, en filtrant ou pas selon une taille |
||||
* maximale. |
||||
* |
||||
* @api |
||||
* |
||||
* @uses dossier_trouver_fichier_recent() |
||||
* @uses mes_fichiers_filtrer() |
||||
* |
||||
* @param bool $filtrer_max_octets Indique si la liste doit être filtrée en fonction d'une taille maximale |
||||
* (configurée). |
||||
* |
||||
* @return array Liste des fichiers et repertoires pouvant être sauvegarder |
||||
*/ |
||||
function mes_fichiers_lister($filtrer_max_octets = false) { |
||||
|
||||
// Constituer la liste des fichiers et dossiers pouvant être sauvegardés |
||||
// -- on garde en statique la liste complète non filtrée |
||||
static $liste = array(); |
||||
|
||||
if (!$liste) { |
||||
// Dans le cas de la mutu, les fichiers de personnalisation sont places |
||||
// - soit dans le site d'un sous-domaine, il faut donc aller les chercher a la racine de ce sous-domaine |
||||
// en utilisant _DIR_SITE |
||||
// - soit dans le site principal, il faut dans ce cas utiliser _DIR_RACINE |
||||
$dir_site = defined('_DIR_SITE') |
||||
? _DIR_SITE |
||||
: _DIR_RACINE; |
||||
|
||||
// Rechercher le fichier sqlite le plus récent depuis config/bases |
||||
$tmp_db = defined('_DIR_DB') ? _DIR_DB : $dir_site . 'config/bases/'; |
||||
if ($fichier_db = dossier_trouver_fichier_recent($tmp_db)) { |
||||
$liste[] = $fichier_db; |
||||
} |
||||
|
||||
// le fichier d'options si il existe |
||||
if ( |
||||
@is_readable($f = $dir_site . _NOM_PERMANENTS_INACCESSIBLES . _NOM_CONFIG . '.php') |
||||
or (!defined('_DIR_SITE') && @is_readable($f = _FILE_OPTIONS)) |
||||
) { |
||||
$liste[] = $f; |
||||
} |
||||
|
||||
// le fichier .htaccess a la racine qui peut contenir des persos |
||||
$htaccess = defined('_ACCESS_FILE_NAME') ? _DIR_RACINE . _ACCESS_FILE_NAME : _DIR_RACINE . '.htaccess'; |
||||
if (@is_readable($htaccess)) { |
||||
$liste[] = $htaccess; |
||||
} |
||||
|
||||
// le fameux repertoire des documents et images |
||||
$IMG = defined('_DIR_IMG') ? _DIR_IMG : $dir_site . 'IMG/'; |
||||
if (@is_dir($IMG)) { |
||||
$liste[] = $IMG; |
||||
} |
||||
|
||||
// le(s) dossier(s) des squelettes nommes |
||||
if (strlen($GLOBALS['dossier_squelettes'])) { |
||||
// Dans le cas d'une mutu, la globale est toujours mise à jour sous la forme sites/domaine/squelettes |
||||
// Cela revient donc au même que pour une install non mutualisée, il faut donc utiliser _DIR_RACINE |
||||
foreach (explode(':', $GLOBALS['dossier_squelettes']) as $_dir) { |
||||
$dir = ($_dir[0] == '/' ? '' : _DIR_RACINE) . $_dir . '/'; |
||||
if (@is_dir($dir)) { |
||||
$liste[] = $dir; |
||||
} |
||||
} |
||||
} elseif (@is_dir($dir_site . 'squelettes/')) { |
||||
$liste[] = $dir_site . 'squelettes/'; |
||||
} |
||||
|
||||
// le dernier fichier de dump de la base |
||||
$tmp_dump = defined('_DIR_DUMP') |
||||
? _DIR_DUMP |
||||
: $dir_site . 'tmp/dump/'; |
||||
if ($fichier_dump = dossier_trouver_fichier_recent($tmp_dump)) { |
||||
$liste[] = $fichier_dump; |
||||
} |
||||
|
||||
// On ajoute via un pipeline pour déclarer des fichiers à sauvegarder provenant de plugins |
||||
// et on renvoie la liste complète sans doublons. |
||||
$liste_en_plus = pipeline('mes_fichiers_a_sauver', []); |
||||
$liste = array_unique(array_merge($liste, $liste_en_plus)); |
||||
} |
||||
|
||||
// Filtrage de la liste si demandé |
||||
if ($filtrer_max_octets) { |
||||
$liste = mes_fichiers_filtrer($liste); |
||||
} |
||||
|
||||
return $liste; |
||||
} |
||||
|
||||
/** |
||||
* Filtre la liste des fichiers et dossiers à archiver selon la taille maximale configurée. |
||||
* Si aucune limite n'est précisée en configuration, la liste n'est pas filtrée. |
||||
* |
||||
* @api |
||||
* |
||||
* @uses taille_convertir_en_octets() |
||||
* @uses mes_fichiers_lire_taille() |
||||
* |
||||
* @param array $liste Liste des fichiers et repertoires pouvant être sauvegarder quelque soit leur taille |
||||
* |
||||
* @return array Liste des fichiers/dossiers filtrée selon la taille |
||||
*/ |
||||
function mes_fichiers_filtrer($liste) { |
||||
|
||||
// Extraction de la taille max en mega octets et vérification de la nécessité de filtrer la liste |
||||
include_spip('inc/config'); |
||||
$megaoctets_max = intval(lire_config('mes_fichiers/taille_max_rep', '75')); |
||||
if ($megaoctets_max > 0) { |
||||
// Convertir la taille max de Mo en octets pour comparaison |
||||
$octets_max = taille_convertir_en_octets($megaoctets_max); |
||||
|
||||
// Exclusion des fichiers ou dossiers trop volumineux |
||||
foreach ($liste as $_cle => $_chemin) { |
||||
// Calcul de la taille du fichier ou dossier |
||||
$taille_octets = mes_fichiers_lire_taille($_chemin); |
||||
if ($taille_octets > $octets_max) { |
||||
unset($liste[$_cle]); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $liste; |
||||
} |
||||
|
||||
/** |
||||
* Renvoie la taille d'un fichier ou d'un répertoire exprimée en octets. |
||||
* |
||||
* @uses dossier_calculer_taille() |
||||
* |
||||
* @param string $chemin Chemin vers le fichier ou le dossier concerné |
||||
* |
||||
* @return int Taille du dossier ou du fichier en octets |
||||
*/ |
||||
function mes_fichiers_lire_taille($chemin) { |
||||
|
||||
return is_dir($chemin) |
||||
? dossier_calculer_taille($chemin) |
||||
: filesize($chemin); |
||||
} |
||||
|
||||
/** |
||||
* Renvoie un chemin de dossier le plus propre possible en gérant le cas d'un SPIP mutualisé ou non. |
||||
* |
||||
* @uses joli_repertoire() |
||||
* |
||||
* @param string $dossier Chemin du dossier à afficher d'une manière la plus lisible. |
||||
*/ |
||||
function mes_fichiers_afficher_dossier($dossier) { |
||||
|
||||
if ( |
||||
defined('_DIR_SITE') |
||||
and preg_match(',' . _DIR_SITE . ',', $dossier) |
||||
) { |
||||
$joli_repertoire = str_replace(_DIR_SITE, '', $dossier); |
||||
} else { |
||||
include_spip('inc/utils'); |
||||
$joli_repertoire = joli_repertoire($dossier); |
||||
} |
||||
|
||||
return $joli_repertoire; |
||||
} |
||||
|
||||
// ---------------------------- |
||||
|
||||
/** |
||||
* Renvoie le fichier le plus récent d'un dossier donné. |
||||
* Le dossier ne doit contenir que des fichiers concernant le même sujet. |
||||
* |
||||
* @param $dossier |
||||
* |
||||
* @return string |
||||
*/ |
||||
function dossier_trouver_fichier_recent($dossier) { |
||||
|
||||
// Par défaut, si le dossier est vide on renvoie un nom de fichier vide |
||||
$fichier_recent = ''; |
||||
|
||||
// On considère que dans le dossier tous les fichiers concernent le même sujet, il est donc inutile |
||||
// d'utiliser un pattern pour le fichier. |
||||
include_spip('inc/flock'); |
||||
$fichiers = preg_files($dossier); |
||||
$mtime_recent = 0; |
||||
foreach ($fichiers as $_fichier) { |
||||
if (($mtime = filemtime($_fichier)) > $mtime_recent) { |
||||
$fichier_recent = $_fichier; |
||||
$mtime_recent = $mtime; |
||||
} |
||||
} |
||||
|
||||
return $fichier_recent; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Calculer la taille d'un répertoire en itérant sur son contenu. |
||||
* |
||||
* @link http://aidanlister.com/repos/v/function.dirsize.php |
||||
* |
||||
* @param string $path Chemin vers le dossier concerné |
||||
* |
||||
* @return int |
||||
*/ |
||||
function dossier_calculer_taille($path) { |
||||
|
||||
// Par défaut, erreur ou pas, le dossier est vide |
||||
$size = 0; |
||||
|
||||
// Trailing slash |
||||
if (substr($path, -1, 1) !== DIRECTORY_SEPARATOR) { |
||||
$path .= DIRECTORY_SEPARATOR; |
||||
} |
||||
|
||||
// Sanity check |
||||
if (is_file($path)) { |
||||
$size = filesize($path); |
||||
} elseif (is_dir($path)) { |
||||
// Iterate queue |
||||
$queue = array($path); |
||||
for ($i = 0, $j = count($queue); $i < $j; ++$i) { |
||||
// Open directory |
||||
if (is_dir($queue[$i]) && $dir = @dir($queue[$i])) { |
||||
$subdirs = array(); |
||||
while (false !== ($entry = $dir->read())) { |
||||
// Skip pointers |
||||
if ($entry == '.' || $entry == '..') { |
||||
continue; |
||||
} |
||||
|
||||
// Get list of directories or filesizes |
||||
$path = $queue[$i] . $entry; |
||||
if (is_dir($path)) { |
||||
$path .= DIRECTORY_SEPARATOR; |
||||
$subdirs[] = $path; |
||||
} elseif (is_file($path)) { |
||||
$size += filesize($path); |
||||
} |
||||
} |
||||
|
||||
// Add subdirectories to start of queue |
||||
unset($queue[0]); |
||||
$queue = array_merge($subdirs, $queue); |
||||
|
||||
// Recalculate stack size |
||||
$i = -1; |
||||
$j = count($queue); |
||||
|
||||
// Clean up |
||||
$dir->close(); |
||||
unset($dir); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $size; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Convertit en octets une taille exprimée en multiple d'octets, en considérant le système d'unité utilisé, à savoir, |
||||
* le système international en base 10 ou le système binaire. |
||||
* |
||||
* @param int $taille Taille dans l'unité spécifiée en second argument |
||||
* @param string $unite Abbréviation de l'unité, à savoir, `K`, `M` (défaut), `G` ou `T`. |
||||
* @param string $systeme Système d'unité dans lequel calculer et afficher la taille lisble. Vaut `BI` (défaut) ou `SI`. |
||||
* |
||||
* @return int |
||||
*/ |
||||
function taille_convertir_en_octets($taille, $unite = 'M', $systeme = 'BI') { |
||||
|
||||
static $puissances = [ |
||||
'k' => 1, |
||||
'm' => 2, |
||||
'g' => 3, |
||||
't' => 4, |
||||
]; |
||||
static $bases = [ |
||||
'si' => 1000, |
||||
'bi' => 1024 |
||||
]; |
||||
|
||||
// Si l'unité est incorrecte on renvoie 0 |
||||
$taille_octets = 0; |
||||
if ( |
||||
($unite = strtolower($unite)) |
||||
and array_key_exists($unite, $puissances) |
||||
and ($systeme = strtolower($systeme)) |
||||
and array_key_exists($systeme, $bases) |
||||
) { |
||||
return (int)$taille * pow($bases[$systeme], $puissances[$unite]); |
||||
} |
||||
|
||||
return $taille_octets; |
||||
} |
@ -0,0 +1,254 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
if (!defined('_MES_FICHIERS_DOSSIER')) { |
||||
/** |
||||
* Repertoire de stockage des archives |
||||
*/ |
||||
define('_MES_FICHIERS_DOSSIER', _DIR_TMP . 'mes_fichiers/'); |
||||
} |
||||
|
||||
/** |
||||
* La fonction de sauvegarde des fichiers. |
||||
* |
||||
* @api |
||||
* |
||||
* @param array|null $liste Liste des dossiers ou fichiers à archiver ou null pour archiver tout ce qui est possible |
||||
* @param array $options Options d'archivage. Pour l'instant uniquement l'auteur ayant déclenché l'archivage. |
||||
* |
||||
* @return string Message d'erreur éventuel ou chaine vide sinon. |
||||
*/ |
||||
function archive_mf_creer($liste = null, $options = array()) { |
||||
// Message d'erreur en retour de la fonction : chaine si pas d'erreur |
||||
$erreur = ''; |
||||
|
||||
// Si on a passé null pour la liste des fichiers, c'est que l'on veut sauvegarder tout ce qui est possible |
||||
// En effet, ce peut être un array vide dans le cas d'un problème de config. |
||||
include_spip('inc/mes_fichiers'); |
||||
if (is_null($liste)) { |
||||
// Les répertoires et fichiers qui excèdent la taille maximale configurée sont exclus |
||||
$liste = mes_fichiers_lister(true); |
||||
} |
||||
|
||||
// Identification de l'auteur ayant déclenché l'archivage |
||||
$auteur = !empty($options['auteur']) |
||||
? $options['auteur'] |
||||
: $GLOBALS['visiteur_session']['id_auteur']; |
||||
|
||||
// Si il y a quelque chose à archiver |
||||
if (count($liste) > 0) { |
||||
// On stocke les fichiers et répertoires source pour insérer cette liste en commentaire de l'archive |
||||
$liste_finale = []; |
||||
foreach ($liste as $_chemin) { |
||||
$liste_finale[] = mes_fichiers_afficher_dossier($_chemin); |
||||
} |
||||
|
||||
// On construit le nom de l'archive et on crée le répertoire d'accueil si il n'existe pas déjà. |
||||
$dir = sous_repertoire(_MES_FICHIERS_DOSSIER); |
||||
$prefixe = lire_config('mes_fichiers/prefixe', 'mf3'); |
||||
$chemin_archive = $dir . $prefixe . '_' . date('Ymd_His') . '.zip'; |
||||
|
||||
// On prépare le commentaire |
||||
if ($auteur === 'cron') { |
||||
$auteur = 'SPIP'; |
||||
} |
||||
$meta = [ |
||||
'auteur' => $auteur, |
||||
'contenu' => $liste_finale |
||||
]; |
||||
|
||||
// On lance l'archivage du contenu. |
||||
include_spip('inc/archives'); |
||||
$archive = new Spip\Archives\SpipArchives($chemin_archive); |
||||
if (!$archive->emballer($liste)) { |
||||
// -- on renvoie le message d'erreur provenant de la librairie d'archivage |
||||
$erreur = $archive->message(); |
||||
} else { |
||||
// -- si pas d'erreur, on ajoute le commentaire |
||||
$archive->commenter(serialize($meta)); |
||||
} |
||||
} else { |
||||
$erreur = _T('mes_fichiers:erreur_aucun_fichier_sauver'); |
||||
} |
||||
|
||||
// Un pipeline post_sauvegarde pour que d'autres plugins puissent agir à ce moment là. |
||||
pipeline( |
||||
'post_sauvegarde', |
||||
array( |
||||
'args' => array( |
||||
'err' => $erreur, |
||||
'auteur' => $auteur, |
||||
'type' => 'mes_fichiers_sauver' |
||||
), |
||||
'data' => '' |
||||
) |
||||
); |
||||
|
||||
// Notifications si nécessaire. |
||||
if ($notifications = charger_fonction('notifications', 'inc')) { |
||||
$notifications( |
||||
'archive_mf_creer', |
||||
'', |
||||
array( |
||||
'auteur' => $auteur, |
||||
'err' => $erreur) |
||||
); |
||||
} |
||||
|
||||
return $erreur; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Supprime les fichiers d'archive considérés comme obsolètes. |
||||
* La fonction retourne la liste des archives effectivement supprimées. |
||||
* |
||||
* @api |
||||
* |
||||
* @param array $options |
||||
* |
||||
* @return array Liste des archives effectivement supprimées. |
||||
*/ |
||||
function archive_mf_nettoyer($options = array()) { |
||||
// Initialiser la liste des archives supprimées fournie en retour |
||||
$liste = []; |
||||
|
||||
// Supprimer les archives dont l'échéance de garde est échue |
||||
include_spip('inc/config'); |
||||
$duree_sauvegarde = intval(lire_config('mes_fichiers/duree_sauvegarde', 15)); |
||||
if ($duree_sauvegarde > 0) { |
||||
// Stocker la date actuelle pour calculer l'obsolescence |
||||
$temps = time(); |
||||
|
||||
// Identification du préfixe des archives |
||||
$prefixe = lire_config('mes_fichiers/prefixe', 'mf3') . '_'; |
||||
|
||||
// Scan des archives existantes et suppression des obsolètes |
||||
include_spip('inc/flock'); |
||||
$archives = preg_files(_MES_FICHIERS_DOSSIER, "${prefixe}.+[.](zip)$"); |
||||
$liste = array(); |
||||
foreach ($archives as $_archive) { |
||||
$date_fichier = filemtime($_archive); |
||||
if ($temps > ($date_fichier + $duree_sauvegarde * 3600 * 24)) { |
||||
supprimer_fichier($_archive); |
||||
$liste[] = $_archive; |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Identification de l'auteur ayant déclenché l'archivage |
||||
$auteur = $options['auteur'] ?: $GLOBALS['visiteur_session']['id_auteur']; |
||||
if ($auteur == 'cron') { |
||||
$auteur = 'SPIP'; |
||||
} |
||||
|
||||
// Pipeline de post sauvegarde si besoin |
||||
pipeline( |
||||
'post_sauvegarde', |
||||
array( |
||||
'args' => array( |
||||
'liste' => $liste, |
||||
'auteur' => $auteur, |
||||
'type' => 'mes_fichiers_cleaner' |
||||
), |
||||
'data' => '' |
||||
) |
||||
); |
||||
|
||||
// Notification de l'action |
||||
if ($notifications = charger_fonction('notifications', 'inc')) { |
||||
$notifications( |
||||
'archive_mf_nettoyer', |
||||
'', |
||||
array('liste' => $liste, 'auteur' => $auteur) |
||||
); |
||||
} |
||||
|
||||
return $liste; |
||||
} |
||||
|
||||
/** |
||||
* Renvoie la liste des archives disponibles au telechargement par date inverse |
||||
* |
||||
* @api |
||||
* |
||||
* @return array |
||||
*/ |
||||
function archive_mf_lister() { |
||||
|
||||
include_spip('inc/config'); |
||||
$prefixe = lire_config('mes_fichiers/prefixe', 'mf3'); |
||||
$laver_auto = (lire_config('mes_fichiers/nettoyage_journalier', 'oui') == 'oui'); |
||||
|
||||
$pattern = "${prefixe}.*\.zip$"; |
||||
|
||||
include_spip('inc/flock'); |
||||
if ($laver_auto) { |
||||
$liste = preg_files(_MES_FICHIERS_DOSSIER, $pattern); |
||||
} else { |
||||
$liste = preg_files(_MES_FICHIERS_DOSSIER, $pattern, 50); |
||||
} |
||||
|
||||
// On filtre les fichiers vides ou corrompues qui sont des résultats d'erreur lors de l'archivage |
||||
foreach ($liste as $_cle => $_archive) { |
||||
if (!is_file($_archive) |
||||
or !is_readable($_archive) |
||||
or (filesize($_archive) === 0)) { |
||||
unset($liste[$_cle]); |
||||
} |
||||
} |
||||
|
||||
return array_reverse($liste); |
||||
} |
||||
|
||||
/** |
||||
* Renvoie les informations sur le contenu de l'archive |
||||
* |
||||
* @api |
||||
* |
||||
* @param string $zip Chemin de l'archive |
||||
* |
||||
* @return string |
||||
*/ |
||||
function archive_mf_informer($zip) { |
||||
|
||||
// Extraction des informations sur l'archive |
||||
include_spip('inc/archives'); |
||||
$archive = new Spip\Archives\SpipArchives($zip); |
||||
$informations = $archive->informer(); |
||||
|
||||
$resume = ''; |
||||
if (empty($informations['commentaire'])) { |
||||
$resume .= _T('mes_fichiers:message_zip_propriete_nok'); |
||||
spip_log('Commentaire de l\'archive absente ou d\'un format obsolète', 'mes_fichiers' . _LOG_ERREUR); |
||||
} else { |
||||
$commentaire = unserialize($informations['commentaire']); |
||||
|
||||
if ( |
||||
!empty($commentaire['contenu']) |
||||
and !empty($commentaire['auteur']) |
||||
) { |
||||
$liste = $commentaire['contenu']; |
||||
$id_auteur = $commentaire['auteur']; |
||||
|
||||
// On gere le cas où l'auteur est le cron |
||||
if (intval($id_auteur)) { |
||||
$auteur = sql_getfetsel('nom', 'spip_auteurs', 'id_auteur=' . intval($id_auteur)); |
||||
} else { |
||||
$auteur = $id_auteur; |
||||
} |
||||
$resume .= _T('mes_fichiers:resume_zip_auteur') . ' : ' . $auteur . '<br />'; |
||||
$resume .= _T('mes_fichiers:resume_zip_compteur') . ' : ' . count($informations['fichiers']) . '<br />'; |
||||
$resume .= _T('mes_fichiers:resume_zip_contenu') . ' : ' . '<br />'; |
||||
$resume .= '<ul class="spip">'; |
||||
foreach ($liste as $_fichier) { |
||||
$resume .= '<li>' . $_fichier . '</li>'; |
||||
} |
||||
$resume .= '</ul>'; |
||||
} |
||||
} |
||||
|
||||
return $resume; |
||||
} |
@ -1,68 +0,0 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
/** |
||||
* Supprime les fichiers d'archive considérés comme obsolètes. |
||||
* La fonction retourne la liste des archives effectivement supprimées. |
||||
* |
||||
* @param array $options |
||||
* |
||||
* @return array Liste des archives effectivement supprimées. |
||||
*/ |
||||
function inc_mes_fichiers_cleaner_dist($options = array()) { |
||||
// Initialiser la liste des archives supprimées fournie en retour |
||||
$liste = []; |
||||
|
||||
// Supprimer les archives dont l'échéance de garde est échue |
||||
include_spip('inc/config'); |
||||
$jours_obso = intval(lire_config('mes_fichiers/duree_sauvegarde', 15)); |
||||
if ($jours_obso > 0) { |
||||
// Stocker la date actuelle pour calculer l'obsolescence |
||||
$temps = time(); |
||||
|
||||
// Scan des archives existantes |
||||
include_spip('inc/mes_fichiers_utils'); |
||||
$prefixe = lire_config('mes_fichiers/prefixe', 'mf2') . '_'; |
||||
$archives = preg_files(_MES_FICHIERS_DOSSIER, "${prefixe}.+[.](zip)$"); |
||||
$liste = array(); |
||||
foreach ($archives as $_archive) { |
||||
$date_fichier = filemtime($_archive); |
||||
if ($temps > ($date_fichier + $jours_obso * 3600 * 24)) { |
||||
$liste[] = $_archive; |
||||
supprimer_fichier($_archive); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// Identification de l'auteur ayant déclenché l'archivage |
||||
$auteur = $options['auteur'] ?: $GLOBALS['visiteur_session']['id_auteur']; |
||||
if ($auteur == 'cron') { |
||||
$auteur = 'SPIP'; |
||||
} |
||||
|
||||
// Pipeline de post sauvegarde si besoin |
||||
pipeline( |
||||
'post_sauvegarde', |
||||
array( |
||||
'args' => array( |
||||
'liste' => $liste, |
||||
'auteur' => $auteur, |
||||
'type' => 'mes_fichiers_cleaner' |
||||
), |
||||
'data' => '' |
||||
) |
||||
); |
||||
|
||||
// Notification de l'action |
||||
if ($notifications = charger_fonction('notifications', 'inc')) { |
||||
$notifications( |
||||
'mes_fichiers_cleaner', |
||||
'', |
||||
array('liste' => $liste, 'auteur' => $auteur) |
||||
); |
||||
} |
||||
|
||||
return $liste; |
||||
} |
@ -0,0 +1,45 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
/** |
||||
* @param $quoi |
||||
* @param $id |
||||
* @param $options |
||||
* |
||||
* @return null|mixed |
||||
*/ |
||||
function inc_mes_fichiers_destinataires_dist($quoi, $id, $options) { |
||||
|
||||
// Recuperation des destinataires configurés |
||||
include_spip('inc/config'); |
||||
$mails_configures = lire_config('mes_fichiers/notif_mail', []); |
||||
if ($mails_configures) { |
||||
$mails_configures = explode(',', $mails_configures); |
||||
} |
||||
|
||||
// On ajoute systématiquement le webmestre |
||||
if (!empty($GLOBALS['meta']['email_webmaster'])) { |
||||
$mails_configures[] = $GLOBALS['meta']['email_webmaster']; |
||||
} |
||||
|
||||
// On ajoute les éventuels destinataires supplémentaires fournis par des plugins |
||||
$destinataires = pipeline( |
||||
'notifications_destinataires', |
||||
[ |
||||
'args'=> [ |
||||
'quoi' => $quoi, |
||||
'id' => $id, |
||||
'options'=> $options |
||||
], |
||||
'data'=> $mails_configures |
||||
] |
||||
); |
||||
|
||||
// Nettoyage de la liste d'emails en vérifiant les doublons |
||||
// et la validité des emails |
||||
include_spip('inc/notifications'); |
||||
notifications_nettoyer_emails($destinataires); |
||||
|
||||
return $destinataires; |
||||
} |
@ -1,98 +0,0 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
/** |
||||
* La fonction de sauvegarde des fichiers. |
||||
* |
||||
* @param array|null $liste Liste des dossiers ou fichiers à archiver ou null pour archiver tout ce qui est possible |
||||
* @param array $options Options d'archivage. Pour l'instant uniquement l'auteur ayant déclenché l'archivage. |
||||
* |
||||
* @return string Message d'erreur éventuel ou chaine vide sinon. |
||||
*/ |
||||
function inc_mes_fichiers_sauver_dist($liste = null, $options = array()) { |
||||
// Message d'erreur en retour de la fonction : chaine si pas d'erreur |
||||
$erreur = ''; |
||||
|
||||
// Si on a passé null pour la liste des fichiers, c'est que l'on veut sauvegarder tout ce qui est possible |
||||
// En effet, ce peut être un array vide dans le cas d'un problème de config. |
||||
include_spip('inc/mes_fichiers_utils'); |
||||
if (is_null($liste)) { |
||||
$liste = mes_fichiers_a_sauver(); |
||||
} |
||||
|
||||
// Identification de l'auteur ayant déclenché l'archivage |
||||
$auteur = !empty($options['auteur']) |
||||
? $options['auteur'] |
||||
: $GLOBALS['visiteur_session']['id_auteur']; |
||||
|
||||
// Si il y a quelque chose à archiver |
||||
if (count($liste) > 0) { |
||||
// On vérifie que les répertoires n'excèdent pas la taille maximale configurée |
||||
// et on stocke les fichiers et répertoires pour insérer cette liste en commentaire de l'archive |
||||
include_spip('inc/config'); |
||||
$taille_max = intval(lire_config('mes_fichiers/taille_max_rep', 75)) * 1000 * 1000; |
||||
$liste_finale = []; |
||||
foreach ($liste as $_cle => $_chemin) { |
||||
if (is_dir($_chemin) and (mes_fichiers_dirsize($_chemin) > $taille_max)) { |
||||
unset($liste[$_cle]); |
||||
} else { |
||||
$liste_finale[] = mes_fichiers_joli_repertoire($_chemin); |
||||
} |
||||
} |
||||
|
||||
// On construit le nom de l'archive et on crée le répertoire d'accueil si il n'existe pas déjà. |
||||
$dir = sous_repertoire(_MES_FICHIERS_DOSSIER); |
||||
$prefixe = lire_config('mes_fichiers/prefixe', 'mf2'); |
||||
$chemin_archive = $dir . $prefixe . '_' . date('Ymd_His') . '.zip'; |
||||
|
||||
// On prépare le commentaire |
||||
if ($auteur === 'cron') { |
||||
$auteur = 'SPIP'; |
||||
} |
||||
$meta = [ |
||||
'auteur' => $auteur, |
||||
'contenu' => $liste_finale |
||||
]; |
||||
|
||||
// On lance l'archivage du contenu. |
||||
include_spip('inc/archives'); |
||||
$archive = new Spip\Archives\SpipArchives($chemin_archive); |
||||
if (!$archive->emballer($liste)) { |
||||
// -- on renvoie le message d'erreur provenant de la librairie d'archivage |
||||
$erreur = $archive->message(); |
||||
} else { |
||||
// -- si pas d'erreur, on ajoute le commentaire |
||||
$archive->commenter(serialize($meta)); |
||||
} |
||||
} else { |
||||
$erreur = _T('mes_fichiers:erreur_aucun_fichier_sauver'); |
||||
} |
||||
|
||||
// Un pipeline post_sauvegarde pour que d'autres plugins puissent agir à ce moment là. |
||||
pipeline( |
||||
'post_sauvegarde', |
||||
array( |
||||
'args' => array( |
||||
'err' => $erreur, |
||||
'auteur' => $auteur, |
||||
'type' => 'mes_fichiers_sauver' |
||||
), |
||||
'data' => '' |
||||
) |
||||
); |
||||
|
||||
// Notifications si nécessaire. |
||||
if ($notifications = charger_fonction('notifications', 'inc')) { |
||||
$notifications( |
||||
'mes_fichiers_sauver', |
||||
'', |
||||
array( |
||||
'auteur' => $auteur, |
||||
'err' => $erreur) |
||||
); |
||||
} |
||||
|
||||
return $erreur; |
||||
} |
@ -1,274 +0,0 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
if (!defined('_MES_FICHIERS_DOSSIER')) { |
||||
/** |
||||
* Repertoire de stockage des archives creees |
||||
*/ |
||||
define('_MES_FICHIERS_DOSSIER', _DIR_TMP . 'mes_fichiers/'); |
||||
} |
||||
|
||||
/** |
||||
* Renvoie la liste des fichiers et repertoires pouvant être sauvegarder. |
||||
* |
||||
* @return array |
||||
*/ |
||||
function mes_fichiers_a_sauver() { |
||||
// Dans le cas de la mutu, les fichiers de personnalisation sont places |
||||
// - soit dans le site d'un sous-domaine, il faut donc aller les chercher a la racine de ce sous-domaine |
||||
// en utilisant _DIR_SITE |
||||
// - soit dans le site principal, il faut dans ce cas utiliser _DIR_RACINE |
||||
if (defined('_DIR_SITE')) { |
||||
// C'est une mutu |
||||
$dir_site = _DIR_SITE; |
||||
} else { |
||||
$dir_site = _DIR_RACINE; |
||||
} |
||||
|
||||
// Constituer la liste des fichiers et dossiers pouvant être sauvegardés |
||||
$liste = array(); |
||||
|
||||
// Rechercher le fichier sqlite le plus récent depuis config/bases |
||||
$tmp_db = defined('_DIR_DB') ? _DIR_DB : $dir_site . 'config/bases/'; |
||||
if ($fichier_db = mes_fichiers_fichier_recent($tmp_db)) { |
||||
$liste[] = $fichier_db; |
||||
} |
||||
|
||||
// le fichier d'options si il existe |
||||
if ( |
||||
@is_readable($f = $dir_site . _NOM_PERMANENTS_INACCESSIBLES . _NOM_CONFIG . '.php') |
||||
or (!defined('_DIR_SITE') && @is_readable($f = _FILE_OPTIONS)) |
||||
) { |
||||
$liste[] = $f; |
||||
} |
||||
|
||||
// le fichier .htaccess a la racine qui peut contenir des persos |
||||
$htaccess = defined('_ACCESS_FILE_NAME') ? _DIR_RACINE . _ACCESS_FILE_NAME : _DIR_RACINE . '.htaccess'; |
||||
if (@is_readable($htaccess)) { |
||||
$liste[] = $htaccess; |
||||
} |
||||
|
||||
// le fameux repertoire des documents et images |
||||
$IMG = defined('_DIR_IMG') ? _DIR_IMG : $dir_site . 'IMG/'; |
||||
if (@is_dir($IMG)) { |
||||
$liste[] = $IMG; |
||||
} |
||||
|
||||
// le(s) dossier(s) des squelettes nommes |
||||
if (strlen($GLOBALS['dossier_squelettes'])) { |
||||
// Dans le cas d'une mutu, la globale est toujours mise à jour sous la forme sites/domaine/squelettes |
||||
// Cela revient donc au même que pour une install non mutualisée, il faut donc utiliser _DIR_RACINE |
||||
foreach (explode(':', $GLOBALS['dossier_squelettes']) as $_dir) { |
||||
$dir = ($_dir[0] == '/' ? '' : _DIR_RACINE) . $_dir . '/'; |
||||
if (@is_dir($dir)) { |
||||
$liste[] = $dir; |
||||
} |
||||
} |
||||
} elseif (@is_dir($dir_site . 'squelettes/')) { |
||||
$liste[] = $dir_site . 'squelettes/'; |
||||
} |
||||
|
||||
// le dernier fichier de dump de la base |
||||
$tmp_dump = defined('_DIR_DUMP') ? _DIR_DUMP : $dir_site . 'tmp/dump/'; |
||||
if ($fichier_dump = mes_fichiers_fichier_recent($tmp_dump)) { |
||||
$liste[] = $fichier_dump; |
||||
} |
||||
|
||||
// On ajoute via un pipeline pour déclarer des fichiers à sauvegarder provenant de plugins |
||||
// et on renvoie la liste complète sans doublons. |
||||
$liste_en_plus = pipeline('mes_fichiers_a_sauver', []); |
||||
|
||||
return array_unique(array_merge($liste, $liste_en_plus)); |
||||
} |
||||
|
||||
/** |
||||
* Renvoie un chemin de dossier le plus propre possible en gérant le cas d'un SPIP mutualisé ou non. |
||||
* |
||||
* @param string $dossier Chemin du dossier à afficher d'une manière la plus lisible. |
||||
*/ |
||||
function mes_fichiers_joli_repertoire($dossier) { |
||||
|
||||
if ( |
||||
defined('_DIR_SITE') |
||||
and preg_match(',' . _DIR_SITE . ',', $dossier) |
||||
) { |
||||
$joli_repertoire = str_replace(_DIR_SITE, '', $dossier); |
||||
} else { |
||||
$joli_repertoire = joli_repertoire($dossier); |
||||
} |
||||
|
||||
return $joli_repertoire; |
||||
} |
||||
|
||||
/** |
||||
* Calculer la taille d'un répertoire en itérant sur son contenu. |
||||
* |
||||
* @link http://aidanlister.com/repos/v/function.dirsize.php |
||||
* |
||||
* @param string $path Chemin vers le dossier concerné |
||||
* |
||||
* @return int |
||||
*/ |
||||
function mes_fichiers_dirsize($path) { |
||||
|
||||
// Par défaut, erreur ou pas, le dossier est vide |
||||
$size = 0; |
||||
|
||||
// Trailing slash |
||||
if (substr($path, -1, 1) !== DIRECTORY_SEPARATOR) { |
||||
$path .= DIRECTORY_SEPARATOR; |
||||
} |
||||
|
||||
// Sanity check |
||||
if (is_file($path)) { |
||||
$size = filesize($path); |
||||
} elseif (is_dir($path)) { |
||||
// Iterate queue |
||||
$queue = array($path); |
||||
for ($i = 0, $j = count($queue); $i < $j; ++$i) { |
||||
// Open directory |
||||
if (is_dir($queue[$i]) && $dir = @dir($queue[$i])) { |
||||
$subdirs = array(); |
||||
while (false !== ($entry = $dir->read())) { |
||||
// Skip pointers |
||||
if ($entry == '.' || $entry == '..') { |
||||
continue; |
||||
} |
||||
|
||||
// Get list of directories or filesizes |
||||
$path = $queue[$i] . $entry; |
||||
if (is_dir($path)) { |
||||
$path .= DIRECTORY_SEPARATOR; |
||||
$subdirs[] = $path; |
||||
} elseif (is_file($path)) { |
||||
$size += filesize($path); |
||||
} |
||||
} |
||||
|
||||
// Add subdirectories to start of queue |
||||
unset($queue[0]); |
||||
$queue = array_merge($subdirs, $queue); |
||||
|
||||
// Recalculate stack size |
||||
$i = -1; |
||||
$j = count($queue); |
||||
|
||||
// Clean up |
||||
$dir->close(); |
||||
unset($dir); |
||||
} |
||||
} |
||||
} |
||||
|
||||
return $size; |
||||
} |
||||
|
||||
/** |
||||
* Renvoie une taille de dossier ou de fichier humainement lisible. |
||||
* |
||||
* @link http://aidanlister.com/repos/v/function.size_readable.php |
||||
* |
||||
* @param int $size Taille en octets |
||||
* @param string $max Unité maximale |
||||
* @param string $system Système d'unités : `si` pour le système international, `bi` pour des unités binaires |
||||
* @param string $format Format de retour |
||||
* |
||||
* @return string Chaine compréhensible pour une taille de fichier ou dossier |
||||
*/ |
||||
function mes_fichiers_size_readable($size, $max = null, $system = 'si', $format = '%01.2f %s') { |
||||
|
||||
// Pick units |
||||
$systems['si']['prefix'] = array('B', 'K', 'MB', 'GB', 'TB', 'PB'); |
||||
$systems['si']['size'] = 1000; |
||||
$systems['bi']['prefix'] = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'); |
||||
$systems['bi']['size'] = 1024; |
||||
|
||||
// Système choisi |
||||
$sys = $systems[$system] ?? $systems['si']; |
||||
|
||||
// Max unit to display |
||||
$depth = count($sys['prefix']) - 1; |
||||
if ($max && false !== $d = array_search($max, $sys['prefix'])) { |
||||
$depth = $d; |
||||
} |
||||
|
||||
// Loop |
||||
$i = 0; |
||||
while ($size >= $sys['size'] && $i < $depth) { |
||||
$size /= $sys['size']; |
||||
$i++; |
||||
} |
||||
|
||||
return sprintf($format, $size, $sys['prefix'][$i]); |
||||
} |
||||
|
||||
/** |
||||
* Renvoie le fichier le plus récent d'un dossier donné. |
||||
* Le dossier ne doit contenir que des fichiers concernant le même sujet. |
||||
* |
||||
* @param $dossier |
||||
* |
||||
* @return string |
||||
*/ |
||||
function mes_fichiers_fichier_recent($dossier) { |
||||
|
||||
// Par défaut, si le dossier est vide on renvoie un nom de fichier vide |
||||
$fichier_recent = ''; |
||||
|
||||
// On considère que dans le dossier tous les fichiers concernent le même sujet, il est donc inutile |
||||
// d'utiliser un pattern pour le fichier. |
||||
include_spip('inc/flock'); |
||||
$fichiers = preg_files($dossier); |
||||
$mtime_recent = 0; |
||||
foreach ($fichiers as $_fichier) { |
||||
if (($mtime = filemtime($_fichier)) > $mtime_recent) { |
||||
$fichier_recent = $_fichier; |
||||
$mtime_recent = $mtime; |
||||
} |
||||
} |
||||
|
||||
return $fichier_recent; |
||||
} |
||||
|
||||
/** |
||||
* @param $quoi |
||||
* @param $id |
||||
* @param $options |
||||
* |
||||
* @return mixed|null |
||||
*/ |
||||
function mes_fichiers_preparer_destinataires($quoi, $id, $options) { |
||||
|
||||
// Recuperation des destinataires configurés |
||||
include_spip('inc/config'); |
||||
$mails_configures = lire_config('mes_fichiers/notif_mail', []); |
||||
if ($mails_configures) { |
||||
$mails_configures = explode(',', $mails_configures); |
||||
} |
||||
|
||||
// On ajoute systématiquement le webmestre |
||||
if (!empty($GLOBALS['meta']['email_webmaster'])) { |
||||
$mails_configures[] = $GLOBALS['meta']['email_webmaster']; |
||||
} |
||||
|
||||
// On ajoute les éventuels destinataires supplémentaires fournis par des plugins |
||||
$destinataires = pipeline( |
||||
'notifications_destinataires', |
||||
[ |
||||
'args'=> [ |
||||
'quoi'=>$quoi, |
||||
'id'=>$id, |
||||
'options'=>$options |
||||
], |
||||
'data'=> $mails_configures |
||||
] |
||||
); |
||||
|
||||
// Nettoyage de la liste d'emails en vérifiant les doublons |
||||
// et la validité des emails |
||||
notifications_nettoyer_emails($destinataires); |
||||
|
||||
return $destinataires; |
||||
} |
@ -0,0 +1,48 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
|
||||
/** |
||||
* Renvoie une taille de dossier ou de fichier humainement lisible en ajustant le format et l'unité. |
||||
* |
||||
* @param int $octets Taille d'un dossier ou fichier en octets |
||||
* @param string $systeme Système d'unité dans lequel calculer et afficher la taille lisble. Vaut `BI` (défaut) ou `SI`. |
||||
* |
||||
* @return string Taille affichée de manière humainement lisible |
||||
*/ |
||||
function mes_fichiers_afficher_taille($octets, $systeme = 'BI') { |
||||
|
||||
// Texte à afficher pour la taille |
||||
$affichage = ''; |
||||
|
||||
static $unites = ['octets', 'ko', 'mo', 'go']; |
||||
static $precisions = [0, 1, 1, 2]; |
||||
|
||||
if ($octets >= 1) { |
||||
// Déterminer le nombre d'octets représentant le kilo en fonction du système choisi |
||||
$systeme = strtolower($systeme); |
||||
if ($systeme === 'bi') { |
||||
$kilo = 1024; |
||||
$suffixe_item = "_$systeme"; |
||||
$module = 'mes_fichiers'; |
||||
} else { |
||||
$kilo = 1000; |
||||
$suffixe_item = ''; |
||||
$module = 'spip'; |
||||
} |
||||
|
||||
// Identification de la puissance en "kilo" correspondant à l'unité la plus appropriée |
||||
$puissance = floor(log($octets, $kilo)); |
||||
|
||||
// Calcul de la taille et choix de l'unité |
||||
$affichage = _T( |
||||
$module . ':taille_' . $unites[$puissance] . $suffixe_item, |
||||
[ |
||||
'taille' => round($octets / pow($kilo, $puissance), $precisions[$puissance]) |
||||
] |
||||
); |
||||
} |
||||
|
||||
return $affichage; |
||||
} |
@ -0,0 +1,35 @@
|
||||
<?php |
||||
if (!defined('_ECRIRE_INC_VERSION')) { |
||||
return; |
||||
} |
||||
function notifications_archive_mf_nettoyer_dist($quoi, $id, $options) { |
||||
|
||||
if ( |
||||
include_spip('inc/config') |
||||
and (lire_config('mes_fichiers/notif_active', 'non') === 'oui') |
||||
and is_array($options['liste']) |
||||
and !empty($options['liste']) |
||||
) { |
||||
// preparation de la liste des destinataires |
||||
$preparer_destinataires = charger_fonction('mes_fichiers_destinataires', 'inc'); |
||||
$destinataires = $preparer_destinataires($quoi, $id, $options); |
||||
|
||||
// Construction du sujet du mail |
||||
include_spip('inc/texte'); |
||||
$sujet_mail = '[' . typo($GLOBALS['meta']['nom_site']) |
||||
. '][mes_fichiers] ' |
||||
. _T('mes_fichiers:message_cleaner_sujet'); |
||||
|
||||