<?php
# Save the code in a text editor and save with a php extention.
# Place in the root directory and run with a browser.
# You will be able to select all levels of directories and files up the path to the root.
# How?
#    Most of the code is enclosed in a class object.
#It does use $_POST to select the directories and recursion to display #the tree.
#Using only recursion with a large tree lead to errors, stack and time outs!
?>
<! ### load javaScript #########################################>
<script language="JavaScript">
<!--
function showDir(dirId){
    var dir = document.getElementById(dirId);
  if(dir.value == '>'){
        dir.value= '<';
  }else{
        dir.value= ">";
  }
document.browser.submit();
}

function levelUp(){
    var dirLevel = document.getElementById('dirLevel');
    var dirLevelCount = document.getElementById('dirLevelCount').value;
    if (dirLevel.value < dirLevelCount -1){
        dirLevel.value ++;
        document.getElementById('dirLevelNew').value = true;
        document.browser.submit();
    }
}

function levelDown(){
    var dirLevel = document.getElementById('dirLevel');
    var dirLevelNew = document.getElementById('dirLevelNew');
    if (dirLevel.value > 0){
        dirLevel.value --;
        dirLevelNew.value= true;
        document.browser.submit();
    }
}

// -->
</script>

<! ### load css ################################################>
<style type="text/css">
<!--

div.showDir{
  position:relative;
    top:0;
  left:30px;
}

input.img{
  width:18px;
    border:0;
}
--> 
</style>
<! ### load php functions #######################################>
<?php
class dirTree{
    protected $tmp= array();
    protected $dirs= array();
    protected $dirLevel= array();
    protected $dirPath= array();
    protected $dirData= array();
    protected $dirTmp;
    
    function pathInput($path){/* make an array of directory paths and root directories */
        $this->dirs= explode("/", $path);
        $this->tmp= $this->dirs;
        $this->dirs= array_reverse($this->dirs);
        while($this->tmp){
            $this->dirTmp = implode("/",$this->tmp);
            if($this->dirTmp!= null){
                $this->dirPath[]= $this->dirTmp;
            }
        array_pop($this->tmp);
        }
        $this->dirData['root']= $this->dirs[(int)$_POST['dirLevel']];
        $this->dirData['path']= $this->dirPath[(int)$_POST['dirLevel']];
        $this->dirData['levelMax']= count($this->dirPath);
        return $this->dirData;
    }

    function dirBrowser($dirPath,$dirRoot){
        if(is_dir($dirPath)){/* check for valid directory root path */
            $this->display('root', 1, $dirRoot);/* display root directory so it colapses */
            if($_POST['root1']!= '<' || $_POST['dirLevelNew']== true){/* check for colapse  */
                print "<div class= 'showDir'>";
                $this->filesInDir($dirPath);/* display files */
                $this->dirSub($dirPath, 'base');/* display sub directories */
                print"</div>";
            }
        }else{  
        print"<br> Not a valid directory<br>";
        }
    }
        
    function dirSub($dirPath, $dirType){/* display directories */
      static $dirNum;
        if($dirHandler = opendir($dirPath)){/* make a handle for directories */
        while (($dir = readdir($dirHandler)) !== FALSE){    
                if(is_dir($dirPath."/".$dir)){{/* select directories from directorties & files */
                    if ($dir != "." && $dir != ".." ){/* remove unwanted directories */
                     $dirNum++;/* increment id for directorties */    
                        $this->display($dirType,$dirNum, $dir);
                        if($_POST[$dirType.$dirNum]=='<'&& $_POST['dirLevelNew']!= true){
                            print "<div class= 'showDir'>";
                          $filePath= $dirPath."/".$dir;/* select files from directorty */
                          $this->filesInDir($filePath);
                            if(is_dir($dirPath."/".$dir)){
                                $this->dirSub($dirPath."/".$dir, 'sub');/*recures sub directories*/ 
                            }
                            print "</div>";    
                            }
                        }
                    }
                }
            }
            closedir($dirHandler);/* close handle for files */
        }
    }
        
    function filesInDir($dirPath){
        if($fileHandler = opendir($dirPath)){
            while (($file = readdir($fileHandler)) !== FALSE){        
                if(is_file($dirPath."/".$file)&& $file != "Thumbs.db"){/* select files from directory */
                            print "<div class= 'file'>" . $file. "</div>"; 
                }
            }
            closedir($fileHandler);/*close handle for files*/
        }  
    }
    
    function display($dirType, $dirNum, $dir){
        print"<div class= 'img'>";
        print"<input type= 'readOnly' id= '$dirType$dirNum' name= '$dirType$dirNum'";
        print "class= 'img' onClick= \"showDir('$dirType$dirNum','$dirType$dirNum');\"";
        if($_POST[$dirType.$dirNum]=='<'&& $_POST['dirLevelNew']!= true){
            print "value=". $_POST[$dirType.$dirNum]. ">[ ".$dir." ]";
        }else{
            print "value= '>'>[ ".$dir." ]";    
        }
    print "</div>";
    }
}

#### make dirTree class #######################################
$dirTree = new dirTree();
#### set document root ########################################
$path=$_SERVER['DOCUMENT_ROOT'];
$dirData= $dirTree->pathInput($path);
#### browser display  #######################################>
print "<form method='post' name= 'browser' action= '$PHP_SELF';>";
print "<input type= 'hidden' name= 'dirLevel' id= 'dirLevel' value= '". $_POST['dirLevel']. "'>";
print "<input type= 'hidden' name= 'dirLevelCount' id= 'dirLevelCount' value= '". $dirData['levelMax']. "'>";
print "<input type= 'hidden' name= 'dirLevelNew' id= 'dirLevelNew'>";
print"Server Root: ". $_SERVER['DOCUMENT_ROOT']. "</br>";
print"Current Path: ". $dirData['path']. "</br>";;
print "<div style= 'float:left;'>";
print"<input type= 'button'  value= 'Up     ' onClick= 'levelUp()' >";
print"<input type= 'button'  value= 'Down' onClick= 'levelDown()' >";
$dirTree->dirBrowser($dirData['path'],$dirData['root']);/* run function */
print"</form>";
print "</div>"; 
?>