0

I am trying to sort all the files and folders in a directory using PHP.

I currently can get all the content of the directory (files and folder) and display them on my page.

however, there is absolutely nothing worked for me in terms of sorting the files and folders by the last uploaded/created Time and its driving me up the wall!

This is my entire code:

<?php

$folders = "";

$fileExt = "<i style='font-size:18px;' class='fa fa-folder-open'></i>";

function human_filesize($bytes, $decimals = 2) {
    $size = array('B', 'kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB');
    $factor = floor((strlen($bytes) - 1) / 3);
    return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$size[$factor];
}

$all_doc = "";
$i = 0;
$filesize = "";

$timeFile = "";
if (isset($_GET['dir']) && ($_GET['user'])) {
    $directory = $_GET['dir'];
    $Uid = $_GET['user'];

    //////WE GET THE DIRECTORIES AND FILES HERE///////////////
    $dir = "../" . $directory . "";
    $dirN = substr($dir, strpos($dir, "/") + 1);
    $files = scandir($dir);

    function newest($a, $b) {
        return (filemtime($a) > filemtime($b)) ? -1 : 1;
    }

    usort($files, "newest"); // sort the array by calling newest()

    $TIMEANDATE = date("F d Y h:i A");
    foreach ($files as $file) {
        include "../config/connect.php";
        $result = $db_conx->query("SELECT * FROM processed WHERE fileName='$file' AND userid='$Uid'");
        $row = $result->fetch_array(MYSQLI_BOTH);
        $proces = $row["proces"];
        $invoice = $row["invoice"];

        $date = filemtime('' . $dir . '/' . $file . '');


        if ($file != '.' && $file != '..') {



            $whatIWant = substr(strrchr($file, '.'), 1);



            if ($whatIWant == "jpg" || $whatIWant == "png" || $whatIWant == "gif" || $whatIWant == "JPG" || $whatIWant == "JPEG" || $whatIWant == "jpeg") {
                $fileExt = '<i style="font-size:18px;" class="fa fa-file-image-o"></i>';
            } else {
                $fileExt = "<i style='font-size:18px;' class='fa fa-folder-open'></i>";
            }
            $filesize = human_filesize(filesize('' . $dir . '/' . $file . ''));
            $key = @filemtime('' . $dir . '/' . $file . '');



            if ($whatIWant == "pdf" || $whatIWant == "docx" || $whatIWant == "xlsx" || $whatIWant == "xls" || $whatIWant == "zip" || $whatIWant == "doc" || $whatIWant == "jpg" || $whatIWant == "png" || $whatIWant == "gif" || $whatIWant == "txt" || $whatIWant == "psd") {


                $timeFile = "" . $dir . "/" . $file . "";
                if ($proces == 'yes') {
                    $all_doc .= "<tr>
                        <td><input  type='checkbox'/></td>
                        <td>" . $fileExt . "&nbsp;<a class='defaults'  href='" . $dir . "/" . $file . "'>" . $file . "</a>&nbsp;&nbsp;<a href='move.php?movef=" . $dirN . "/" . $file . "&user=" . $Uid . "'><i title='Move' class='fa fa-refresh'></i></a>&nbsp;&nbsp;
    <a href='folder.php?del=" . $dirN . "/" . $file . "'><i title='Delete' class='fa fa-times'></i>
    </a></td>           


                        <td>" . $invoice . "</td>
                        <td ><a style='color:#0C0;' href='process.php?nopro=" . $file . "&user=" . $Uid . "&loc=" . $dirN . "'>Processed (Click here to un-process)</a></td>
                        <td>" . date('F d Y h:i A', $date) . "</td>
                        <td>" . $filesize . "</td>
                        </td>
                    </tr>";
                } else {
                    $all_doc .= "<tr>
                        <td><input  type='checkbox'/></td>
                        <td>" . $fileExt . "&nbsp;<a class='defaults'  href='" . $dir . "/" . $file . "'>" . $file . "</a>&nbsp;&nbsp;<a href='move.php?movef=" . $dirN . "/" . $file . "&user=" . $Uid . "'><i title='Move' class='fa fa-refresh'></i></a>&nbsp;&nbsp;
    <a href='folder.php?del=" . $dirN . "/" . $file . "'><i title='Delete' class='fa fa-times'></i>
    </a></td>           
                        <td>N/A</td>
                        <td >
                        <a style='color:#F00;' href='process.php?pro=" . $file . "&user=" . $Uid . "&loc=" . $dirN . "&gback=" . $goBack . "'>Not Processed (Click here to Process)</a>
                        <!--<form action='process.php' method='get' >
                        <input type='hidden' name='pro' value='" . $file . "' />                    
                        <input type='hidden' name='user' value='" . $Uid . "' />
                        <input type='hidden' name='loc' value='" . $dirN . "' />
                        <input class='notPro' type='submit' value='Not Processed (Click here to Process)' />
                        </form>-->
                        </td>
                        <!--<td>" . date('F d Y h:i A', $date) . "</td>-->
                        <td>" . date("F d Y H:i:s", filemtime($timeFile)) . "</td>
                        <td>" . $filesize . "</td>

                        </td>
                    </tr>";
                }
            } else {
                $all_doc .= "<tr>
                        <td><input  type='checkbox'/></td>
                        <td>" . $fileExt . "&nbsp;<a class='defaults'  href='folder.php?dir=" . $dirN . "/" . $file . "&user=" . $Uid . "'>" . $file . "</a>&nbsp;&nbsp;<a href='move.php?movef=" . $dirN . "/" . $file . "&user=" . $Uid . "'><i title='Move' class='fa fa-refresh'></i></a>&nbsp;&nbsp;
    <a href='folder.php?del=" . $dirN . "/" . $file . "'><i title='Delete' class='fa fa-times'></i>
    </a></td>

    <td>N/A</td>
                        <td></td>

                        <td>" . date('F d Y h:i A', $date) . "</td>
                        <td>" . $filesize . "</td>
                        </td>
                    </tr>";
            }
            $i++;
        }
    }
}
?>

