SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Mentor bronze trophy
    John_Betong's Avatar
    Join Date
    Aug 2005
    Location
    City of Angels
    Posts
    1,828
    Mentioned
    73 Post(s)
    Tagged
    6 Thread(s)

    PHP RecursiveDirectoryIterator(...) refuses to validate

    For the past couple of days I have been searching for a script to show a directory tree for use in an photo album, etc. I have yet to find one that validates without HTML errors.

    http://www.sitepoint.com/forums/show...r-and-sorting&
    I stumbled across the above source code which seems ideal and have a demo here:
    http://www.johns-jokes.com/downloads.../index-001.php


    Source code and W3.org validation links are supplied.

    I would be grateful if someone could eliminate the W3 Validation Errors.

    A word of warning, although the source code is only 25 lines a recursive function is called and makes tracing difficult.


    Perhaps this could be a competition

    PHP Code:
    $path '/downloads/sp-b';
    $path $_SERVER['DOCUMENT_ROOT'] .$path;

    function 
    isDocument($filePath)
    {
        
    $allowedTypes = array('pdf''djvu''doc''rtf');
        
    $extension substr(strtolower($filePath), (strrpos($filePath'.')+1));

        return 
    in_array($extension$allowedTypes);
    }

    function 
    recurse($it)
    {
       echo 
    '<ul>';
          for( ; 
    $it->valid(); $it->next()):
             if(
    $it->isDir() && !$it->isDot()):
               echo 
    sprintf('<li class="d">%s</li>'$it->getFileName());
               if(
    $it->hasChildren()):
                  
    $bleh $it->getChildren();
                  echo 
    '<ul>' recurse($bleh) . "</ul>\n";
               endif;

             elseif(
    $it->isFile() && isDocument($it->getPathName())):
                    
    # echo '<li class="f">'. $it->current() . ' (' . $it->getSize(). " Bytes)</li>\n";
                   
    echo 'NOT CURRENTLY USED';
             endif;
          endfor;
        echo 
    '</ul>';
    }
    recurse(new RecursiveDirectoryIterator$path )); 
    Last edited by John_Betong; Feb 24, 2014 at 04:12. Reason: spelling and formatting

  2. #2
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,127
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    This validates, but I had to change how it was implemented. Instead of echoing out the content as it runs it, it builds it into a string and you need to echo it at the call.
    PHP Code:
    $path '/downloads/sp-b';
    $path $_SERVER['DOCUMENT_ROOT'] .$path;

    function 
    isDocument($filePath)
    {
        
    $allowedTypes = array('pdf''djvu''doc''rtf');
        
    $extension substr(strtolower($filePath), (strrpos($filePath'.')+1));

        return 
    in_array($extension$allowedTypes);
    }

    function 
    recurse($it$content '')
    {
        for( ; 
    $it->valid(); $it->next()):
            if(
    $it->isDir() && !$it->isDot()):
                if (
    strlen(trim($content)) === 0)
                    
    $content '<ul>';
                
    $content .= sprintf('<li class="d">%s'$it->getFileName());

                if(
    $it->hasChildren()):
                    
    $bleh $it->getChildren();
                    
    $content .= recurse($bleh);
                endif;
                
    $content .= '</li>';
            elseif(
    $it->isFile() && isDocument($it->getPathName())):
                
    #if (strlen(trim($content)) === 0)
                #    $content = '<ul>';
                #$content .= '<li class="f">'. $it->current() . ' (' . $it->getSize(). " Bytes)</li>";
            
    endif;
        endfor;

        if (
    strlen(trim($content)) !== 0)
            
    $content .= '</ul>';
        return 
    $content;
    }

    echo 
    recurse(new RecursiveDirectoryIterator$path )); 

  3. #3
    SitePoint Mentor bronze trophy
    John_Betong's Avatar
    Join Date
    Aug 2005
    Location
    City of Angels
    Posts
    1,828
    Mentioned
    73 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by cpradio View Post
    This validates, but I had to change how it was implemented. Instead of echoing out the content as it runs it, it builds it into a string and you need to echo it at the call.
    <snip>
    Many thanks for the rather neat solution.

    I have uploaded your version and amended the menu:

    http://www.johns-jokes.com/downloads...-tree-menu.php



    Any other solutions available?

  4. #4
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,127
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    One quick adjustment, as when I took a second look, I found a redundant statement.
    PHP Code:
                    $recursiveContent recurse($bleh);
                    if (
    strlen(trim($recursiveContent)) !== 0)
                        
    $content .= $recursiveContent
    Can be simplified to
    PHP Code:
                    $content .= recurse($bleh); 
    This is only possible because of the changes I made on the recurse implementation (so it only writes output, if there is something to write). I've also updated my above post to reflect these changes.

  5. #5
    SitePoint Mentor bronze trophy
    John_Betong's Avatar
    Join Date
    Aug 2005
    Location
    City of Angels
    Posts
    1,828
    Mentioned
    73 Post(s)
    Tagged
    6 Thread(s)
    Many thanks once again,

    Updated revisions.


    Any other solutions available?

  6. #6
    SitePoint Wizard lorenw's Avatar
    Join Date
    Feb 2005
    Location
    was rainy Oregon now sunny Florida
    Posts
    1,099
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I changed things to shorten the code a bit.
    I have never gotten along with endif, prefer {}.
    I am assuming there will always be content so not checking strlen. worst case scenario, <ul></ul>
    I left everything in and commented out everything that I would remove / change.
    PHP Code:
    $path './';
    function 
    isDocument($filePath)
    {
        
    $allowedTypes = array('php''djvu''doc''rtf');
        
    $extension substr(strtolower($filePath), (strrpos($filePath'.')+1));

        return 
    in_array($extension$allowedTypes);
    }

    function 
    recurse($it$content '')
    {

      
    $content '<ul>';

        for( ; 
    $it->valid(); $it->next()){
            if(
    $it->isDir() && !$it->isDot()){
    //            if (strlen(trim($content)) === 0){
    //                }
                
    $content .= sprintf('<li class="d">%s'$it->getFileName());

                if(
    $it->hasChildren()){
    //                $bleh = $it->getChildren();
                    
    $content .= recurse($it->getChildren());
                }
                
    $content .= '</li>';
    //        elseif($it->isFile() && isDocument($it->getPathName())): // can be moved to blow the }
                #if (strlen(trim($content)) === 0)
                #    $content = '<ul>';
                #$content .= '<li class="f">'. $it->current() . ' (' . $it->getSize(). " Bytes)</li>";
            
    }
        }

    //    if (strlen(trim($content)) !== 0){
            
    $content .= '</ul>';
    //        }
        
    return $content;
    }

    echo 
    recurse(new RecursiveDirectoryIterator$path )); 
    What I lack in acuracy I make up for in misteaks

  7. #7
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,127
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lorenw View Post
    I changed things to shorten the code a bit.
    I have never gotten along with endif, prefer {}.
    I am assuming there will always be content so not checking strlen. worst case scenario, <ul></ul>
    I left everything in and commented out everything that I would remove / change.
    PHP Code:
    $path './';
    function 
    isDocument($filePath)
    {
        
    $allowedTypes = array('php''djvu''doc''rtf');
        
    $extension substr(strtolower($filePath), (strrpos($filePath'.')+1));

        return 
    in_array($extension$allowedTypes);
    }

    function 
    recurse($it$content '')
    {

      
    $content '<ul>';

        for( ; 
    $it->valid(); $it->next()){
            if(
    $it->isDir() && !$it->isDot()){
    //            if (strlen(trim($content)) === 0){
    //                }
                
    $content .= sprintf('<li class="d">%s'$it->getFileName());

                if(
    $it->hasChildren()){
    //                $bleh = $it->getChildren();
                    
    $content .= recurse($it->getChildren());
                }
                
    $content .= '</li>';
    //        elseif($it->isFile() && isDocument($it->getPathName())): // can be moved to blow the }
                #if (strlen(trim($content)) === 0)
                #    $content = '<ul>';
                #$content .= '<li class="f">'. $it->current() . ' (' . $it->getSize(). " Bytes)</li>";
            
    }
        }

    //    if (strlen(trim($content)) !== 0){
            
    $content .= '</ul>';
    //        }
        
    return $content;
    }

    echo 
    recurse(new RecursiveDirectoryIterator$path )); 
    Unfortunately, that may produce invalid markup, as you'll end up with <ul></ul> due to where you moved the <ul> statements to (hence the reason for the checks) .

    I'm also not a huge fan of the if: endif; but I was just making the existing code produce valid XHTML

  8. #8
    Hosting Team Leader silver trophybronze trophy
    cpradio's Avatar
    Join Date
    Jun 2002
    Location
    Ohio
    Posts
    5,127
    Mentioned
    152 Post(s)
    Tagged
    0 Thread(s)
    As an FYI, I verified that empty <ul></ul> does make it invalid markup. So you actually do need to have those strlen (or a similar check) checks to ensure valid markup is applied.

  9. #9
    SitePoint Wizard bronze trophy Jeff Mott's Avatar
    Join Date
    Jul 2009
    Posts
    1,266
    Mentioned
    18 Post(s)
    Tagged
    0 Thread(s)
    Are we interested in separating the concerns a bit?

    tree.php
    Code PHP:
    <?php
     
    $path = '/downloads/sp-b';
    $path = $_SERVER['DOCUMENT_ROOT'] .$path;
     
    function isDocument($filePath)
    {
        $allowedTypes = array('pdf', 'djvu', 'doc', 'rtf');
        $extension = substr(strtolower($filePath), (strrpos($filePath, '.')+1));
     
        return in_array($extension, $allowedTypes);
    }
     
    // "recurse" now echos nothing
    // it returns an associative array where each key is a file name
    // and each value is an array of children, or null if there were no children
    function recurse($it)
    {
        $contents = array();
     
        for ( ; $it->valid(); $it->next()) {
            if ($it->isDir() && !$it->isDot()) {
                if ($it->hasChildren()) {
                    $children = recurse($it->getChildren());
                }
                $contents[$it->getFileName()] = $children;
            }
            elseif ($it->isFile() && isDocument($it->getPathName())) {
                // 'NOT CURRENTLY USED';
            }
        }
     
        return $contents;
    }
     
    // "render" takes a template filename and an associative array of parameters
    // that should be available to that template, and returns the rendered output
    function render($template, $params)
    {
        extract($params);
     
        ob_start();
        require $template;
        $content = ob_get_clean();
     
        return $content;
    }
     
    echo render('recursiveDirectory.html.php', array(
        'contents' => recurse(new RecursiveDirectoryIterator( $path )))
    );

    recursiveDirectory.html.php
    Code PHP:
    <ul>
        <?php foreach ($contents as $name => $children): ?>
            <li>
                <?php echo htmlspecialchars($name) ?>
     
                <?php if ($children): ?>
                    <?php echo render('recursiveDirectory.html.php', array('contents' => $children)) ?>
                <?php endif ?>
            </li>
        <?php endforeach ?>
    </ul>
    "First make it work. Then make it better."

  10. #10
    SitePoint Mentor bronze trophy
    John_Betong's Avatar
    Join Date
    Aug 2005
    Location
    City of Angels
    Posts
    1,828
    Mentioned
    73 Post(s)
    Tagged
    6 Thread(s)
    Quote Originally Posted by Jeff Mott View Post
    Are we interested in separating the concerns a bit?

    <snip>
    Many thanks Jeff, your version has been uploaded:

    http://www.johns-jokes.com/downloads...-tree-menu.php



    Any other solutions available?


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •