Reputation: 171
::SOLUTION::
using @RomanPerekhrest answer with a slight modification, I have what I need. This adds multiple directories to search recursively, while filtering out certain folders (in my case: "_thumbs" folders). Final code below:
$dir1 = new RecursiveDirectoryIterator("./folder01");
$dir2 = new RecursiveDirectoryIterator("./folder02");
$dir3 = new RecursiveDirectoryIterator("./folder03");
$iterators = new AppendIterator();
$filter = function ($file, $key, $iterator) {
if ($iterator->hasChildren() && $file->getFilename() != "_thumbs") {
return true;
}
return $file->isFile();
};
$iterators->append(new RecursiveIteratorIterator( $dir1 ));
$iterators->append( $dir2 );
$iterators->append(new RecursiveIteratorIterator(new RecursiveCallbackFilterIterator($dir3, $filter)));
$rgIt = new RegexIterator($iterators, "/^.+\.jpg$/i");
$files = iterator_to_array($rgIt);
::Original Question::
I'm having a tough time figuring out the RegexIterator. I'm trying to filter out a directory thats inside a parent directory that's been scanned by RecursiveIteratorIterator. In my code below, $dir3 has multiple directories, hence the RecursiveIteratorIterator, however it also has a "_thumbs" directory, which I don't want it to process. The RegexIterator currently is filtering and keeping .jpg images, but I'd like to also kill anything that was grabbed from the "_thumbs" directory.
$dir1 = new RecursiveDirectoryIterator("./folder01");
$dir2 = new RecursiveDirectoryIterator("./folder02");
$dir3 = new RecursiveDirectoryIterator("./folder03"); // <<< this dir has a _thumbs directory that I don't want to process
$iterators = new AppendIterator();
$iterators->append(new RecursiveIteratorIterator( $dir1 ));
$iterators->append( $dir2 );
$iterators->append(new RecursiveIteratorIterator( $dir3 ));
$rgIt = new RegexIterator($iterators, "/^.+\.jpg$/i"); //<<< this filters and keeps .jpg images. I don't fully understand the syntax though
$files = iterator_to_array($rgIt);
usort($files, function($a, $b){
if(filectime($a) == filectime($b)){
return 0;
}
return filectime($a) > filectime($b) ? -1 : 1;
});
$files = array_slice($files, 0 , 18);
::EDIT01::
Here's another test I tried, but also didn't get anywhere with it. Tried using RecursiveFilterIterator, but I doubt I'm using it correctly. The error I get says "Argument 1 passed to RecursiveFilterIterator::__construct() must implement interface RecursiveIterator, instance of AppendIterator given
".
$dir1 = new RecursiveDirectoryIterator("./folder01");
$dir2 = new RecursiveDirectoryIterator("./folder02");
$dir3 = new RecursiveDirectoryIterator("./folder03");
$iterators = new AppendIterator();
$iterators->append(new RecursiveIteratorIterator( $dir1 ));
$iterators->append( $dir2 );
$iterators->append(new RecursiveIteratorIterator( $dir3 ));
class DirFilter extends RecursiveFilterIterator{
public function accept(){
$excludes = "/_thumbs";
return !(in_array($this->getFilename(), $excludes));
}
}
$filterItr = new DirFilter($iterators);
$rgIt = new RegexIterator($filterItr, "/^.+\.jpg$/i");
$files = iterator_to_array($rgIt);
Upvotes: 4
Views: 705
Reputation: 92854
Use negative assertion in your regexp pattern:
...
$rgIt = new RegexIterator($iterators, "/(?!\/_thumbs\/)^.+\.jpg$/i");
$files = iterator_to_array($rgIt);
...
If the above doesn't work for you, try using RecursiveCallbackFilterIterator
to filter out "thumb" images :
$filter = function ($file, $key, $iterator) {
if ($iterator->hasChildren() && $file->getFilename() == "_thumbs") {
return true;
}
return $file->isFile();
};
...
$iterators->append( $dir2 );
$iterators->append(new RecursiveIteratorIterator(new RecursiveCallbackFilterIterator($dir3, $filter)));
...
Upvotes: 1