Sorting Files and folders

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
GreggF
Forum Newbie
Posts: 4
Joined: Wed Aug 13, 2008 8:14 pm

Sorting Files and folders

Post by GreggF »

I need a little help. I am pretty new to PHP... how many times have you heard that.

I am using the following scritp to create a display of Folders and the files linked in them. Looks like this:

2004
- August
- March
- September
2007
- April
- October
- January
2005
- June
- Janurary
- November

There are two problems that having to do with sorting. I need to sort the Folders(years) from current to oldest (2008, 2007, 2006, 2005, etc.) Then the files(months) in monthly order. Would that be chronological? Anyway any help would be appriciated. Here is the code:

Code: Select all

<?php
            // Remove the ext
            function RemoveExtension($strName)
                {
                $ext = strrchr($strName, '.');
 
                if($ext !== false)
                {
                $strName = substr($strName, 0, -strlen($ext));
                }
                return $strName;
                } 
            
            // List folders and files
            function ListFolder($path)
            {
                //using the opendir function
                $dir_handle = @opendir($path) or die("Unable to open $path");
                
                //Leave only the lastest folder name
                $dirname = end(explode("/", $path));
                
                //display the target folder.
                echo ("<h2>$dirname</h2>\n");
                echo "<ul>\n";
                while (false !== ($file = readdir($dir_handle))) 
                {
                    if($file!="." && $file!="..")
                    {
                        if (is_dir($path."/".$file))
                        {
                            //Display a list of sub folders.
                            ListFolder($path."/".$file);
                        }
                        else
                        {
                            //Display a list of files.
                            echo "<li><a href='";
                            bloginfo('template_url'); 
                            echo "/Newsletters/$dirname/$file' target='_blank'>" . RemoveExtension($file) . "</a></li>";
                        }
                    }
                }
                echo "</ul>\n";
                
                //closing the directory
                closedir($dir_handle);
            }
            
            // Get the base folder
            $base_folder = getcwd();
            $ourDir = $base_folder . "/wp-content/themes/TA_custom/Newsletters/"; 
            
            ListFolder($ourDir);
            
            ?>
User avatar
ghurtado
Forum Contributor
Posts: 334
Joined: Wed Jul 23, 2008 12:19 pm

Re: Sorting Files and folders

Post by ghurtado »

Which line does the sorting?
GreggF
Forum Newbie
Posts: 4
Joined: Wed Aug 13, 2008 8:14 pm

Re: Sorting Files and folders

Post by GreggF »

Hi ghurtado

Thanks for the quick reply. I don't have any sorting going on... not sure where to even start with that. :banghead:
User avatar
omniuni
Forum Regular
Posts: 738
Joined: Tue Jul 15, 2008 10:50 pm
Location: Carolina, USA

Re: Sorting Files and folders

Post by omniuni »

I think these commands may come in handy for you:

is_dir() http://us.php.net/function.is-dir

isfile() http://us2.php.net/DirectoryIterator_isFile

sort() http://us2.php.net/sort

I hope some of that helps you out. If you have any further questions, just ask.

-OmniUni
GreggF
Forum Newbie
Posts: 4
Joined: Wed Aug 13, 2008 8:14 pm

Re: Sorting Files and folders

Post by GreggF »

OmniUni

I am using is_dir() to determine the Folder and then doing an else to get the files. The sort() works on arrays, I am using a loop. I don't have a good grasp on Arrays at this point. But I am wondering if I should dump the loop items (folders) into an array, the same for the files.

Is that the direction I should go? Do you have an example?

I actually think the Folders might be the easiest because it is simply one year after the other(decending). But the files, now that I'm not sure how to deal with getting them to show up as January,February,March,April,etc. The only crazy idea I have is put a number in front to sort and then strip it off to display like 1January, 2February, 3March, 4April, etc.

I really appricaite your help!
User avatar
omniuni
Forum Regular
Posts: 738
Joined: Tue Jul 15, 2008 10:50 pm
Location: Carolina, USA

Re: Sorting Files and folders

Post by omniuni »

Hi! I'm sorry, I skimmed your code a bit too hastily. Below is an example that I use to create a "file manager" type view. As such, it sorts both files and directories. You can see it in action here: http://d-site.net/stuff/ (It's a part of my website where I store random files).

You'll note that what I did is I replaced my loops instead of for display, with a loop that adds the files into an array. This array is then sorted, and looped through for display.

CODE FOR STYLEFILE:

Code: Select all

 
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 
<?php
 
/*Read Current Directory from $_GET[]*/
if(!isset($_GET['dir'])){
$cDIR = ".".substr($_GET['dir'], 1);
}else{
$cDIR = "./".substr($_GET['dir'], 1);
}
 
