diff --git a/src/wp-includes/class-wp-theme.php b/src/wp-includes/class-wp-theme.php index 6952c59bda494..f5b9f6bab238f 100644 --- a/src/wp-includes/class-wp-theme.php +++ b/src/wp-includes/class-wp-theme.php @@ -1338,13 +1338,21 @@ public function get_post_templates() { $files = (array) $this->get_files( 'php', 1, true ); foreach ( $files as $file => $full_path ) { - if ( ! preg_match( '|Template Name:(.*)$|mi', file_get_contents( $full_path ), $header ) ) { + $headers = get_file_data( + $full_path, + array( + 'Template Name' => 'Template Name', + 'Template Post Type' => 'Template Post Type', + ) + ); + + if ( ! $headers['Template Name'] ) { continue; } $types = array( 'page' ); - if ( preg_match( '|Template Post Type:(.*)$|mi', file_get_contents( $full_path ), $type ) ) { - $types = explode( ',', _cleanup_header_comment( $type[1] ) ); + if ( $headers['Template Post Type'] ) { + $types = explode( ',', $headers['Template Post Type'] ); } foreach ( $types as $type ) { @@ -1353,28 +1361,28 @@ public function get_post_templates() { $post_templates[ $type ] = array(); } - $post_templates[ $type ][ $file ] = _cleanup_header_comment( $header[1] ); + $post_templates[ $type ][ $file ] = $headers['Template Name']; } } - $this->cache_add( 'post_templates', $post_templates ); - } + if ( current_theme_supports( 'block-templates' ) ) { + $block_templates = get_block_templates( array(), 'wp_template' ); + foreach ( get_post_types( array( 'public' => true ) ) as $type ) { + foreach ( $block_templates as $block_template ) { + if ( ! $block_template->is_custom ) { + continue; + } - if ( current_theme_supports( 'block-templates' ) ) { - $block_templates = get_block_templates( array(), 'wp_template' ); - foreach ( get_post_types( array( 'public' => true ) ) as $type ) { - foreach ( $block_templates as $block_template ) { - if ( ! $block_template->is_custom ) { - continue; - } + if ( isset( $block_template->post_types ) && ! in_array( $type, $block_template->post_types, true ) ) { + continue; + } - if ( isset( $block_template->post_types ) && ! in_array( $type, $block_template->post_types, true ) ) { - continue; + $post_templates[ $type ][ $block_template->slug ] = $block_template->title; } - - $post_templates[ $type ][ $block_template->slug ] = $block_template->title; } } + + $this->cache_add( 'post_templates', $post_templates ); } if ( $this->load_textdomain() ) { diff --git a/tests/phpunit/tests/admin/includesTheme.php b/tests/phpunit/tests/admin/includesTheme.php index ed90cf9514ae5..499120d181042 100644 --- a/tests/phpunit/tests/admin/includesTheme.php +++ b/tests/phpunit/tests/admin/includesTheme.php @@ -222,6 +222,72 @@ public function test_get_post_templates_child_theme() { ); } + /** + * @ticket 42513 + * + * @covers WP_Theme::get_post_templates + */ + public function test_get_post_templates_caches_results() { + $theme = wp_get_theme( 'page-templates' ); + $this->assertNotEmpty( $theme ); + + switch_theme( $theme['Template'], $theme['Stylesheet'] ); + + // First call populates the cache. + $first_result = $theme->get_post_templates(); + $this->assertNotEmpty( $first_result ); + + // Second call should return the same result from cache. + $second_result = $theme->get_post_templates(); + $this->assertSame( $first_result, $second_result ); + } + + /** + * @ticket 42513 + * + * @covers WP_Theme::get_post_templates + */ + public function test_get_post_templates_uses_get_file_data() { + $theme = wp_get_theme( 'page-templates' ); + $this->assertNotEmpty( $theme ); + + switch_theme( $theme['Template'], $theme['Stylesheet'] ); + + $post_templates = $theme->get_post_templates(); + + // Verify single-line header format is parsed correctly via get_file_data(). + $this->assertArrayHasKey( 'page', $post_templates ); + $this->assertArrayHasKey( 'template-header.php', $post_templates['page'] ); + $this->assertSame( 'This Template Header Is On One Line', $post_templates['page']['template-header.php'] ); + } + + /** + * @ticket 42513 + * + * @covers WP_Theme::get_post_templates + */ + public function test_get_post_templates_cache_cleared_on_switch() { + $theme = wp_get_theme( 'page-templates' ); + $this->assertNotEmpty( $theme ); + + switch_theme( $theme['Template'], $theme['Stylesheet'] ); + + // Populate cache. + $theme->get_post_templates(); + + // Clearing theme cache should require a fresh scan on next call. + wp_clean_themes_cache(); + + $child_theme = wp_get_theme( 'page-templates-child' ); + switch_theme( $child_theme['Template'], $child_theme['Stylesheet'] ); + + $child_templates = $child_theme->get_post_templates(); + + // Child theme should include its own templates. + $this->assertArrayHasKey( 'foo', $child_templates ); + $this->assertArrayHasKey( 'template-top-level-post-types-child.php', $child_templates['foo'] ); + } + /** * Test that the list of theme features pulled from the WordPress.org API returns the expected data structure. *