1 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)$/'. This default ignores all hidden files (those that start with a period) and items named "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
File
- core/
includes/ file.inc, line 2353 - API for handling file uploads and server file management.
Code
function file_scan_directory($dir, $mask, $options = array(), $depth = 0) {
// By default, do not check for files in common special-purpose directories.
$ignore_directories = array(
'node_modules',
'bower_components',
);
$no_mask = '/^((\..*)|' . implode('|', $ignore_directories) . ')$/';
// Merge in defaults.
$options += array(
'nomask' => $no_mask,
'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 !== '.' && $filename !== '..') {
$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;
}