?>
 
<html>
<head>
    <title>StyleFile Directory List for <?php echo $cDIR; ?></title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
    <link href="http://omniimpact.com/stylefile/sf_resources/stylefile_default.css" rel="stylesheet" type="text/css">
</head>
 
<?php
 
/*Get a full list of the current directory*/
if ($directory2read = opendir($cDIR)) {
    while (false !== ($file = readdir($directory2read))) {
        $ALLFILES[] = $file;
        }
closedir($directory2read);
}
 
/*Populate an array with the directories using is_dir()*/
 
$DIRS;
foreach($ALLFILES as $maybeDIR){
    if(is_dir($cDIR."/".$maybeDIR) && $maybeDIR != "." && $maybeDIR != ".."){
        $DIRS[] = $maybeDIR;
    }
}
$DIRlist = "<ul class=\"dirlist\">\n\t
    <li style=\"background-color: silver;\">
    <a href=\"?\"><div align=\"center\">ROOT</div>
    </a></li>\n";
if($DIRS){
    sort($DIRS);
    foreach($DIRS as $DIR){
    $DIRlist = $DIRlist."\t<li><a href=\"?dir=".substr($cDIR, 1)."/$DIR\">$DIR</a></li>\n";
    }
}
$DIRlist = $DIRlist."</ul>\n";
 
 
$FILES;
foreach($ALLFILES as $maybeFILE){
    if(is_file($cDIR."/".$maybeFILE) && $maybeFILE != "index.php"){
        $FILES[] = $maybeFILE;
    }
}
$FILElist = "<ul class=\"filelist\">\n";
if($FILES){
    sort($FILES);
    foreach($FILES as $FILE){
    $FILElist = $FILElist."\t<li><a href=\"$cDIR/$FILE\"><img src=\"http://omniimpact.com/stylefile/sf_gfx/";
    /* Determine Extension */   
    $FILEext = substr($FILE, strrpos($FILE, ".")+1);
 
    /*adds an icon:
    Word processor: .doc .rtf .odt .sxw .docx .dot .ott .wps .wpf[WRD]
    Spreadsheet: .xls .xlsx .ods .sxc .csv .mw[SRD]
    Office Generic: .ppt .pptx .odp .otp .otg .pub .odf .odg .pdf[OFS]
    text: .txt .info .conf .config .nfo .sh .cfg .f90 .f95 .java .cpp .c .asm .x86 .cap .hex .dat[TXT]
    web: .css .html .xhtml .shtml .php .asp .aspx .xml .js[WEB]
    image: .jpg .jpeg .gif .png .bmp .tif .tiff .xpm .svg .psd .ai .ps .eps .xcf .cel[IMG]
    sound: .wav .mp2 .mp3 .ogg .pls .flac .aac .mp4 .wma .aup .pcm .midi .mid[SND]
    movie: .mov .mpeg .mpg .avi .wmv .ogm .swf .rm .nes[MOV]
    compressed: .zip .rar .tar .gz .7z .sitx .pk3 .pkg .deb .rpm .iso .cue .cab .run .qvm .img .vdi .qcow .cow .bak[CMX]
    watchit: .exe .db .ini .reg .lnk .sys .bin .obj .so .dll .bat .class[STP]
    default: blank graphic [---]
    */
    $EXTtype;
    $FILEext = strtolower($FILEext);
    switch($FILEext){
        case "doc":case "docx":case "dot":
        case "sxw":case "odt":case "ott":
        case "rtf":case "wps":case "wpf":
            $EXTtype = "wrd";
            break;
        case "xls":case "xlsx":case "sxc":case "ods":
        case "csv": case "mw":
            $EXTtype = "srd";
            break;
        case "ppt": case "pptx":case "pdf": case "pub": case "pot":
        case "odp": case "otp": case "odg": case "otg": case "pps":
            $EXTtype = "ofs";
            break;
        case "txt": case "info": case "conf": case "config": case "cfg": case "nfo":
        case "f90": case "f95": case "java": case "cpp": case "c": case "asm": case "x86":
        case "cap": case "hex": case "dat": case "log":
            $EXTtype = "txt";
            break;
        case "html": case "shtml": case "xhtml": case "php": case "css": case "js":
        case "asp": case "aspx": case "xml":
            $EXTtype = "web";
            break;
        case "jpg": case "gif": case "jpeg": case "png": case "bmp": case "tif": case "tiff":
        case "xpm": case "svg": case "psd": case "ai": case "ps": case "eps": case "xcf": case "cell":
            $EXTtype = "img";
            break;
        case "wav": case "mp3": case "mp2": case "mp4": case "ogg": case "flac":
        case "wma": case "aac": case "aup": case "pcm": case "midi": case "mid":
        case "pls":
            $EXTtype = "snd";
            break;
        case "mov": case "avi": case "mpg": case "mpeg": case "wmv": case "ogm":
        case "swf": case "rm": case "nes":
            $EXTtype = "mov";
            break;
        case "zip": case "rar": case "gz": case "tar": case "7z": case "sitx": case "pk3": case "deb": case "rpm": case "run":
        case "iso": case "cue": case "cab": case "qvm": case "img": case "qcow": case "vdi": case "bak": case "pkg": case "img":
            $EXTtype = "cmx";
            break;
        case "exe": case "db": case "ini": case "lnk": case "reg": case "sys": case "bin": case "obj":
        case "dll": case "so": case "obj": case "bat": case "class":
            $EXTtype = "stp";
            break;
        default: $EXTtype = "---";
    }
    
    $FILElist = $FILElist.$EXTtype.".png";
    $FILElist = $FILElist."\" border=\"0\" alt=\"icon\" style=\"margin-right: 5pt;\">$FILE</a></li>\n";
    }
}
$FILElist = $FILElist."</ul>\n";
 
