I'm not sure how simple this would be, but I'm using a script which displays the files from a specific folder, however I'd like them to be displayed in alphabetical order, would it be hard to do this? Here's the code I'm using:
if ($handle = opendir($mainframe->getCfg( 'absolute_path' ) ."/images/store/")) {
while (false !== ($file = readdir($handle))) {
if ($file != "." && $file != "..") {
if (($file != "index.html")&&($file != "index.php")&&($file != "Thumbs.db")) {
$strExt = end(explode(".", $file));
if ($strExt == 'jpg') {
$Link = 'index.php?option=com_shop&task=deleteFile&file[]='.$file;
$thelist .= '<tr class="row0"><td nowrap="nowrap"><a href="'.$Link.'">'.$file.'</a></td>'."\n";
$thelist .= '<td align="center" class="order"><a href="'.$Link.'" title="delete"><img src="/administrator/images/publish_x.png" width="16" height="16" alt="delete"></a></td></tr>'."\n";
}
}
}
}
closedir($handle);
}
echo $thelist;
:)
Instead of using readdir
you could simply use scandir
(documentation) which sorts alphabetically by default.
The return value of scandir
is an array instead of a string, so your code would have to be adjusted slightly, to iterate over the array instead of checking for the final null
return value. Also, scandir
takes a string with the directory path instead of a file handle as input, the new version would look something like this:
foreach(scandir($mainframe->getCfg( 'absolute_path' ) ."/images/store/") as $file) {
// rest of the loop could remain unchanged
}
That code looks pretty messy. You can separate the directory traversing logic with the presentation. A much more concise version (in my opinion):
<?php
// Head of page
$it = new DirectoryIterator($mainframe->getCfg('absolute_path') . '/images/store/'));
foreach ($it as $file) {
if (preg_match('#\.jpe?g$#', $file->getFilename()))
$files[] = $file->getFilename();
}
sort($files);
// Further down
foreach ($files as $file)
// display links to delete file.
?>
You don't even need to worry about opening or closing the handle, and since you're checking the filename with a regular expression, you don't need any of the explode or conditional checks.
I like Glob
It makes directory reading a snap as it returns an array that's easily sortable:
<?php
$files = glob("*.txt");
sort($files);
foreach ($files as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
?>
If you're using Joomla1.5 you should be using the defined constant JPATH_BASE instead of
$mainframe->getCfg( 'absolute_path' )
If this is a Joomla extension that you will distribute, don't use scandir() as it is PHP5 only.
The best thing to do is to use the Joomla API. It has a classes for directory and file access that is layered to do this over different networks and protocols. So the file system can be over FTP for example, and the classes can be extended for any network/protocol.
jimport( 'joomla.filesystem.folder' );
$files = JFolder::files(JPATH_BASE."/images/store/");
sort($files);
foreach($files as $file) {
// do your filtering and other task
}
You can also pass a regular expression as the second parameter to JFolder::files() that filters the files you receive.
You also don't want to use URL literals like /administrator/ since they can be changed.
use the JURI methods like:
JURI::base();
If you want to make sure of the Joomla CSS classes in the tables, for:
'<tr class="row0">'
use:
'<tr class="row'.($i&1).'">'
where $i is the number of iterations. This gives you a sequence of alternating 0s and 1s.
if we have PHP built in functions, always use it, they are faster.
use glob instead of traversing folders, if it fits for your needs.
$folder_names = array();
$folder_names = glob( '*', GLOB_ONLYDIR + GLOB_MARK + GLOB_NOSORT );
- returs everything in the current directory, use chdir() before calling it
remove the GLOB_ONLYDIR to include files too ( . would be only files )
GLOB_MARK is for adding a slash to folders names
Remove GLOB_NOSORT not to sort the array