file_scan_directory

5 file.inc file_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0)
6 file.inc file_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0)
7 file.inc file_scan_directory($dir, $mask, $options = array(), $depth = 0)
8 file.inc file_scan_directory($dir, $mask, $options = array(), $depth = 0)

Finds all files that match a given mask in a given directory.

Directories and files beginning with a period are excluded; this prevents hidden files and directories (such as SVN working directories) from being scanned.

Parameters

$dir: The base directory or URI to scan, without trailing slash.

$mask: The preg_match() regular expression of the files to find.

$options: An associative array of additional options, with the following elements:

  • 'nomask': The preg_match() regular expression of the files to ignore. Defaults to '/(\.\.?|CVS)$/'.
  • 'callback': The callback function to call for each match. There is no default callback.
  • 'recurse': When TRUE, the directory scan will recurse the entire tree starting at the provided directory. Defaults to TRUE.
  • 'key': The key to be used for the returned associative array of files. Possible values are 'uri', for the file's URI; 'filename', for the basename of the file; and 'name' for the name of the file without the extension. Defaults to 'uri'.
  • 'min_depth': Minimum depth of directories to return files from. Defaults to 0.

$depth: Current depth of recursion. This parameter is only used internally and should not be passed in.

Return value

An associative array (keyed on the chosen key) of objects with 'uri', 'filename', and 'name' members corresponding to the matching files.

Related topics

24 calls to file_scan_directory()

1 string reference to 'file_scan_directory'

File

includes/file.inc, line 2023
API for handling file uploads and server file management.

Code

function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
  // Merge in defaults.
  $options += array(
    'nomask' => '/(\.\.?|CVS)$/', 
    'callback' => 0, 
    'recurse' => TRUE, 
    'key' => 'uri', 
    'min_depth' => 0,
  );

  $options['key'] = in_array($options['key'], array('uri', 'filename', 'name')) ? $options['key'] : 'uri';
  $files = array();
  if (is_dir($dir) && $handle = opendir($dir)) {
    while (FALSE !== ($filename = readdir($handle))) {
      if (!preg_match($options['nomask'], $filename) && $filename[0] != '.') {
        $uri = "$dir/$filename";
        $uri = file_stream_wrapper_uri_normalize($uri);
        if (is_dir($uri) && $options['recurse']) {
          // Give priority to files in this folder by merging them in after any subdirectory files.
          $files = array_merge(file_scan_directory($uri, $mask, $options, $depth + 1), $files);
        }
        elseif ($depth >= $options['min_depth'] && preg_match($mask, $filename)) {
          // Always use this match over anything already set in $files with the
          // same $$options['key'].
          $file = new stdClass();
          $file->uri = $uri;
          $file->filename = $filename;
          $file->name = pathinfo($filename, PATHINFO_FILENAME);
          $key = $options['key'];
          $files[$file->$key] = $file;
          if ($options['callback']) {
            $options['callback']($uri);
          }
        }
      }
    }

    closedir($handle);
  }

  return $files;
}

Comments

uri's don't pass file_valid_uri()

The uri's that file_scan_directory returns don't pass file_valid_uri().
Which is a bit confusing...

It returns e.g. sites/all/modules/custom/imgimp/pics/test.jpg instead of a string that starts with public://

Fixed already?

The URIs I get from file_scan_directory() are in the public://old_product_images/1359b.jpg form, so it might be a bug in an earlier vresion you encountered…

absolute path?

Does the $dir parameter need to be an absolute path, a relative path, or either?

Retrieving all fiiles of a certain type

The mask can be tricking if you are not great in regular expressions.

Here is an example of retrieving all files from a directory and it's sub-directories that are PDF's.

<?php
  $dir
= "/some/dir"
 
$files = file_scan_directory($dir, '/.*\.pdf$/');
?>

The return format is

array(
  "/full/file/path/" => stdClass
    ->uri
    ->filename
    ->name
)

For the ones who would need it

After googling and inflectin Drupal in many bad ways, I've found out how to get the files within the default directory:

$files = file_scan_directory('public://fm_video', '/^.*\.(mov|mp4|avi|MOV|MP4|AVI)$/');

where fm_video must have read rights. If you would need only one file type use the '/.*\.jpg$/' like:

$files = file_scan_directory('public://fm_video', '/.*\.jpg$/');

Since regex is a realy difficult thing, I don't undestand the joke of Drupal developers to use mandatorily in a basic function. Hope this will help you further.

Login or register to post comments