Dannymh
Dannymh

Reputation: 149

How can I exclude directories using RecursiveDirectoryIterator

I have the function below. Which goes through directories and recursively searches through them to grab a random image file and then attaches that to a post. What I want to do is exclude some files from the search.

I have a comma separated list which I explode into an array, I tried using a filter but couldn't get this to work.

Current function without filter is

function swmc_get_imgs($start_dir, $ext, $exclude=array()){
$dir   = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($start_dir));
$files = array();

// Force array of extensions and make them all lower-case
if ( ! is_array($ext))
{
    $ext = (array) $ext;
}

$ext = array_unique(array_map('strtolower', $ext));

foreach($dir as $file)
{
    // Skip anything that isn't a file
    if ( ! $file->isFile())
        continue;

    // If the file has one of our desired extensions, add it to files array
    if (in_array(strtolower(pathinfo($file->getFilename(), PATHINFO_EXTENSION)), $ext)) {
        $files[] = $file->getPathname();
    }
}

return $files;
}

So the above works but can be fairly expensive still especially with a lot of directories, as such I want to exclude a list of directories stored in a comma list.

I tried the following

class SwmcOnlyFilter extends RecursiveFilterIterator {
public function accept() {
    // Accept the current item if we can recurse into it
    // or it is a value starting with "test"
    return $this->hasChildren() || !in_array($this->current(),     explode(",",get_option('swmc_image_excl')));
}
}

And then changing the first part of the swmc_get_imgs function to

$dirIterator = new RecursiveDirectoryIterator($start_dir);
$filter   = new SwmcOnlyFilter($dirIterator);
$dir   = new RecursiveIteratorIterator($filter);

However the filter doesn't jump over that directory but instead goes into it.

The directories could look like

/uploads/2009/1/2011_pic.jpg
/uploads/2011/1/john_smith.jpg

and so on.

So I may want to exclude 2011 as a directory but not exclude the image that lives in 2009 with 2011 in its title.

CLARIFICATION:

I could filter out these manually by skipping them in the foreach loop, however this still checks them and wastes memory and time. I would prefer to skip these at the time of the grab if possible.

Upvotes: 1

Views: 2083

Answers (1)

Dannymh
Dannymh

Reputation: 149

figured it out using the following

function swmc_iterate_imgs($start_dir)  {
$directory = $start_dir; 
$excludedDirs = explode(",",get_option('swmc_image_excl')); // array of subdirectory paths, relative to $directory, to exclude from search 
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($directory)); 
$fileArr = array();  // numerically indexed array with your files 
$x = -1; 
while ($it->valid()) 
{ 
    if (!$it->isDot() && !in_array($it->getSubPath(), $excludedDirs) && preg_match('/(\.(jpg|jpeg|gif|png))$/i', $it->key()) == 1) 
    { 
        $fileArr[] = $it->key(); 
    } 
    $it->next(); 
} 

return $fileArr;
}  

Upvotes: 1

Related Questions