<?php
/*************************************
CLASSE DE CACHE PAR BLOC

par fablezouave
http://www.scriptsphp.net

customisé par Tetsuo

Ajout fonction test
***************************************/

class HDAcache {
	var $cachename;
	var $valid;
	var $rebuild;
	var $gc_max;

	function HDAcache($time,$zone='',$gctimemax=86400) {
		// modifier la valeur par defaut au besoin (en secondes)

		$this->rebuild = 0;
		// dur�e max du cache pour le fichier courant
		$this->valid = $time;
		// dur�e max du cache
		$this->gc_max = $gctimemax;
		// Repertoire contenant le cache
		$this->store_dir = './cache';

		$this->zone = $zone;

		// On recupere les parametre de l'url
		// puis on les classe alphabetiquement
		// enfin on recompose les parametres...

		$array_get=(is_array($_GET)) ?$_GET : array() ;
// print_r($_GET);
		if (isset($array_get['rebuild'])) {
			unset($array_get['rebuild']);
			$this->rebuild=1;
		}
		ksort($array_get);
		$array_qs = array();
		foreach( $array_get as $key => $val ) {
			array_push($array_qs, $key.'='.$val);
		}
		$sorted_query_string=implode('&',$array_qs);

		// On cr�e un identifiant unique
		// de chaque element du cache bas� sur
		// le nom du fichier et ses parametres

		$this->cachename=$this->store_dir.'/'
		.md5(basename($_SERVER['PHP_SELF'])
		.$zone.$sorted_query_string).'.cache';

		// si on a pass� rebuild en parametre d'url
		//on force ici le recalcul de la page

		if ($this->rebuild==1) HDAcache::force_cache();

		// on execute ici l'appelle du ramasse miette
		// 1 fois sur 100

		srand((double)microtime()*1000000);
		if (!rand(0,99)) HDAcache::gc();
	}

	function add_header($ftime) {
		if ( isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
			$since = strtotime( $_SERVER['HTTP_IF_MODIFIED_SINCE'] );
			if ( $since + $this->valid > time() ) {
				header('HTTP/1.x 304 Not Modified');
				exit;
			}
		}
		if ( !$this->rebuild ) {
			header("Expires: ".gmdate("D, d M Y H:i:s",time()+$this->valid/2)." GMT");  // Date d'expiration H + validit�/2
		} else {
			header("Expires: ".gmdate("D, d M Y H:i:s",time() )." GMT");  // Expire de suite ... pour garder le controle du cache
		}
		header("Last-Modified: " . gmdate("D, d M Y H:i:s", $ftime ) . " GMT");   // derniere modification
	}

	function start_cache() {

		/*
		ici on v�rifie la validit� du cache
		et soit on renvoi le contenu du cache
		soit on demarre la mise au tampon
		*/
		$file = $this->cachename;
		$Tout = time() - $this->valid;

		if ( (file_exists($file)==1) && ( filemtime($file) > $Tout ) && ( empty($_POST) ) ) {
			if (!headers_sent()) {
				$this->add_header(filemtime($file));
			}


			$fd=@fopen ($file, "rb");
			@flock($fd,1);
			echo @fread($fd,@filesize($file));
			@flock($fp,3);
			@fclose ($fd);

			readfile($this->cachename);

			echo "<!--FROMCACHE-->";

			return TRUE;
		}
		else {
			if (!headers_sent() && !$this->zone) {
				if (file_exists($file)) { $ht=filemtime($file); } else { $ht=time(); }
				$ht=time();
				$this->add_header($ht);
			}

			ob_start();
			return FALSE;
		}
	}



	function end_cache() {

		/*
		ici on recupere le tampon pour l'afficher
		et pour le stocker ds le cache
		*/
		$data_cache = ob_get_contents();


		$fp = @fopen($this->cachename, "wb+");
		if(!$fp) return FALSE;
		@flock($fp,2);

		@fputs($fp, $data_cache);

		@flock($fp,3);
		@fclose($fp);


		ob_end_flush();

		echo "<!--REBUILD-->";

		return TRUE;
	}

	function force_cache(){

		/*
		ici on supprime le fichier courant du cache
		pour forcer le recalcule de la page
		*/
		$file = $this->cachename;
		@touch($file, time()-($this->valid +1));
		if ( filemtime($file)>time()-$this->valid ) {
			HDAcache::delfile($file);
		}
		else return TRUE;
	}


	function gc() {

		/*
		Ici on a une routine de ramasse miette
		qui nettoie le contenu du cache des fichiers hors d'age
		et evite d'avoir un cache trop volumineux
		tout les fichiers dont l'age est sup�rieur a gc_max
		sont supprim�s
		*/

		$handle=opendir(dirname($this->cachename));

		while ($file = readdir($handle)) {
			$path=dirname($this->cachename).'/'.$file;
			if (
			is_file($path)
			&& filemtime($path)<time()-$this->gc_max
			&& $file!='.htaccess' ) {
				HDAcache::delfile($path);
			}
		}
		closedir($handle);
	}

	function delfile($file) {
		/*
		l� une routine qui permet l'effacement du fichier file
		sous unix puis windows
		*/
		@unlink($file);
		clearstatcache();
		if (@file_exists($file)) {
			$filesys = str_replace("/", "\\", $file);
			@system("del $filesys");
			clearstatcache();
			if (@file_exists($file)) {
				@chmod ($file, 0775);
				@unlink($file);
				@system("del $filesys");
			}
		}
		clearstatcache();
		if (@file_exists($file)) return FALSE;
		else return TRUE;
	}

}
?>
