<?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!
# Click the files to be inserted as includes. 
# Click the include button and they will be included in the order they were selected.
# The absolute paths will be changed to relative paths
#######################################################################
### load php functions for post #######################################
function absToRelPath($filePath){    /* change to relative path */
    $filePath= str_replace('\\','/',$filePath);
    if(is_file($filePath)){ /* check to see if file exists */
        $fileInput= basename($filePath); /* get include file name */  
      $dirPath = dirname($filePath). "/"; /* get include directory path */  
        $getPath= getcwd(); /* get current working directory */  
        $rootPath= str_replace('\\','/',$getPath);/* adjust to forward slashes */  
        $rootPath= $rootPath. "/";/*add forward slash for looping */  
        while($rootPath){/* loop to set path to relative */  
            $rootDir= substr($rootPath,0,strpos($rootPath,'/'));/* get root directory */
            $pathDir= substr($dirPath,0,strpos($dirPath,'/'));/* get include directory */
            if($rootDir== $pathDir){
                $dirPath= substr($dirPath,strpos($dirPath,'/')+1);
            }else{/* break when root and include paths are different */  
                break;  
            }
            $rootPath= substr($rootPath,strpos($rootPath,'/')+1);/* shorten root path to next directory level */  
        }
        if($rootPath){/* process to make relative path */
            while($rootPath){
                $rootPath= substr($rootPath,strpos($rootPath,'/')+1);  
                $relPath=    $relPath . '../';
            }
                $relPath= $relPath.$dirPath.$fileInput;/* file in higher directory */   
            }else{
                if($dirPath){
                    $relPath=     $dirPath.$fileInput;/* file in lower directory */   
                }else{
                    $relPath=    $fileInput; /* file in current directory */  
                }
                
            }
            return $relPath;
    }else{
        print "No File found <br>";
    }
}
### posts ##########################################################

if($_POST['include']){/* post for including files */
    if(!empty($_POST['selectedFiles'])){/* list of included files */
        $incArray= explode(',',$_POST['selectedFiles']);/* made post string into an array */ 
        foreach($incArray as $file){
          $fileInclude= absToRelPath($file);
            //print "fileInclude=  ". $fileInclude. "<br><br><br>";
            include $fileInclude;/* include file */
        }
    }else{ /* if there are no files error message */
        ?>
        <script language="JavaScript">
        <!--
        alert('No Files Selected!');    
        window.location.href=window.location.href;
        // -->
        </script>
        <?php
    } 
}else{
    ?>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
    <! ### load javaScript #########################################>
    <script language="JavaScript">
    <!--
    function saveVertPos(){ /* save screen position so it stays in the same position on page reload */
        var ScrollTop = document.body.scrollTop;
      if (ScrollTop == 0){
        if (window.pageYOffset){
                ScrollTop = window.pageYOffset;  
            }else{
                ScrollTop = (document.body.parentElement) ? document.body.parentElement.scrollTop : 0;  
            }
        }
        document.cookie = 'vPos' + "=" + ScrollTop;
      document.browser.submit();
    }
    
    function setVertPos(){/* reset screen position after page reload */
        var name = 'vPos';
        start = document.cookie.indexOf(name+"=");
      end = document.cookie.indexOf(";", start); /* first ; after start */
      if (end == -1) end = document.cookie.length;{ /* failed indexOf = -1 */
            var vPosValue = document.cookie.substring(start, end).split('=');
            document.documentElement.scrollTop = vPosValue[1];
        }
    }
    
    function showDir(dirId){ /* toggle directory, open or closed*/
        var dir = document.getElementById(dirId);
      if(dir.value == '>'){
            dir.value= '<';
      }else{
            dir.value= ">";
      }
        saveVertPos();
    }
    
    function levelUp(){ /* reset directory path to higher level */
        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(){ /* reset directory path to lower level */
        var dirLevel = document.getElementById('dirLevel');
        var dirLevelNew = document.getElementById('dirLevelNew');
        if (dirLevel.value > 0){
            dirLevel.value --;
            dirLevelNew.value= true;
            saveVertPos();
            document.browser.submit();
        }
    }
    
    function selectFile(fileId){/* pass file id in hidden field */
        document.getElementById('fileNum').value= fileId;
        saveVertPos();
    }
    
    // -->
    </script>
    
    <! ### load css ################################################>
    <style type="text/css">
    <!--
    body{
     cursor:text;
    }
    th{
        vertical-align:baseline;
        font-size:13pt;
        font-weight:bold;
    }
    td{
        border-width:1px;
        margin:0 auto;
        padding:5px;
        white-space:nowrap; 
      vertical-align:middle;
        text-align:left;
        color: #004d9c;
    }
    
    div.showDir{
      position:relative;
        top:0;
      left:30px;
    }
    
    input.img{
      width:18px;
        border:0;
        cursor:default;
    }
    
    input.file{
         border:0;
    }
    .btn{
        line-height:1.3em;
        width:80px;
        border:2px outset lightBlue;
        vertical-align:middle; 
        padding:0;
        margin:0;  
        color:blue;
        background-color:lightBlue;
        font-size:10pt;
        font-weight:bold;
    }
    
    tr.input td{
        padding:0;
        text-indent:5px;
    }
    div.file{
     cursor:default;
    }
    --> 
    </style>
<?php    
### load php class ################################################
    class dirTree{
        protected $tmp= array();
        protected $dirs= array();
        protected $dirLevel= array();
        protected $dirPath= array();
        protected $dirData= array();
        protected $files= array();
        protected $dirTmp;
        protected $filePath;
        protected $selectedFiles= array();
        static public $strOfSelectedFiles;
        static $fileNum;
            
        function __construct(){        
            if ($_POST['selectedFiles']){
                $this->selectedFiles= explode(',',$_POST['selectedFiles']) ;  
            }     
            if($_POST['clear']){
                foreach($this->selectedFiles as $key=>$value){
                    unset($this->selectedFiles);
                }
      }
        
        }
        
        function selectedFiles(){        
            if(!empty($_POST['fileNum'])){        
                $this->selectedFiles[]= $this->files[$_POST['fileNum']];
            }
            if(count($this->selectedFiles)> 0){
                foreach($this->selectedFiles as $file){
                    print $file. "<br>";  
                }      
              $this->strOfSelectedFiles= implode(",", $this->selectedFiles);/* make string of files for post */  
                }
        }    
            
        function pathInput($path){/* make an array of directory paths */
            $path= str_replace('\\','/',$path);
            $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['obsPath']= $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 collapses */
                if($_POST['root1']!= '<' || $_POST['dirLevelNew']== true){/* check for collapse  */
                    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 */
          $this->filePath= $dirPath;
            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){/* display files in directory */
            if($fileHandler = opendir($dirPath)){/*open handle for files*/
                while (($file = readdir($fileHandler)) !== FALSE){        
                    if(is_file($dirPath."/".$file)&& $file != "Thumbs.db"){/* select files from directory */
                        $this->fileNum++;
                        $tmp= parse_url($file);
                        $this->files[$this->fileNum]= $dirPath. "/". $file;
                        print "<div class= 'file' onClick= \"selectFile('$this->fileNum');\" >" .$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>";
        }
        function __destruct(){
        }
    }
    
    #### make dirTree class #######################################
    $dirTree = new dirTree();
    #### set working directory  ###################################
    $path= getcwd();
    $dirData= $dirTree->pathInput($path);/* set current directory path */
    #### browser display  #########################################
    ?>
    </head>
    <body  onload= 'setVertPos();' ><center>
    <form method='post' name= 'browser' id= 'browser' action= <?php $PHP_SELF;?>  >
    <table cellspacing= '0' cellpadding= '0' border= '2'>
    <tr>
        <td colspan= '4'><center>Select Files and Insert as PHP Includes</center></td>
    </tr>
    <tr>
        <td style= 'width:10%;'>Current Working directory:</td>
        <td style= 'width:40%;'><?php print $path;?> </td>
        <td colspan= '2'><center>Files for Including</center></td>
    </tr>
    <tr>
        <td>Current Path:</td>
        <td><?print  $dirData['obsPath'];?></td>
      <td colspan= '2'>&nbsp;</td>
    </tr>    
    <tr class= 'input'>
        <td> Set path:</td>
        <td>
            <input type='button' class= 'btn' value= '<<' onClick= 'levelUp()' />
          <input type='button' class= 'btn' value= '>>' onClick=  'levelDown()'/>
        </td>
        <td>Set Files</td>
      <td>
            <input type='submit' class= 'btn' name= 'include' value= 'Include' />
            <input type='submit' class= 'btn' name= 'clear' value= 'Clear' />
        </td>
    </tr>
    <tr>
        <td colspan= '2' style= 'height:500px;vertical-align:top;'>
        <?php    
        $dirTree->dirBrowser($dirData['obsPath'],$dirData['root']);/* run function for display*/    
        ?>
        </td>
        <td  colspan= '2' style= 'width:50%;vertical-align:top;'>
        <?php
        if(!$dirTree->selectedFiles()){
            print"&nbsp;";  
        }
        ?>
        </td>
    </tr>
    </table>
    <input type= 'hidden' name= 'dirLevel' id= 'dirLevel' value= <?php print $_POST["dirLevel"]?> >
    <input type= 'hidden' name= 'dirLevelCount' id= 'dirLevelCount' value= '<?php print $dirData["levelMax"];?>'>
    <input type= 'hidden' name= 'dirLevelNew' id= 'dirLevelNew'>
    <input type= 'hidden' name= 'fileNum' id= 'fileNum'>
    <input type= 'hidden' name= 'selectedFiles' value= "<?php print $dirTree->strOfSelectedFiles?>">
    </form>
    </center>
    </body>
    
    <?php
}
?>
</html>