Skip to content

Instantly share code, notes, and snippets.

@donquixote
Last active April 4, 2016 23:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save donquixote/898a573dab8aefd473c27c11cb4d5f14 to your computer and use it in GitHub Desktop.
Save donquixote/898a573dab8aefd473c27c11cb4d5f14 to your computer and use it in GitHub Desktop.
<?php
/**
* Recursively scans a directory and its subdirectories, to collect all files
* that end with the specified extension.
*
* The result is keyed by file basename.
*
* @param string $dir
* E.g. 'sites/all/modules'
* @param string $extension_with_dot
* Extension of files to look for, including the dot.
* E.g. '.module'
*
* @return string[]
* Format: $[$file] = $basename
* E.g. $[''modules/system/system.module'] = 'system'
*/
function _drupal_discover_files_by_path($dir, $extension_with_dot) {
$glob_pattern_suffix = '*{/,' . $extension_with_dot . '}';
$glob_flags = GLOB_NOSORT | GLOB_BRACE | GLOB_MARK | GLOB_NOESCAPE;
$extension_strlen_neg = -strlen($extension_with_dot);
$files = array();
$dirs_with_slash = array($dir . '/');
$i = 0;
while ($i >= 0) {
// glob() sometimes returns FALSE if no results are found, even
// if there is no real error.
foreach (glob($dirs_with_slash[$i--] . $glob_pattern_suffix, $glob_flags) ?: array() as $file_or_subdir_with_slash) {
if ('/' === $strrchr = strrchr($file_or_subdir_with_slash, '/')) {
$dirs_with_slash[++$i] = $file_or_subdir_with_slash;
}
else {
$files[$file_or_subdir_with_slash] = substr($strrchr, 1, $extension_strlen_neg);
}
}
}
return $files;
}
@donquixote
Copy link
Author

@donquixote
Copy link
Author

Optimized for cases where the number of matches (e.g. every *.module file) is much smaller than the overall number of files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment