diff --git a/includes/common.inc b/includes/common.inc index 633ab0f7422..f62b35d3c67 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -2074,7 +2074,7 @@ function _drupal_load_stylesheet($matches) { * Delete all cached CSS files. */ function drupal_clear_css_cache() { - file_scan_directory(file_create_path('css'), '/.*/', array('.', '..', 'CVS'), 'file_unmanaged_delete', TRUE); + file_scan_directory(file_create_path('css'), '/.*/', '/(\.\.?|CVS)$/', 'file_unmanaged_delete', TRUE); } /** @@ -2484,7 +2484,7 @@ function drupal_build_js_cache($files, $filename) { * Delete all cached JS files. */ function drupal_clear_js_cache() { - file_scan_directory(file_create_path('js'), '/.*/', array('.', '..', 'CVS'), 'file_unmanaged_delete', TRUE); + file_scan_directory(file_create_path('js'), '/.*/', '/(\.\.?|CVS)$/', 'file_unmanaged_delete', TRUE); variable_set('javascript_parsed', array()); } @@ -2855,7 +2855,7 @@ function drupal_system_listing($mask, $directory, $key = 'name', $min_depth = 1) // Get current list of items foreach ($searchdir as $dir) { - $files = array_merge($files, file_scan_directory($dir, $mask, array('.', '..', 'CVS'), 0, TRUE, $key, $min_depth)); + $files = array_merge($files, file_scan_directory($dir, $mask, '/(\.\.?|CVS)$/', 0, TRUE, $key, $min_depth)); } return $files; diff --git a/includes/file.inc b/includes/file.inc index b79525b5bcc..d79b9bd2c8c 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -1259,7 +1259,7 @@ function file_download() { * @param $mask * The preg_match() regular expression of the files to find. * @param $nomask - * An array of files/directories to ignore. + * The preg_match() regular expression of the files to ignore. * @param $callback * The callback function to call for each match. * @param $recurse @@ -1280,13 +1280,13 @@ function file_download() { * "path", "basename", and "name" members corresponding to the * matching files. */ -function file_scan_directory($dir, $mask, $nomask = array('.', '..', 'CVS'), $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0) { +function file_scan_directory($dir, $mask, $nomask = '/(\.\.?|CVS)$/', $callback = 0, $recurse = TRUE, $key = 'filename', $min_depth = 0, $depth = 0) { $key = (in_array($key, array('filename', 'basename', 'name')) ? $key : 'filename'); $files = array(); if (is_dir($dir) && $handle = opendir($dir)) { while (FALSE !== ($file = readdir($handle))) { - if (!in_array($file, $nomask) && $file[0] != '.') { + if (!preg_match($nomask, $file) && $file[0] != '.') { if (is_dir("$dir/$file") && $recurse) { // Give priority to files in this folder by merging them in after any subdirectory files. $files = array_merge(file_scan_directory("$dir/$file", $mask, $nomask, $callback, $recurse, $key, $min_depth, $depth + 1), $files); diff --git a/includes/locale.inc b/includes/locale.inc index 00db655f7f9..9eded673783 100644 --- a/includes/locale.inc +++ b/includes/locale.inc @@ -97,7 +97,7 @@ function theme_locale_languages_overview_form($form) { $header = array(array('data' => t('English name')), array('data' => t('Native name')), array('data' => t('Code')), array('data' => t('Direction')), array('data' => t('Enabled')), array('data' => t('Default')), array('data' => t('Weight')), array('data' => t('Operations'))); $output = theme('table', $header, $rows, array('id' => 'language-order')); $output .= drupal_render($form); - + drupal_add_tabledrag('language-order', 'order', 'sibling', 'language-order-weight'); return $output; @@ -2485,7 +2485,7 @@ function locale_batch_by_language($langcode, $finished = NULL, $skip = array()) // with names ending with $langcode.po. This allows for filenames // like node-module.de.po to let translators use small files and // be able to import in smaller chunks. - $files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)' . $langcode . '\.po$/', array('.', '..', 'CVS'), 0, FALSE)); + $files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)' . $langcode . '\.po$/', '/(\.\.?|CVS)$/', 0, FALSE)); $components[] = $component->name; } @@ -2517,7 +2517,7 @@ function locale_batch_by_component($components, $finished = '_locale_batch_syste // as $langcode.po or with names ending with $langcode.po. This allows // for filenames like node-module.de.po to let translators use small // files and be able to import in smaller chunks. - $files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)(' . $language_list . ')\.po$/', array('.', '..', 'CVS'), 0, FALSE)); + $files = array_merge($files, file_scan_directory(dirname($component->filename) . '/translations', '/(^|\.)(' . $language_list . ')\.po$/', '/(\.\.?|CVS)$/', 0, FALSE)); } } return _locale_batch_build($files, $finished); diff --git a/install.php b/install.php index caa5feb3ea0..4a5df926f5d 100644 --- a/install.php +++ b/install.php @@ -410,7 +410,7 @@ function install_settings_form_submit($form, &$form_state) { * Find all .profile files. */ function install_find_profiles() { - return file_scan_directory('./profiles', '/\.profile$/', array('.', '..', 'CVS'), 0, TRUE, 'name', 0); + return file_scan_directory('./profiles', '/\.profile$/', '/(\.\.?|CVS)$/', 0, TRUE, 'name', 0); } /** @@ -496,7 +496,7 @@ function install_select_profile_form(&$form_state, $profile_files) { * Find all .po files for the current profile. */ function install_find_locales($profilename) { - $locales = file_scan_directory('./profiles/' . $profilename . '/translations', '/\.po$/', array('.', '..', 'CVS'), 0, FALSE); + $locales = file_scan_directory('./profiles/' . $profilename . '/translations', '/\.po$/', '/(\.\.?|CVS)$/', 0, FALSE); array_unshift($locales, (object) array('name' => 'en')); return $locales; } diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test index 564ecea3503..e383defcaee 100644 --- a/modules/simpletest/tests/file.test +++ b/modules/simpletest/tests/file.test @@ -541,6 +541,38 @@ class FileDirectoryTest extends FileTestCase { } +/** + * Tests the file_scan_directory() function. + */ +class FileScanDirectoryTest extends FileTestCase { + /** + * Implementation of getInfo(). + */ + function getInfo() { + return array( + 'name' => t('File scan directory'), + 'description' => t('Tests the file_scan_directory() function.'), + 'group' => t('File'), + ); + } + + /** + * Check that the no-mask parameter is honored. + */ + function testNoMask() { + $path = $this->original_file_directory . '/simpletest'; + + // Grab a listing of all the JS files. + $all_files = file_scan_directory($path, '/javascript*/'); + $this->assertEqual(2, count($all_files), t('Found two, expected javascript files.')); + + // Now use the nomask parameter to filter out the .script file. + $filtered_files = file_scan_directory($path, '/javascript*/', '/.script$/'); + $this->assertEqual(1, count($filtered_files), t('Filtered correctly.')); + } +} + + /** * Deletion related tests. */