Un explorateur de fichiers pour télechargement (filtrable)

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

15 avr. 2005, 12:40

Voici un programme objet que je viens de terminer, qui présente des classes permettant de parcourir un disque (ou dossier) en extraire et afficher le contenu selon des critères de selections.

Schèma logique des classes :
Un dossier est un conteneur qui contient des fichiers et/ou des dossiers.
Un lien réflexif existe entre un dossier et ses sous-dossiers, puisqu'ils sont de même nature :
. dossier X ---- N ----> dossier Y (sous-dossiers)
. dossier Y (sous-dossier) ---- 1 ----> dossier X
. dossier X ---- N ----> fichier

Un fichier n'est pas un conteneur, il se distingue d'un dossier par le fait qu'il est une terminaison.
. fichier ---- 1 ----> dossier X

Mais un fichier et un dossier sont identifiés de la même façon : un chemin + un nom + une taille ...

un dossier hérite alors des propriétés d'un fichier

Comportement :
1. A chaque construction d'un objet dossier il charge son contenu à partir d'un chemin d'accès. Toute ressource rencontrée est référencée selon son type (dossier ou fichier) dans deux listes objets (dossiers et fichiers) de l'objet dossier en cours.

2. A chaque référencement d'une ressource dans l'une ou l'autre liste il y a construction d'objet (dossier ou fichier). L'étape 1 se repéte alors dans le cas d'un dossier.

3. un dossier peut être listé selon un filtre (à propriétés variables)
Lister un dossier veut dire :
. Afficher son identité
. Afficher ses fichiers (en transmettant le filtre)
. Afficher ses sous-dossiers (même chose que 1.)

3. l'identité du dossier et du fichier peut être affichée

Pour des raisons de test l'affichage (en mode HTML) est assuré par les classes, mais cette fonctionalité peut être remplacée par un retour de contenu.

Voici le programme :
class filtre{
	var $afficher_dossiers;
	var $afficher_fichiers;
	var $afficher_chemin_complet;
	var $sur_extension;
	var $sur_nom;
	var $sur_chemin;
	var $critère;
	
	function filtre (){
		$this->afficher_dossiers = true;
		$this->afficher_fichiers = true;
		$this->afficher_chemin_complet = false;
		$this->sur_extension = false;
		$this->sur_nom = true;
		$this->critère = "*";
	}
}
class fichier {
	var $chemin;
	var $nom;
	var $type;
	var $taille;
	var $icone;
	
	function fichier($chemin){
		$this->chemin = $chemin;
		$this->type = "FICHIER"; 
		$this->taille = 0;
		$this->icone = "./images/fichier.gif";
	}
	function getExtension(){
	    $extPos = strpos($this->nom,".");
		if ($extPos !== false) return substr($this->nom,$extPos,strlen($this->nom)-$extPos+1);
		else return "";
	}
	function getTaille(){ 
	    $taille = $this->taille;
		$unité = "oct";
		if ($taille >= 1024) {
		$taille /= 1024; $unité = "Ko" ;
		} 
		if ($taille >= 1024) {
		$taille /= 1024; $unité = "Mo" ;
		} 
		if ($taille >= 1024) {
		$taille /= 1024; $unité = "Go" ;
		} 
		
		return number_format($taille, 1, ',', ' ')." ".$unité;
	}
	function afficher($filtre) {
	    //Données de l'affichage
	    $chemin = $this->chemin;
		$nom = $this->nom;
	    $taille = $this->getTaille();
		$icone = $this->icone;
		
		//Correction automatique des propriétés de filtre contradictoires
		if ($filtre != null){
			//Filtrage sur extension => fichiers doivent s'afficher
			if ($filtre->sur_extension)
				$filtre->afficher_fichiers = true;
			//Filtrage sur nom => afficher le chemin
			if ($filtre->sur_nom) {
				if (!$filtre->afficher_dossiers && !$filtre->afficher_fichiers  ){
					$this->afficher_dossiers = true;
					$this->afficher_fichiers = true;
				}
				$filtre->afficher_chemin_complet = true;
			}
		}
		//Affichage filtré
		if ( ($filtre == null
		     || ($filtre->afficher_dossiers && $this->type == "DOSSIER")
		     || ($filtre->afficher_fichiers && $this->type == "FICHIER")
		     ) && (
			 		($filtre->sur_extension && strpos($this->getExtension(),$filtre->critère)!==false)
			 		|| ($filtre->sur_nom && strpos($this->nom,$filtre->critère)!==false)
			 		|| ($filtre->critère=="*")
				)
		   ) {
		   		//Propriétés de la ressource
		  	 	if ($filtre->afficher_chemin_complet) 
			 		$description = "($this->chemin : $taille)";
		   	 	else $description = "($taille)";
		   		//Affichage
		   		echo "<p><img src=\"$icone\" align=middle width=20 heigth=10>
		   		<A href='$chemin' style='text-decoration:none'> $nom</A>  
				<font size=1>$description</font> ";
			}
	}
}
class dossier extends fichier {
	var $dossiers;
	var $fichiers;
	
