Skip to content

Commit

Permalink
Improve efficiency of findFiles
Browse files Browse the repository at this point in the history
  • Loading branch information
Rich Lott / Artful Robot committed Jul 4, 2020
1 parent 3ac647f commit ba89bdb
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 5 deletions.
25 changes: 20 additions & 5 deletions CRM/Utils/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,16 @@ public static function tempdir($prefix = 'tmp-') {
* @return array(string)
*/
public static function findFiles($dir, $pattern, $relative = FALSE) {
if (!is_dir($dir)) {
if (!is_dir($dir) || !is_readable($dir)) {
return [];
}
// Which dirs should we exclude from our searches?
// If not defined, we default to excluding any dirname that begins
// with a . which is the old behaviour and therefore excludes .git/
$excludeDirsPattern = defined('CIVICRM_EXCLUDE_DIRS_PATTERN')
? constant('CIVICRM_EXCLUDE_DIRS_PATTERN')
: '@' . preg_quote(DIRECTORY_SEPARATOR) . '\.@';

$dir = rtrim($dir, '/');
$todos = [$dir];
$result = [];
Expand All @@ -769,13 +776,21 @@ public static function findFiles($dir, $pattern, $relative = FALSE) {
}
}
}
// Find subdirs to recurse into.
if ($dh = opendir($subdir)) {
while (FALSE !== ($entry = readdir($dh))) {
$path = $subdir . DIRECTORY_SEPARATOR . $entry;
if ($entry{0} == '.') {
// ignore
}
elseif (is_dir($path)) {
// Exclude . (self) and .. (parent) to avoid infinite loop.
// Exclude configured exclude dirs.
// Exclude dirs we can't read.
// Exclude anything that's not a dir.
if (
$entry !== '.'
&& $entry !== '..'
&& (empty($excludeDirsPattern) || !preg_match($excludeDirsPattern, $path))
&& is_dir($path)
&& is_readable($path)
) {
$todos[] = $path;
}
}
Expand Down
21 changes: 21 additions & 0 deletions templates/CRM/common/civicrm.settings.php.template
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,27 @@ if (CIVICRM_UF === 'UnitTests') {
// define('CIVICRM_LOG_ROTATESIZE', 0 );
// }

/**
* Which directories should we exclude when scanning the codebase for things
* like extension .info files, or .html partials or .xml files etc. This needs
* to be a valid preg_match() pattern.
*
* If you do not define it, a pattern that excludes dirs starting with a dot is
* used, e.g. to exclude .git/). Adding suitable patterns here can vastly speed
* up your container rebuilds and cache flushes. The pattern is matched against
* the absolute path. Remember to use your system's DIRECTORY_SEPARATOR the
* examples below assume /
*
* Example: This excludes node_modules (can be huge), various CiviCRM dirs that
* are unlikely to have anything we need to scan inside, and (what could be
* your) Drupal's private file storage area.
*
* '@/(\.|node_modules|js/|css/|bower_components|packages/|vendor/|sites/default/files/private)@'
*/
// if (!defined('CIVICRM_EXCLUDE_DIRS_PATTERN')) {
// define('CIVICRM_EXCLUDE_DIRS_PATTERN', '@/\.@');
// }

/**
*
* Do not change anything below this line. Keep as is
Expand Down

0 comments on commit ba89bdb

Please sign in to comment.