From 77dcb1771ae14e655edaf514f0f55c28212d9bb2 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Wed, 20 Dec 2023 20:00:04 +0000 Subject: [PATCH] Themes: Improve the performance of `_get_block_templates_paths`. This avoids redundant recursive lookups for block template paths in the same base directory by implementing a static cache. It also replaces an potentially expensive `file_exists` call in favor of doing recursive iteration of files inside a try/catch block. Props thekt12, spacedmonkey, flixos90, mukesh27, joemcgill. Fixes #58196. git-svn-id: https://develop.svn.wordpress.org/trunk@57215 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-includes/block-template-utils.php | 9 ++++- tests/phpunit/tests/block-template.php | 43 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/block-template-utils.php b/src/wp-includes/block-template-utils.php index 265758b922840..f47c649fff081 100644 --- a/src/wp-includes/block-template-utils.php +++ b/src/wp-includes/block-template-utils.php @@ -224,14 +224,21 @@ static function ( $item ) { * @return string[] A list of paths to all template part files. */ function _get_block_templates_paths( $base_directory ) { + static $template_path_list = array(); + if ( isset( $template_path_list[ $base_directory ] ) ) { + return $template_path_list[ $base_directory ]; + } $path_list = array(); - if ( file_exists( $base_directory ) ) { + try { $nested_files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $base_directory ) ); $nested_html_files = new RegexIterator( $nested_files, '/^.+\.html$/i', RecursiveRegexIterator::GET_MATCH ); foreach ( $nested_html_files as $path => $file ) { $path_list[] = $path; } + } catch ( Exception $e ) { + // Do nothing. } + $template_path_list[ $base_directory ] = $path_list; return $path_list; } diff --git a/tests/phpunit/tests/block-template.php b/tests/phpunit/tests/block-template.php index 8e86254f29c2f..dcc3f6282dd40 100644 --- a/tests/phpunit/tests/block-template.php +++ b/tests/phpunit/tests/block-template.php @@ -387,6 +387,49 @@ public function data_get_block_theme_folders() { ); } + /** + * Tests `_get_block_templates_paths()` for an invalid directory. + * + * @ticket 58196 + * + * @covers ::_get_block_templates_paths + */ + public function test_get_block_templates_paths_dir_exists() { + $theme_dir = get_template_directory(); + // Templates in the current theme. + $templates = array( + 'parts/small-header.html', + 'templates/custom-single-post-template.html', + 'templates/index.html', + 'templates/page-home.html', + 'templates/page.html', + 'templates/single.html', + ); + + $expected_template_paths = array_map( + static function ( $template ) use ( $theme_dir ) { + return $theme_dir . '/' . $template; + }, + $templates + ); + + $template_paths = _get_block_templates_paths( $theme_dir ); + $this->assertSameSets( $expected_template_paths, $template_paths ); + } + + /** + * Test _get_block_templates_paths() for a invalid dir. + * + * @ticket 58196 + * + * @covers ::_get_block_templates_paths + */ + public function test_get_block_templates_paths_dir_doesnt_exists() { + // Should return empty array for invalid path. + $template_paths = _get_block_templates_paths( '/tmp/random-invalid-theme-path' ); + $this->assertSame( array(), $template_paths ); + } + /** * Registers a test block to log `in_the_loop()` results. *