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);