?>
 
<body>
 
<div class="header">
<span id="headtitle">StyleFile Directory List v2</span><br>
<?php echo $cDIR; ?>
</div>
 
 
<div class="container">
 
<div class="directories">
<?php
echo $DIRlist;
?>
<div style="float: none; clear: both; height: 0;">&nbsp;</div>
</div>
 
<div class="files">
<?php
echo $FILElist;
?>
<div style="float: none; clear: both; height: 0;">&nbsp;</div>
</div>
 
<div style="float: none; clear: both; height: 0;">&nbsp;</div>
</div>
 
<div style="float: none; clear: both; height: 4pt;">&nbsp;</div>
 
<div class="footer">
StyleFile is &copy;2008 by Daniel S. Marcus
</div>
 
</body>
</html>
GreggF
Forum Newbie
Posts: 4
Joined: Wed Aug 13, 2008 8:14 pm

Re: Sorting Files and folders

Post by GreggF »

Thank you omniuni !

This will send me on the right track...

What did you think about the idea of placing a number in front of the file months to sort it and then strip the number off?

Good idea or bad idea?
User avatar
omniuni
Forum Regular
Posts: 738
Joined: Tue Jul 15, 2008 10:50 pm
Location: Carolina, USA

Re: Sorting Files and folders

Post by omniuni »

I would say not bad idea on the extra numbers. The directory is read, I believe, in terms of chronological creation, not any sort of ordering. Using numbers is a good idea if you need certain ones out of order, or in an alternate order. For example, if you need a user to be able to move a particular entry "up and down" in the list.

Here is an example. Let's say I want to order pages in my CMS; right now, each page is called "something.snippet" and they are displayed alphabetically. The next version will probably use ordering by way of "something.001.snippet" which will allow it to use up to 999 pages. Note, btw, the leading zeros. If you don't use them, for example, numbering months 1-12 instead of 01-12, you'll get an order 1,11,12,2,3,4,5 etc. which is, in fact, OUT of order.

In other words, you can use 01, 02, 03 to order the months. That said, I have a slightly better idea. Try using a scheme like I would use for my snippets; name the directories Name.01 Name.02. Since you're using is_dir, it won't confuse PHP, and it allows you to move them around a lot easier. The "." also gives you an easy delimiter for finding the "key" in the directory name.

PHP handles arrays truly elegantly; check out http://www.tizag.com/phpT/arrays.php for some additional info.

-OmniUni
User avatar
ghurtado
Forum Contributor
Posts: 334
Joined: Wed Jul 23, 2008 12:19 pm

Re: Sorting Files and folders

Post by ghurtado »

For what it's worth: whenever I need subdirectories ordered by date, month or year, I use the following convention: yyyymmdd ( yyyy: year, mm: month, dd:day of the month). I use this to sort photos I have taken by date. This guarantees that the folders will always be sorted by date.
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Re: Sorting Files and folders

Post by pickle »

Using glob() is much, much simpler than using opendir(), readdir() and is_dir()
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
ghurtado
Forum Contributor
Posts: 334
Joined: Wed Jul 23, 2008 12:19 pm

Re: Sorting Files and folders

Post by ghurtado »

Agreed. But it limits you to a list of filenames, so if you want to get things like filesize, you have to read those files individually.

It is much more flexible and straightforward to use the SPL:

Code: Select all

$myFiles = new DirectoryIterator($path);
foreach ($myFiles as $file) {
    echo $file->getFilename();
    echo $file->getSize();
}
Post Reply