From bbe8e0d95eb9dc17159c8134436c70d684ade0e9 Mon Sep 17 00:00:00 2001
From: Fil <fil@rezo.net>
Date: Fri, 10 Feb 2006 19:52:23 +0000
Subject: [PATCH] =?UTF-8?q?retour=20des=20sous-r=C3=A9pertoires=20"plats"?=
 =?UTF-8?q?=20(pour=20le=20bug=20d'Arno*)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

à tester :
- les stats
- l'upload de logos
- l'upload de documents
- le cache
---
 ecrire/exec_spip_action_joindre.php |  2 +-
 ecrire/exec_tidy.php                |  2 +-
 ecrire/inc_distant.php              |  4 +-
 ecrire/inc_documents.php            | 29 +---------
 ecrire/inc_filtres.php              |  2 +-
 ecrire/inc_flock.php                | 88 ++++++++++++++++++++++++++---
 ecrire/inc_getdocument.php          |  2 +-
 ecrire/inc_index.php                |  4 +-
 ecrire/inc_logos.php                |  8 +--
 ecrire/inc_visites.php              | 49 +++++-----------
 inc-cache.php3                      | 19 +++----
 inc-stats.php3                      | 27 +++------
 12 files changed, 122 insertions(+), 114 deletions(-)

diff --git a/ecrire/exec_spip_action_joindre.php b/ecrire/exec_spip_action_joindre.php
index d4a3007f62..66ff61566b 100644
--- a/ecrire/exec_spip_action_joindre.php
+++ b/ecrire/exec_spip_action_joindre.php
@@ -107,7 +107,7 @@ function spip_action_joindre3($arg, $mode, $type, $id, $id_document,$hash, $id_a
 	else {
 	  include_ecrire('inc_documents');
 	  $files = array();
-	  foreach (fichiers_upload($upload) as $fichier) {
+	  foreach (preg_files($upload) as $fichier) {
 			$files[]= array (
 					'name' => basename($fichier),
 					'tmp_name' => $fichier
diff --git a/ecrire/exec_tidy.php b/ecrire/exec_tidy.php
index 6a2a4170e7..17e47e8a9c 100644
--- a/ecrire/exec_tidy.php
+++ b/ecrire/exec_tidy.php
@@ -113,7 +113,7 @@ function traite_xhtml ($buffer) {
 
 		list($buffer, $les_echap) = echappe_xhtml($buffer); # math et textarea
 
-		$cache = _DIR_CACHE.creer_repertoire(_DIR_CACHE,'tidy');
+		$cache = sous_repertoire(_DIR_CACHE,'tidy');
 		$nomfich = $cache.'tidy'.md5($buffer);
 		if (!file_exists($nomfich)) {
 			define ('_calcul_tidy', 1);
diff --git a/ecrire/inc_distant.php b/ecrire/inc_distant.php
index b1d2db3c42..bbc2d4a8f3 100644
--- a/ecrire/inc_distant.php
+++ b/ecrire/inc_distant.php
@@ -187,8 +187,8 @@ function recuperer_page($url, $munge_charset=false, $get_headers=false, $taille_
 // mais la tout de suite je ne trouve pas l'idee, etant donne les limitations
 // des filesystems
 function nom_fichier_copie_locale($source, $extension) {
-	$dir = _DIR_IMG. creer_repertoire(_DIR_IMG, 'distant'); # IMG/distant/
-	$dir2 = $dir . creer_repertoire($dir, $extension); 		# IMG/distant/pdf/
+	$dir = sous_repertoire(_DIR_IMG, 'distant'); # IMG/distant/
+	$dir2 = sous_repertoire($dir, $extension); 		# IMG/distant/pdf/
 	return $dir2 . substr(basename($source).'-'.md5($source),0,12).
 		substr(md5($source),0,4).'.'.$extension;
 }
diff --git a/ecrire/inc_documents.php b/ecrire/inc_documents.php
index 43c39b0d1e..7aa87acca6 100644
--- a/ecrire/inc_documents.php
+++ b/ecrire/inc_documents.php
@@ -430,39 +430,12 @@ function inserer_documents($letexte) {
 }
 
 
-//
-// Parcourt recursivement le repertoire upload/ (ou tout autre repertoire, d'ailleurs)
-//
-function fichiers_upload($dir) {
-	$fichiers = array();
-
-	if (@is_dir($dir) AND is_readable($dir)) {
-		$d = opendir($dir);
-		while (($f = readdir($d)) !== false) {
-			if (($f[0] != '.') AND is_readable("$dir/$f"))
-				if (is_file("$dir/$f") 
-				AND $f != 'remove.txt')
-					$fichiers[] = "$dir/$f";
-			else if (is_dir("$dir/$f"))
-				$fichiers = array_merge($fichiers, fichiers_upload("$dir/$f"));
-
-		}
-		closedir($d);
-
-		sort($fichiers);
-	}
-	else
-		spip_log("repertoire $dir absent ou illisible");
-
-	return $fichiers;
-}
-
 //
 // Retourner le code HTML d'utilisation de fichiers uploades a la main
 //
 
 function texte_upload_manuel($dir, $inclus = '') {
-	$fichiers = fichiers_upload($dir);
+	$fichiers = preg_files($dir);
 	$exts = array();
 	$dirs = array();
 	foreach ($fichiers as $f) {
diff --git a/ecrire/inc_filtres.php b/ecrire/inc_filtres.php
index 07851210a5..30c237a7ec 100644
--- a/ecrire/inc_filtres.php
+++ b/ecrire/inc_filtres.php
@@ -1969,7 +1969,7 @@ function image_typo() {
 
 	$string = "$text-$taille-$couleur-$fond-$ombre-$ombrex-$ombrey-$align-$police-$largeur";
 	$query = md5($string);
-	$dossier = _DIR_IMG. creer_repertoire(_DIR_IMG, 'cache-texte');
+	$dossier = sous_repertoire(_DIR_IMG, 'cache-texte');
 	$fichier = "$dossier$query.png";
 
 	$flag_gd_typo = function_exists("imageftbbox")
diff --git a/ecrire/inc_flock.php b/ecrire/inc_flock.php
index 98e7b5d458..ac3550533d 100644
--- a/ecrire/inc_flock.php
+++ b/ecrire/inc_flock.php
@@ -133,25 +133,95 @@ function supprimer_fichier($fichier) {
 
 
 //
-// Retourne $subdir/ si le sous-repertoire peut etre cree, '' sinon
+// Retourne $base/${subdir}/ si le sous-repertoire peut etre cree,
+// $base/${subdir}_ sinon ; le flag $nobase signale qu'on ne veut pas de $base/
 //
-function creer_repertoire($base, $subdir) {
+function sous_repertoire($base, $subdir, $nobase = false) {
+	$base = str_replace("//", "/", "$base/");
+	$baseaff = $nobase ? '' : $base;
+
+	if (!strlen($subdir)) return $baseaff;
+
+	$subdir = str_replace("/", "", "$subdir");
+
+	if (@file_exists("$base${subdir}.plat"))
+		return "$baseaff${subdir}_";; 
+
 	$path = $base.'/'.$subdir;
-	if (@is_dir($path)) return "$subdir/";
+	if (@file_exists("$path/.ok"))
+		return "$baseaff$subdir/";
 
 	@mkdir($path, 0777);
 	@chmod($path, 0777);
+
 	$ok = false;
-	if ($f = @fopen("$path/.test", "w")) {
+	if ($f = @fopen("$path/dir_test.php", "w")) {
 		@fputs($f, '<'.'?php $ok = true; ?'.'>');
 		@fclose($f);
-		include("$path/.test");
-		@unlink("$path/.test");
+		@include("$path/dir_test.php");
+		@unlink("$path/dir_test.php");
+	}
+	if ($ok) {
+		@touch ("$path/.ok");
+		spip_log("creation $base$subdir/");
+		return "$baseaff$subdir/";
+	}
+
+	$f = @fopen("$base${subdir}.plat", "w");
+	if ($f)
+		fclose($f);
+	else {
+		spip_log("echec creation $base${subdir}_");
+		redirige_par_entete(generer_url_action('test_dirs','',true));
+	}
+	spip_log("faux sous-repertoire $base${subdir}_");
+	return "$baseaff${subdir}_";
+}
+// compatibilite ascendante
+function creer_repertoire($base, $subdir) {
+	return sous_repertoire($base, $subdir, true);
+}
+
+//
+// Cette fonction parcourt recursivement le repertoire $dir, et renvoie les
+// fichiers dont le chemin verifie le pattern (preg) donne en argument.
+// En cas d'echec retourne un array() vide
+//
+// Usage: array preg_files('ecrire/data/', '[.]lock$');
+//
+// Attention, afin de conserver la compatibilite avec les repertoires '.plat'
+// si $dir = 'rep/sous_rep_' au lieu de 'rep/sous_rep/' on scanne 'rep/' et on
+// applique un pattern '^rep/sous_rep_'
+//
+function preg_files($dir, $pattern=-1 /* AUTO */ ) {
+	if ($pattern == -1)
+		$pattern = "^$dir";
+	$fichiers = array();
+	$dir = preg_replace(',/[^/]*$,', '', $dir);
+
+	if (@is_dir($dir) AND is_readable($dir) AND $d = @opendir($dir)) {
+		while (($f = readdir($d)) !== false) {
+			if ($f[0] != '.' # ignorer . .. .svn etc
+			AND $f != 'CVS'
+			AND $f != 'remove.txt'
+			AND is_readable("$dir/$f")) {
+				if (is_file("$dir/$f")) {
+					if (preg_match(",$pattern,i", "$dir/$f"))
+						$fichiers[] = "$dir/$f";
+				} else if (is_dir("$dir/$f")) {
+					$fichiers = array_merge($fichiers,
+						preg_files("$dir/$f", $pattern));
+				}
+			}
+		}
+		closedir($d);
+		sort($fichiers);
 	}
-	if ($ok) return "$subdir/";
+	else
+		spip_log("repertoire $dir absent ou illisible");
 
-	redirige_par_entete(generer_url_action('test_dirs',
-		'test_dir='.urlencode($path),true));
+	sort($fichiers);
+	return $fichiers;
 }
 
 ?>
diff --git a/ecrire/inc_getdocument.php b/ecrire/inc_getdocument.php
index 6746d167a8..e354dcc289 100644
--- a/ecrire/inc_getdocument.php
+++ b/ecrire/inc_getdocument.php
@@ -16,7 +16,7 @@ include_ecrire('inc_minipres');
 
 // Creer IMG/pdf/
 function creer_repertoire_documents($ext) {
-	$rep = _DIR_DOC . creer_repertoire(_DIR_DOC, $ext);
+	$rep = sous_repertoire(_DIR_DOC, $ext);
 
 	if (!$ext OR !$rep) {
 		spip_log("creer_repertoire_documents interdit");
diff --git a/ecrire/inc_index.php b/ecrire/inc_index.php
index 3467d75630..34eaef9927 100644
--- a/ecrire/inc_index.php
+++ b/ecrire/inc_index.php
@@ -724,9 +724,9 @@ function prepare_recherche($recherche, $primary = 'id_article', $id_table='artic
 
 	// Premier passage : chercher eventuel un cache des donnees sur le disque
 	if (!$cache[$recherche]['hash']) {
-		$dircache = _DIR_CACHE.creer_repertoire(_DIR_CACHE,'rech');
+		$dircache = sous_repertoire(_DIR_CACHE,'rech');
 		$fcache[$recherche] =
-			$dircache.'rech_'.substr(md5($recherche),0,10).'.txt';
+			$dircache . substr(md5($recherche),0,10).'.txt';
 		if (lire_fichier($fcache[$recherche], $contenu))
 			$cache[$recherche] = @unserialize($contenu);
 	}
diff --git a/ecrire/inc_logos.php b/ecrire/inc_logos.php
index 3b01c4789f..4234588ad6 100644
--- a/ecrire/inc_logos.php
+++ b/ecrire/inc_logos.php
@@ -194,12 +194,8 @@ function creer_vignette($image, $maxWidth, $maxHeight, $format, $destdir, $destf
 	// si le doc n'est pas une image, refuser
 	if (!$force AND !eregi(",$format,", ",$formats_graphiques,"))
 		return;
-	// normalement il a ete cree
-	if ($destdir) {
-	  $destdir = creer_repertoire(_DIR_IMG, $destdir);
-	} 
-	$destination = _DIR_IMG . $destdir . $destfile;
-#	spip_log("$dir $destination");
+	$destination = sous_repertoire(_DIR_IMG, $destdir) . $destfile;
+
 	// chercher un cache
 	foreach (array('gif','jpg','png') as $fmt)
 		if (@file_exists($destination.'.'.$fmt)) {
diff --git a/ecrire/inc_visites.php b/ecrire/inc_visites.php
index 22064b6e47..bdb7265771 100644
--- a/ecrire/inc_visites.php
+++ b/ecrire/inc_visites.php
@@ -28,7 +28,8 @@ function compte_fichier_visite($fichier,
 
 	$content = array();
 	if (lire_fichier($fichier, $content))
-		$content = unserialize($content);
+		$content = @unserialize($content);
+	if (!is_array($content)) return;
 
 	foreach ($content as $source => $num) {
 		list($log_type, $log_id_num, $log_referer)
@@ -62,41 +63,21 @@ function calculer_visites($t) {
 	// charger un certain nombre de fichiers de visites,
 	// et faire les calculs correspondants
 
-	// 1. Chercher les paniers datant d'au moins 30 minutes
-	$date_init = date('YmdHi', time()-30*60);
-	$paniers = array();
-	$dir = opendir(_DIR_SESSIONS);
-	while (($item = readdir($dir)) !== false) {
-		if (preg_match(',^stats_([0-9]{12})$,', $item, $regs)
-		AND $regs[1]<$date_init
-		AND is_dir(_DIR_SESSIONS.$item))
-			$paniers[] = $item;
-	}
-	closedir($dir);
+	// Traiter jusqu'a 100 sessions datant d'au moins 30 minutes
+	$sessions = preg_files(sous_repertoire(_DIR_SESSIONS, 'visites'));
 
-	// 2. Manger 100 fichiers de ces paniers (sans ordre particulier)
 	$compteur = 100;
-	$pasfini = false;
-	foreach ($paniers as $panier) {
-		spip_log("traite le panier $panier");
-		$dir = opendir(_DIR_SESSIONS.$panier);
-		while (($item = readdir($dir)) !== false) {
-			if ($compteur-- < 0) {
-				$pasfini = true;
-				break;
-			}
-			if (is_file($f = _DIR_SESSIONS.$panier.'/'.$item)) {
-				compte_fichier_visite($f,
-					$visites, $visites_a, $referers, $referers_a, $articles);
-				@unlink($f);
-			}
-		}
-		// effacer le panier, sauf si on a atteint la limite de fichiers vus
-		closedir($dir);
-		if ($pasfini)
-			break;
-		else
-			@rmdir(_DIR_SESSIONS.$panier);
+	$date_init = time()-30*60;
+
+	while ($compteur -- > 0
+	AND list(,$item) = each($sessions)) {
+		if (@filemtime($item) < $date_init) {
+			spip_log("traite la session $item");
+			compte_fichier_visite($item,
+				$visites, $visites_a, $referers, $referers_a, $articles);
+			@unlink($item);
+		} else
+			spip_log("$item pas vieux");
 	}
 
 	if (!$visites) return;
diff --git a/inc-cache.php3 b/inc-cache.php3
index 63f044c9d9..ea341e4b67 100644
--- a/inc-cache.php3
+++ b/inc-cache.php3
@@ -13,7 +13,7 @@
 if (!defined("_ECRIRE_INC_VERSION")) return;
 
 //
-// Le format souhaite : "CACHE/a/bout-d-url.md5(.gz)"
+// Le format souhaite : "a/bout-d-url.md5(.gz)"
 // Attention a modifier simultanement le sanity check de
 // la fonction retire_cache()
 //
@@ -45,8 +45,8 @@ function generer_nom_fichier_cache($contexte, $fond) {
 	$md_cache = md5($fichier_requete . $_SERVER['HTTP_HOST'] . $fond);
 	$fichier_cache .= '.'.substr($md_cache, 1, 8);
 
-	// Sous-repertoires 0...9a..f/
-	$subdir = creer_repertoire(_DIR_CACHE, substr($md_cache, 0, 1));
+	// Sous-repertoires 0...9a..f ; ne pas prendre la base _DIR_CACHE
+	$subdir = sous_repertoire(_DIR_CACHE, substr($md_cache, 0, 1), true);
 
 	include_ecrire('inc_acces');
 	verifier_htaccess(_DIR_CACHE);
@@ -270,15 +270,12 @@ function restaurer_meta_donnees ($contenu) {
 // vieux fichiers
 function nettoyer_petit_cache($prefix, $duree = 300) {
 	// determiner le repertoire a purger : 'CACHE/rech/'
-	$dircache = _DIR_CACHE . creer_repertoire(_DIR_CACHE,$prefix);
+	$dircache = sous_repertoire(_DIR_CACHE,$prefix);
 	if (spip_touch($dircache.'purger_'.$prefix, $duree, true)) {
-		if ($h = @opendir($dircache)) {
-			while (($f = @readdir($h)) !== false) {
-				if (preg_match(',^'.$prefix.'_,', $f)
-				AND time() - filemtime("$dircache$f") > $duree) {
-					@unlink("$dircache$f");
-					@unlink("$dircache$f.err"); # pour tidy
-				}
+		foreach (preg_files("$dircache$prefix") as $f) {
+			if (time() - filemtime($f) > $duree) {
+				@unlink($f);
+				@unlink("$f.err"); # pour tidy
 			}
 		}
 	}
diff --git a/inc-stats.php3 b/inc-stats.php3
index 9cc115a589..76cfb7939a 100644
--- a/inc-stats.php3
+++ b/inc-stats.php3
@@ -65,31 +65,22 @@ function ecrire_stats() {
 	}
 
 	//
-	// stockage sous forme de fichier ecrire/data/stats_200511161005/client_id
+	// stockage sous forme de fichier ecrire/data/stats/client_id
 	//
 
-	// 1. Chercher dans les paniers recents (moins de 30 minutes) s'il existe
-	// deja une session pour ce numero IP. Chaque panier couvre 5 minutes
+	// 1. Chercher s'il existe deja une session pour ce numero IP.
 	$content = array();
-	for ($i = -5; $i <= 0; $i++) {
-		$panier = date('YmdHi', (intval(time()/300)+$i)*300);
-		if (@file_exists($s = _DIR_SESSIONS.'stats_'.$panier.'/'.$client_id)) {
-			lire_fichier($s, $content);
-			$content = @unserialize($content);
-			if ($i<0) @unlink($s);
-			break;
-		}
-	}
-
-	// 2. Determiner le fichier session dans le panier actuel
-	$panier = date('YmdHi', (intval(time()/300))*300);
-	$dir = _DIR_SESSIONS.creer_repertoire(_DIR_SESSIONS,'stats_'.$panier);
+	$session = sous_repertoire(_DIR_SESSIONS, 'visites') . $client_id;
+	if (@file_exists($session)
+	AND lire_fichier($session, $content))
+		$content = @unserialize($content);
 
-	// 3. Plafonner le nombre de hits pris en compte pour un IP (robots etc.)
+	// 2. Plafonner le nombre de hits pris en compte pour un IP (robots etc.)
+	// et ecrire la session
 	if (count($content) < 200) {
 		$entree = trim("$log_type\t$log_id_num\t$log_referer");
 		$content[$entree] ++;
-		ecrire_fichier($s, serialize($content));
+		ecrire_fichier($session, serialize($content));
 	}
 }
 
-- 
GitLab