MemUya
MemUya

Reputation: 347

Return files in a directory between a certain date range

I have a directory with a bunch of files in it. I am able to get all the files by using the DirectoryIterator.

$files = new DirectoryIterator('/path/to/directory/');

To add to this, I can also filter which files are returned by using RegexIterator and LimitIterator.

$regex_iterator = new RegexIterator($files, '/my_regex_here/');
$limit_iterator = new LimitIterator($regex_iterator, $offset, $limit);

This works great as it only returns the files I require. Is there a way I could go about only returning files created between a certain date range similar to using the RegexIterator (which filters by matching the regex on a filename)? Think similar to an SQL query:

SELECT * FROM table WHERE created_date BETWEEN 'first_date' AND 'second_date';

I could just loop all the files from $limit_iterator and check when the file was created but I would like to avoid returning unnecessary files from the iterator class as there could potentially be a lot of files in the directory.

I also need, for the sake of pagination, the total count of files based on these filters (before using LimitIterator) so that I can have a 'next' and 'previous' page as required.

Is it possible to do what I am asking for?

Upvotes: 1

Views: 312

Answers (1)

Kevin
Kevin

Reputation: 41885

I don't think there is a built-in function that does the filtering of dates magically. You can roll up your own though.

Here's an idea via FilterIterator:

class FileDateFilter extends FilterIterator
{
    protected $from_unix;
    protected $to_unix;

    public function __construct($iterator, $from_unix, $to_unix)
    {
        parent::__construct($iterator);
        $this->from_unix = $from_unix;
        $this->to_unix = $to_unix;
    }

    public function accept()
    {
        return $this->getMTime() >= $this->from_unix && $this->getMTime() <= $this->to_unix;
    }
}

So basically accept a FROM and TO arguments like what you normally do in a query.

Just change your logic inside the accept block to your business requirements.

So when you instantiate your custom filter:

$di = new DirectoryIterator('./'); // your directory iterator object
// then use your custom filter class and feed the arguments
$files = new FileDateFilter($di, strtotime('2017-01-01'), strtotime('2018-01-01'));
$total = iterator_count($files);
foreach ($files as $file) {
    // now echo `->getFilename()` or `->getMTime()` or whatever you need to do here
}
// or do the other filtering like regex that you have and whatnot

Sidenote: You can use DateTime classes if you choose to do so.

Upvotes: 1

Related Questions