<?php

 /**
  * Verzeichnisklasse zum Auslesen von Dateien
  *
  * Klasse zum rekursiven Auslesen von Dateien, ausgehend von einem Startordner
  * Das Ergebnis wird in ein Array geschrieben mit den folgenden Informationen:
  * - Pfad
  * - Dateiname
  * - Dateigröße
  * - Datum der letzten Änderung (UNIX-Timestamp)
  * Optionen:
  * - Festlegen des Startverzeichnisses
  * - Ordner vorgeben, die nicht ausgelesen werden sollen
  * - Festlegen von Dateitypen, die nicht erfaßt werden sollen
  * - Angabe über spezielle Dateien, die nicht erfaßt werden sollen
  * Vorgaben
  * - kann derzeit nur von einer anderen Klasse zur Verarbeitung genutzt werden (siehe protected function)
  * - alternativ sollten alle Methoden mit der Sichtbarkeit protected auf public gesetztz werden
  *
  * Systemvorrausetzungen
  * - PHP 5.1 oder höher
  *    
  * Benötigte Dateien
  * - Dir.class.php
  * - DirExceptions.class.php
  * 
  * Lizenz: MIT License 
  *  
  * @package  Suchfunktion und Google-Sitemap
  * @author   Peter Kropff <mail@peterkropff.de>
  * @license  http://de.wikipedia.org/wiki/MIT-Lizenz
  * @version  1.0
  *
  * Benutzung (Beispiel)
  * meineKlasse.class.php
  *
  * require_once (Dir.class.php);
  * class meineKlasse extends Dir
  * {
  *   $root = $_SERVER['DOCUMENT_ROOT'].'/folder';
  *   $filetype = array ('.php','.htm');
  *   $deny_folder = array ('bla', 'blubb', 'blubber');
  *   $deny_files = array ('db.php', 'print.php', 'google123456789.html');    
  *   $this -> setRoot ($root);
  *   $this -> denyFolder ($folder);
  *   $this -> denyFiletype ($filetype);  
  *   $this -> denySpecialFiles ($files);      
  *   $result = $this -> startSearch();  
  * }
  *
  * Anmerkung:
  * die folgenden Methoden müssen nicht aufgerufen werden, wenn keine Einschränkungen benötigt werden
  * - $this -> denyFolder ($folder);
  * - $this -> denyFiletype ($filetype);  
  * - $this -> denySpecialFiles ($files);  
  * 
  */
  
 /**
  * Exception-Klasse für Fehler einbinden
  */
  require_once ('DirExceptions.class.php');
 
 /**
  * Die Verzeichnisklasse
  */
  class Dir 
  {
   /**
    * Startverzeichnis
    * @var string
    * @access private
    */
    private $root;
    
   /**
    * Ordner von der Erfassung ausklammern
    * @var array
    * @access private
    */
    private $deny = array ();
    
   /**
    * Bestimmte Dateitypen ausklammern
    * @var array
    * @access private
    */
    private $filetype = array ();        
    
   /**
    * Spezielle Dateien ausklammern
    * @var array
    * @access private
    */
    private $special_files = array (); 
    
   /**
    * Das Ergebnis als Array
    * @var array
    * @access private
    */
    private $files = array ();
    
   /**
    * Festlegen des Startverzeichnisses
    * Überprüfung auf existierenden Startordner
    */
    protected function setRoot($var) 
    {
      if (is_dir ($var)) 
      {
        $this -> root $var;
      }
      else 
      {
       /**
        * Wenn Startordner nicht vorhanden ist, dann die 
        * entsprechende Exception-Meldung ausgeben
        */
        throw new fatalerror_exception ('Der Ordner '.$var.' ist nicht vorhanden!');
      }
    }

   /**
    * Festlegen der nicht zu erfassenden Ordner
    * Wenn $var kein Array, dann Fehlermeldung über Type Hinting
    */
    protected function denyFolder(array $var) 
    {
      $this -> deny $var;
    }

   /**
    * Festlegen der erlaubten Dateitypen
    * Wenn $var kein Array, dann Fehlermeldung über Type Hinting
    */
    protected function denyFiletype(array $var) 
    {
      $this -> filetype $var;
    }
      
   /**
    * Festlegen der speziell verbotenenen Dateien
    * Wenn $var kein Array, dann Fehlermeldung über Type Hinting
    */
    protected function denySpecialFiles(array $var) 
    {
      $this -> special_files $var;
    }
      
   /**
    * Suche starten, gibt im Erfolgsfall $files als Array zurück
    * mit folgenden Schlüsseln
    * - path
    * - file
    * - size
    * - time
    */
    protected function startSearch() 
    {
     /**
      * Aufruf der Hauptmethode doNavigate zum Einlesen der Dateien
      */
      $this -> doNavigate();
      if ($this -> files) 
      {
       /**
        * Gibt im Erfolgsfall das Ergebnis als Array zurück
        */
        return $this -> files;                
      }
      else 
      {
       /**
        * Gibt Fehlermeldung aus, wenn keine Dateien erfaßt wurden
        */
        throw new fatalerror_exception ('Keine Daten vorhanden'0);
      }
    }
      
   /**
    * rekursive Hauptmethode zum Einlesen von Dateien
    */
    private function doNavigate() 
    {
     /**
      * "temporäres" Array zum späteren sortieren
      */
      $sort = array ();

     /**
      * Wenn Verzeichnis existiert
      */
      if ($handle opendir ($this -> root)) 
      {
       /**
        * Ordern und Dateien im "temopäres" Array $sort einlesen
        */
        while ($found readdir ($handle))
        {
          if ($found != '.' && $found != '..') 
          {
            $sort[] = $this -> root.'/'.$found;
          }
        }
             
       /**
        * Überprüfung, ob $sort Inhalte hat
        */
        if (count ($sort) > 0) 
        {
         /**
          * natürliche Sortierung des Arrays $sort
          */
          natcasesort($sort);
          
         /**
          * Array $sort durchlaufen
          */
          foreach ($sort as $var) 
          {
           /**
            * Wenn Ordner
            */
            if (is_dir ($var)) 
            {
             /**
              * Methode für das Setzen des aktuellen Verzeichnisses aufrufen
              */
              $this -> setFolder ($var);                           
             /**
              * Rekursion, Funktion ruft sich selber auf
              */
              $this -> doNavigate();
            }
           /**
            * Wenn Datei
            */
            else if (is_file($var)) 
            {
             /**
              * Methode zum Schreiben der Informationen aufrufen
              */
              $this -> setFile ($var);  
            }
          }
        }
              
       /**
        * Verzeichnis-Handle schließen
        */
        closedir($handle);
      }
      else 
      {
         /**
          * Keine Leserechte mit entsprechender Exception
          */
          throw new fatalerror_exception ('Keine Zugriffsrechte auf '.$this -> root);
        }
      }

   /**
    * Aktuellen Ordner festlegen und überprüfen
    */
    private function setFolder($folder) 
    {
     /**
      * Methode zur Überprüfen verbotener Ordner aufrufen
      */
      if (!$this -> checkFolder($folder)) 
      {
       /**
        * Aktuellen Ordner festlegen
        */
        $this -> root $folder;
      }
    }

   /**
    * Methode zur Überprüfung der erlaubten Ordner
    */
    private function checkFolder($folder) 
    {
     /**
      * Schleife zur Überprüfung aller verbotenen Ordner
      */
      foreach ($this -> deny as $forbidden) 
      {
       /**
        * Pfad in Einzelordner zerlegen
        */
        $tmp explode ('/'$folder);
        
       /**
        * Überprüfung des aktuellen Ordners
        */
        if ($tmp[count($tmp) -1] == $forbidden) 
        {
         /**
          * wenn verboten, true zurückgeben und abbrechen
          */
          return true;
          break;
        }
      }
    }

   /**
    * Methode zur Erfassung der gewünschten Inhalte
    */
    private function setFile($file) 
    {     
    
     /**
      * Methoden zur Überprüfung der erlaubten Dateiendungen und 
      * verbotenen Dateien aufrufen
      */
      if ($this -> checkFiletype($file) && !$this -> checkSpecialFiles ($file)) 
      {
       /**
        * Dateigröße
        */
        $filesize filesize ($file);

       /**
        * letzte Änderung
        */
       $filetime filemtime ($file);

       /**
        * Position des letzen /
        */
        $mark strrpos ($file"/");
       
       /**
        * Position des letzen /
        */
        $path substr ($file0$mark);
        
       /**
        * Dateinamen ohne Pfadangabe
        */
        $file substr ($file$mark 1);
        
       /**
        * Informationen in Eigenschaft (Array) files schreiben
        */
        $this -> files[] = array (
                                  'path' => $path,
                                  'file' => $file,
                                  'size' => $filesize,
                                  'time' => $filetime
                                  );                
      }
    }

   /**
    * Methode zur Überprüfung der gewünschten Dateitypen
    */
    private function checkFiletype($file) 
    {            
     /**
      * Schleife zur Überprüfung aller erlaubten Dateien
      */
      foreach ($this -> filetype as $valid) 
      {                
       /**
        * wenn Dateiendung paßt, true zurückgeben und abbrechen
        */
        if (substr ($file, - strlen($valid)) == $valid) 
        {
          return true;
          break;
        }
      }
    }
      
   /**
    * Methode zur Überprüfung der verbotenen Dateien
    */        
    private function checkSpecialFiles($file) 
    {           
     /**
      * Schleife zur Überprüfung aller speziell verbotenten Dateien           
      */
      foreach ($this -> special_files as $invalid) 
      {       
       /**
        * Datei aus Pfad extrahieren
        */
        $tmp explode ('/'$file);
        $tmp_file $tmp[(count($tmp) - 1)];
        
       /**
        * wenn Datei verboten ist, true zurückgeben und abbrechen
        */
        if ($tmp_file == $invalid) {
          return true;
          break;
        }
      }
    }
  }

?>