From 45b080dd5402b72e91c045b1244b773c1fde0573 Mon Sep 17 00:00:00 2001 From: Mike Schroder Date: Tue, 27 Jun 2023 16:06:16 +0000 Subject: [PATCH] Filesystem API: Allow optional inclusion of hidden files in `list_files()`. Adds a new optional `$include_hidden` parameter to allow the inclusion of hidden (`.` prefixed) files. Defaults to false for backward compatibility. Props yani.iliev, sabernhardt, costdev, rutviksavsani, zunaid321, azaozz. Fixes #53659. git-svn-id: https://develop.svn.wordpress.org/trunk@56069 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/file.php | 15 +++--- tests/phpunit/tests/functions/listFiles.php | 59 +++++++++++++++++++++ 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/src/wp-admin/includes/file.php b/src/wp-admin/includes/file.php index 3ead3d98cd..6ef2aed553 100644 --- a/src/wp-admin/includes/file.php +++ b/src/wp-admin/includes/file.php @@ -127,13 +127,16 @@ function get_home_path() { * * @since 2.6.0 * @since 4.9.0 Added the `$exclusions` parameter. + * @since 6.3.0 Added the `$include_hidden` parameter. * - * @param string $folder Optional. Full path to folder. Default empty. - * @param int $levels Optional. Levels of folders to follow, Default 100 (PHP Loop limit). - * @param string[] $exclusions Optional. List of folders and files to skip. + * @param string $folder Optional. Full path to folder. Default empty. + * @param int $levels Optional. Levels of folders to follow, Default 100 (PHP Loop limit). + * @param string[] $exclusions Optional. List of folders and files to skip. + * @param bool $include_hidden Optional. Whether to include details of hidden ("." prefixed) files. + * Default false. * @return string[]|false Array of files on success, false on failure. */ -function list_files( $folder = '', $levels = 100, $exclusions = array() ) { +function list_files( $folder = '', $levels = 100, $exclusions = array(), $include_hidden = false ) { if ( empty( $folder ) ) { return false; } @@ -156,12 +159,12 @@ function list_files( $folder = '', $levels = 100, $exclusions = array() ) { } // Skip hidden and excluded files. - if ( '.' === $file[0] || in_array( $file, $exclusions, true ) ) { + if ( ( ! $include_hidden && '.' === $file[0] ) || in_array( $file, $exclusions, true ) ) { continue; } if ( is_dir( $folder . $file ) ) { - $files2 = list_files( $folder . $file, $levels - 1 ); + $files2 = list_files( $folder . $file, $levels - 1, array(), $include_hidden ); if ( $files2 ) { $files = array_merge( $files, $files2 ); } else { diff --git a/tests/phpunit/tests/functions/listFiles.php b/tests/phpunit/tests/functions/listFiles.php index a70a058940..bfdd080f8b 100644 --- a/tests/phpunit/tests/functions/listFiles.php +++ b/tests/phpunit/tests/functions/listFiles.php @@ -19,4 +19,63 @@ class Tests_Functions_ListFiles extends WP_UnitTestCase { $admin_files = list_files( ABSPATH . 'wp-admin/', 100, array( 'index.php' ) ); $this->assertNotContains( ABSPATH . 'wp-admin/index.php', $admin_files ); } + + /** + * Tests that list_files() optionally includes hidden files. + * + * @ticket 53659 + * + * @dataProvider data_list_files_should_optionally_include_hidden_files + * + * @param string $filename The name of the hidden file. + * @param bool $include_hidden Whether to include hidden ("." prefixed) files. + * @param string[] $exclusions List of folders and files to skip. + * @param bool $expected Whether the file should be included in the results. + */ + public function test_list_files_should_optionally_include_hidden_files( $filename, $include_hidden, $exclusions, $expected ) { + $test_dir = get_temp_dir() . 'test-list-files/'; + $hidden_file = $test_dir . $filename; + + mkdir( $test_dir ); + touch( $hidden_file ); + + $actual = list_files( $test_dir, 100, $exclusions, $include_hidden ); + + unlink( $hidden_file ); + rmdir( $test_dir ); + + if ( $expected ) { + $this->assertContains( $hidden_file, $actual, 'The file was not included.' ); + } else { + $this->assertNotContains( $hidden_file, $actual, 'The file was included.' ); + } + } + + /** + * Data provider. + * + * @return array[] + */ + public function data_list_files_should_optionally_include_hidden_files() { + return array( + '$include_hidden = false and no exclusions' => array( + 'filename' => '.hidden_file', + 'include_hidden' => false, + 'exclusions' => array(), + 'expected' => false, + ), + '$include_hidden = true and no exclusions' => array( + 'filename' => '.hidden_file', + 'include_hidden' => true, + 'exclusions' => array(), + 'expected' => true, + ), + '$include_hidden = true and an excluded filename' => array( + 'filename' => '.hidden_file', + 'include_hidden' => true, + 'exclusions' => array( '.hidden_file' ), + 'expected' => false, + ), + ); + } }