	function dossier($chemin){
		$this->chemin = $chemin; 
		$this->type = "DOSSIER";
		$this->taille = 0;
		$this->icone = "./images/dossier.gif";
		$this->charger();
	}
	function charger(){
	    if ($this->chemin != null){
		 $d = dir($this->chemin);
		 if ($d != null)
		   while (($entry = $d->read())!== false) {
			if ($entry != null && !is_file($d->path ."/".$entry)){ 
			  if ($entry != "." && $entry != "..") {
			    $rang = count($this->dossiers);
				$this->dossiers [$rang] = new dossier($d->path ."/".$entry);
				$this->dossiers [$rang]->nom = $entry;
				$this->dossiers [$rang]->getTaille();
			  }
			}
			else {
			    $rang = count($this->fichiers);
				$this->fichiers [$rang] = new fichier($d->path ."/".$entry);
				$this->fichiers [$rang]->nom = $entry;
				$this->fichiers [$rang]->taille = filesize($d->path ."/".$entry);	
			}
		}
		$d->close();
	   }
	}
	function getTaille(){
	  $this->taille = 0;
	  if ($this->dossiers != null)
		 foreach ($this->dossiers as $dossier)
		 	if ($dossier != null)
		 		$this->taille += $dossier->taille;
				
	   if ($this->fichiers != null)
		 foreach ($this->fichiers as $fichier)
		 	if ($fichier != null)
		 		$this->taille += $fichier->taille;
		
	    $taille = $this->taille;
		$unité = "oct";
		if ($taille >= 1024) {
		$taille /= 1024; $unité = "Ko" ;
		} 
		if ($taille >= 1024) {
		$taille /= 1024; $unité = "Mo" ;
		} 
		if ($taille >= 1024) {
		$taille /= 1024; $unité = "Go" ;
		} 
		
		return number_format($taille, 1, ',', ' ')." ".$unité;	
	}
	function lister($filtre){
			$this->afficher($filtre);
			$this->lister_fichiers($filtre);
	    	$this->lister_dossiers($filtre);
	}
	function lister_dossiers($filtre){
		echo "<ul>";
		if ($this->dossiers != null && count($this->dossiers) >0){
		 foreach ($this->dossiers as $dossier)
		 	if ($dossier != null){
				$dossier->lister($filtre);
			}
		}
		echo "</ul>";
		
	}
	function lister_fichiers($filtre){
		echo "<ul>";
		if ($this->fichiers != null && count($this->fichiers) >0){
		 foreach ($this->fichiers as $fichier)
		 	if ($fichier != null)
		 		$fichier->afficher($filtre);
		}
		echo "</ul>";
	}
}

//Test de la classe dossier :

$racine = new dossier("a:");
$racine->nom = "Disquette A";
$filtre = new filtre();
$filtre->critère = "*";
$racine->lister($filtre);
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène