1

Using previous questions about this topic I have been able to create a recursive function to display the contents of a directory in a menu however, I have run into an issue with the recursion depth when it comes to the actual file names.

When the depth of the directory increases I cannot figure out how to store/reference the parent directory path such that the href is correct.

With the below code and an example directory structure like below the file path which I'm creating for the href works for top level directories but I need a way to preserve the parent directory paths as it goes deeper in the directory structure. The link to file.html inside InnerSection for example simple generates as file/InnerSection/file.html instead of files/Section2/Innersection/file.html.

Any help would be appreciated.

Files
  Section1
  Section2
    file.html
    InnerSection
      file.html
function findDir($path){
        $dir=directory_map($path, 0);
        return $this->recursive($dir, $path);
    }

function recursive($arr, $path) {
    global $menu;
    global $current_path;
    foreach ($arr as $key => $val) {
        if (is_array($val)){
            $current_path =rtrim($key, '\\');
            $menu.= "<li data-role='collapsible' data-iconpos='right' data-shadow='false' data-corners='false'>";
            $menu.= "<h3>".rtrim($key, "\\")."</h3>";
            $menu.= "<ul data-role='listview' data-shadow='false' data-inset='true' data-corners='false'>";
            $this->recursive($val, $path);
            $menu.= "</ul></li>"; //finish directory listing
        } else {
            $menu.= "<li><a class='load-file' data-file='". $path."/".$current_path."/".$val . "' href='". $path . "/" . $current_path . "/" . "$val''>".$val."</a></li>"; //List file
        }
    }
    return $menu;
}
Radicis
  • 21
  • 2
  • wouldn't something like http://stackoverflow.com/a/2207739/208809 be much simpler? – Gordon Jan 10 '16 at 11:17
  • Thanks for the reply Gordon, To me that seems more complex if I'm honest(perhaps my understanding of it is lacking though) but it also shares a problem, like many of the others I've found online that they echo out as they go as opposed to appending to a returned variable which is essential for what I'm doing. – Radicis Jan 10 '16 at 11:36
  • I dont understand your problem then. Why is that essential? You wanrt to render a directory listing, so just echo it. store the string inside the iterator and use a method to retrieve it after iteration. Or wrap it into an output buffer. – Gordon Jan 10 '16 at 11:39
  • I'm not experienced enough to be able to comprehend your suggestion here I'm afraid. However, I can try to explain why I believe it to be essential. I have the function which returns the menu string in a base controller which I'm extending with all subsequent controllers which each need to display the contents of different directories. As such I feel like just calling a function, storing the string in a variable and then passing that variable to the view to render it on the page is the best way to approach it. – Radicis Jan 10 '16 at 11:48
  • While you can do it that way, the responsibility of a Controller is not to render HTML. What the controller could do is fetch the directory listing without any particular rendering attached, e.g. it could set a RecursiveDirectoryIterator to the View. The responsibility to render that belongs to the View, e.g. in the View, you can use the Iterator I show in that question, pass it the DirectoryIterator and render it as HTML list. See http://stackoverflow.com/questions/3563863/read-files-in-folder/3564311#3564311 – Gordon Jan 10 '16 at 12:01
  • Nothing is being rendered in the controller, merely the string is being constructed and passed to the view but perhaps that is considered rendering to your mind. I've tried to get my head around the answer you posted but as yet do not understand it to the point I can implement it. I'll keep trying and give you the answer should I succeed. I appreciate you taking the time to reply. – Radicis Jan 10 '16 at 12:09
  • well, yes. the construction of the HTML inside the controller does not belong in there. The controller should not know anything about how the data will get rendered. That's what you do in the View. – Gordon Jan 10 '16 at 12:13

1 Answers1

0

Unfortunately I was unable to get the solution posted above working.

I ended up going with a much less elegant solution. I created a helper function which I was able to call from the view so I was able to use the solutions which used echo to output the menu.

Thanks to Gordon for the input.

    function createMenu($dir) {
    if(is_dir($dir)) {
        echo "<li><a href='#'>".basename($dir)."</a><ul>";
        foreach(glob("$dir/*") as $path) {
            createMenu($path);
        }
        echo "</ul></li>";
    }
    else {
        $extension = pathinfo($dir);
        $extension = $extension['extension'];
        echo "<li><a class='load-file' data-file='$dir' href='". basename($dir, ".".$extension). "'>".basename($dir, ".".$extension)."</a></li>";
    }
}
Radicis
  • 21
  • 2