diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php index 81409e9382..86a21a8e78 100644 --- a/src/wp-includes/functions.php +++ b/src/wp-includes/functions.php @@ -8120,8 +8120,9 @@ function get_dirsize( $directory, $max_execution_time = null ) { * @param string $directory Full path of a directory. * @param string|array $exclude Optional. Full path of a subdirectory to exclude from the total, * or array of paths. Expected without trailing slash(es). - * @param int $max_execution_time Maximum time to run before giving up. In seconds. The timeout is global - * and is measured from the moment WordPress started to load. + * @param int $max_execution_time Optional. Maximum time to run before giving up. In seconds. + * The timeout is global and is measured from the moment + * WordPress started to load. * @param array $directory_cache Optional. Array of cached directory paths. * * @return int|false|null Size in bytes if a valid directory. False if not. Null if timeout. @@ -8194,7 +8195,9 @@ function recurse_dirsize( $directory, $exclude = null, $max_execution_time = nul } } - if ( $max_execution_time > 0 && microtime( true ) - WP_START_TIMESTAMP > $max_execution_time ) { + if ( $max_execution_time > 0 && + ( microtime( true ) - WP_START_TIMESTAMP ) > $max_execution_time + ) { // Time exceeded. Give up instead of risking a fatal timeout. $size = null; break; @@ -8205,6 +8208,10 @@ function recurse_dirsize( $directory, $exclude = null, $max_execution_time = nul } } + if ( ! is_array( $directory_cache ) ) { + $directory_cache = array(); + } + $directory_cache[ $directory ] = $size; // Only write the transient on the top level call and not on recursive calls. diff --git a/tests/phpunit/tests/functions/cleanDirsizeCache.php b/tests/phpunit/tests/functions/cleanDirsizeCache.php index 6ae7d6d2dc..d600bdca54 100644 --- a/tests/phpunit/tests/functions/cleanDirsizeCache.php +++ b/tests/phpunit/tests/functions/cleanDirsizeCache.php @@ -1 +1 @@ -expectNotice(); $this->expectNoticeMessage( $expected_message ); clean_dirsize_cache( $path ); } /** * Data provider. * * @return array */ public function data_clean_dirsize_cache_with_invalid_inputs() { return array( 'null' => array( 'path' => null, 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received NULL.', ), 'bool false' => array( 'path' => false, 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received boolean.', ), 'empty string' => array( 'path' => '', 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received string.', ), 'array' => array( 'path' => array( '.', './second/path/' ), 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received array.', ), ); } /** * Test the handling of a non-path text string passed as the $path parameter. * * @ticket 52241 * * @dataProvider data_clean_dirsize_cache_with_non_path_string * * @param string $path Path input to use in the test. * @param int $expected_count Expected number of paths in the cache after cleaning. */ public function test_clean_dirsize_cache_with_non_path_string( $path, $expected_count ) { // Set the dirsize cache to our mock. set_transient( 'dirsize_cache', $this->mock_dirsize_cache_with_non_path_string() ); clean_dirsize_cache( $path ); $cache = get_transient( 'dirsize_cache' ); $this->assertIsArray( $cache ); $this->assertCount( $expected_count, $cache ); } /** * Data provider. * * @return array */ public function data_clean_dirsize_cache_with_non_path_string() { return array( 'single dot' => array( 'path' => '.', 'expected_count' => 1, ), 'non-path' => array( 'path' => 'string', 'expected_count' => 1, ), 'non-existant string, but non-path' => array( 'path' => 'doesnotexist', 'expected_count' => 2, ), ); } private function mock_dirsize_cache_with_non_path_string() { return array( '.' => array( 'size' => 50 ), 'string' => array( 'size' => 42 ), ); } } \ No newline at end of file +expectNotice(); $this->expectNoticeMessage( $expected_message ); clean_dirsize_cache( $path ); } /** * Data provider. * * @return array */ public function data_clean_dirsize_cache_with_invalid_inputs() { return array( 'null' => array( 'path' => null, 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received NULL.', ), 'bool false' => array( 'path' => false, 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received boolean.', ), 'empty string' => array( 'path' => '', 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received string.', ), 'array' => array( 'path' => array( '.', './second/path/' ), 'expected_message' => 'clean_dirsize_cache() only accepts a non-empty path string, received array.', ), ); } /** * Test the handling of a non-path text string passed as the $path parameter. * * @ticket 52241 * * @covers ::clean_dirsize_cache * * @dataProvider data_clean_dirsize_cache_with_non_path_string * * @param string $path Path input to use in the test. * @param int $expected_count Expected number of paths in the cache after cleaning. */ public function test_clean_dirsize_cache_with_non_path_string( $path, $expected_count ) { // Set the dirsize cache to our mock. set_transient( 'dirsize_cache', $this->mock_dirsize_cache_with_non_path_string() ); clean_dirsize_cache( $path ); $cache = get_transient( 'dirsize_cache' ); $this->assertIsArray( $cache ); $this->assertCount( $expected_count, $cache ); } /** * Data provider. * * @return array */ public function data_clean_dirsize_cache_with_non_path_string() { return array( 'single dot' => array( 'path' => '.', 'expected_count' => 1, ), 'non-path' => array( 'path' => 'string', 'expected_count' => 1, ), 'non-existant string, but non-path' => array( 'path' => 'doesnotexist', 'expected_count' => 2, ), ); } private function mock_dirsize_cache_with_non_path_string() { return array( '.' => array( 'size' => 50 ), 'string' => array( 'size' => 42 ), ); } /** * Test the behaviour of the function when the transient doesn't exist. * * @ticket 52241 * @ticket 53635 * * @covers ::recurse_dirsize */ public function test_recurse_dirsize_without_transient() { delete_transient( 'dirsize_cache' ); $size = recurse_dirsize( __DIR__ . '/fixtures' ); $this->assertGreaterThan( 10, $size ); } /** * Test the behaviour of the function when the transient does exist, but is not an array. * * In particular, this tests that no PHP TypeErrors are being thrown. * * @ticket 52241 * @ticket 53635 * * @covers ::recurse_dirsize */ public function test_recurse_dirsize_with_invalid_transient() { set_transient( 'dirsize_cache', 'this is not a valid transient for dirsize cache' ); $size = recurse_dirsize( __DIR__ . '/fixtures' ); $this->assertGreaterThan( 10, $size ); } } \ No newline at end of file diff --git a/tests/phpunit/tests/functions/fixtures/dummy.txt b/tests/phpunit/tests/functions/fixtures/dummy.txt new file mode 100644 index 0000000000..7cc0f577ee --- /dev/null +++ b/tests/phpunit/tests/functions/fixtures/dummy.txt @@ -0,0 +1 @@ +This is a dummy text file which is only used by the `Tests_Multisite_CleanDirsizeCache::test_recurse_dirsize_without_transient()` test. \ No newline at end of file