Sorry about so many code but I have to send you all of it so you know how it works!

as you can see in my code, I am trying to sort the content like so:

$dir = "../".$directory."";
$dirN = substr($dir, strpos($dir, "/") + 1);
$files = scandir($dir);

function newest($a, $b)
{
    return (filemtime($a) > filemtime($b)) ? -1 : 1;
}



usort($files, "newest"); // sort the array by calling newest()

but the output of the files and folders is all over the place. Please view the attached image to see how it displays the files and folders at the moment:

enter image description here

Could someone please advise on this issue?

any help would be appreciated.

EDIT: This question is not sorting by Date. i need to sort the files by TIME.

Peter
  • 16,453
  • 8
  • 51
  • 77
H.HISTORY
  • 520
  • 9
  • 28
  • possible duplicate of [sort files by date in PHP](http://stackoverflow.com/questions/2667065/sort-files-by-date-in-php) – Jeff Sloyer Apr 30 '15 at 10:09
  • @JeffSloyer, no, its not I'm afraid. this question clearly asking sorting by `TIME` and not `Date`! however I have looked at that post before I posted mine any way. – H.HISTORY Apr 30 '15 at 10:11
  • @JeffSloyer, Date and Time are the same thing?!? where did you get that from? and no its not duplicated! – H.HISTORY Apr 30 '15 at 10:17
  • this is offtopic but you connect to DB on each `foreach` iteration, you probably want to take `include "../config/connect.php";` out of the loop – Peter Apr 30 '15 at 10:18
  • 1
    I haven't review all your code, but the compare function 'newest' is incorrect. It should return 0 if the times are equal. – GolezTrol Apr 30 '15 at 10:19
  • @Peter, good eyes mate.. yes, i will take it out. I totally missed that. thanks – H.HISTORY Apr 30 '15 at 10:20
  • You're susceptible to sql-injection. Use prepared statements! – Yoshi Apr 30 '15 at 10:21
  • @Yoshi, sure will do, but lets stay on the topic please. – H.HISTORY Apr 30 '15 at 10:22
  • Problem is, maybe someday in the future, some other novice reader, will copy your code for whatever reason, whitout knowing or realizing that it's problematic. – Yoshi Apr 30 '15 at 10:24
  • @Yoshi, well if someone copy/paste codes from internet to build a site or application then they deserve to be subjected to hacking and their website should get hacked to teach them a lesson... :) – H.HISTORY Apr 30 '15 at 10:40
  • Aren't you doing the exact same thing by asking a question on this site? But we don't need to push this any further, I stated my point, and we can leave it at that. – Yoshi Apr 30 '15 at 10:44
  • @Yoshi, no, I am actually doing the opposite – H.HISTORY Apr 30 '15 at 10:46

1 Answers1

1

In your for loop, you get the file time by using

$date = filemtime('' . $dir . '/' . $file . '');

In this code, $file is the file name from the array.

The usort function that ran first, works on the $files array, and uses its bare values. So apparently that array doesn't contain the directory names. So most likely, the call to filemtime inside your newest function will fail and return false all the time. So the return value is never useful.

A better approach would be to construct an array that contains the full file paths. That array can then more easily be used for sorting and to do the other processing.

Alternatively, you could create a nested array or an array of objects, where each item contains the file name, path, file date and maybe other information. That way, you can easily separate the process of constructing the array, sorting it, and outputting the information. Sorting and outputting can use the information in the object, so you don't have to read the file dates from disk multiple times.

<?php
$dir = 'c:\\test\\'; // Or whatever you get your dir from..

$filenames = scandir($dir);
$files = array();

// Build an array with all the meta information you need.
// In this case, I use a nested array (array of arrays),
// but you could as well use objects too.
foreach ($filenames as $filename) {

  $fullpath = $dir . $filename;

  $file = array(
    'filename' => $filename,
    'fullpath' => $fullpath,
    'filedatetime' => filemtime($fullpath)
  );
  $files[] = $file;
}

// Sort the array. Note you can use an inline (anonymous) callback
// function if you have a modern version of PHP.
usort($files, function($file1, $file2) {
  return $file1['filedatetime'] - $file2['filedatetime'];
});

// Output a table of file information by iterating over the enriched 
// files array. In this stage all the info is there, and you don't need 
// to call any file I/O functions.
?>
<table>
  <tr><th>File</th><th>Time</th><th>Path</th></tr>

<?php
foreach ($files as $file) { ?>
  <tr>
    <td><?php echo $file['filename']; ?></td>  
    <td><?php echo date('c', $file['filedatetime']) ?></td>
    <td><?php echo $file['fullpath']; ?></td>
  </tr>
<?php } ?>

</table>

<?php
GolezTrol
  • 114,394
  • 18
  • 182
  • 210
  • is it possible to do this using php.ini or .htaccess? – H.HISTORY Apr 30 '15 at 10:55
  • @H.HISTORY I don't see how my answer could be implemented in either. But maybe I'm missing the point. – GolezTrol Apr 30 '15 at 11:53
  • no, ur not missing the point.. What i meant was, is it possible to sort files/folders using php.ini instead of PHP because I am at my wits end with trying and not being able to make it work with PHP? – H.HISTORY Apr 30 '15 at 14:44
  • You mean, changing the behavior of scandir? No, I don't think that's possible with php.ini. – GolezTrol Apr 30 '15 at 17:30