Upgrade/Install: Skip registering theme block patterns during the upgrade process.

This fixes a bug during the database upgrade process where a theme's `functions.php` file may not be loaded, leading to potential exceptions if the theme's pattern files use symbols (classes, functions, constants, etc.) that are declared only when the `functions.php` file is loaded. To do so, a check for `wp_get_active_and_valid_themes()` is added early to `_register_theme_block_patterns()`, which returns early if no active or valid themes are returned.

Props fabiankaegy, rajinsharwar, pbiron, huzaifaalmesbah, hellofromTonya, peterwilsoncc, joemcgill.
Reviewed by hellofromTonya.
Merges [57021] to the 6.4 branch.
Fixes .


git-svn-id: https://develop.svn.wordpress.org/branches/6.4@57023 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Joe McGill 2023-10-27 19:23:24 +00:00
parent c6a7ff026c
commit 74d3772816
2 changed files with 75 additions and 0 deletions
src/wp-includes
tests/phpunit/tests/blocks

@ -328,6 +328,17 @@ function _register_remote_theme_patterns() {
* @access private
*/
function _register_theme_block_patterns() {
/*
* During the bootstrap process, a check for active and valid themes is run.
* If no themes are returned, the theme's functions.php file will not be loaded,
* which can lead to errors if patterns expect some variables or constants to
* already be set at this point, so bail early if that is the case.
*/
if ( empty( wp_get_active_and_valid_themes() ) ) {
return;
}
/*
* Register patterns for the active theme. If the theme is a child theme,
* let it override any patterns from the parent theme that shares the same slug.

@ -482,4 +482,68 @@ class Tests_Blocks_wpBlockPattersRegistry extends WP_UnitTestCase {
$result = $this->registry->is_registered( 'test/one' );
$this->assertTrue( $result );
}
/**
* Ensures theme patterns are registered on init.
*
* @ticket 59723
*
* @covers ::_register_theme_block_patterns
*/
public function test_register_theme_block_patterns_on_init() {
// This test needs to use access static class properties.
$registry = WP_Block_Patterns_Registry::get_instance();
// Ensure we're using a theme with patterns.
switch_theme( 'twentytwentythree' );
$theme = wp_get_theme();
$theme_patterns = array_values( wp_list_pluck( $theme->get_block_patterns(), 'slug' ) );
// This helper is fired on the init hook.
_register_theme_block_patterns();
$registered = wp_list_pluck( $registry->get_all_registered(), 'name' );
// Cleanup patterns registry.
foreach ( $theme_patterns as $pattern ) {
$registry->unregister( $pattern );
}
$this->assertSameSets( $theme_patterns, array_intersect( $theme_patterns, $registered ), 'Could not confirm theme patterns were registered.' );
}
/**
* Ensures theme patterns are not registered when no themes are active and valid.
*
* @ticket 59723
*
* @covers ::_register_theme_block_patterns
*/
public function test_register_theme_block_patterns_on_init_skipped_during_install() {
// This test needs to use access static class properties.
$registry = WP_Block_Patterns_Registry::get_instance();
// Ensure we're using a theme with patterns.
switch_theme( 'twentytwentythree' );
$theme = wp_get_theme();
$theme_patterns = array_values( wp_list_pluck( $theme->get_block_patterns(), 'slug' ) );
/*
* This will short-circuit theme activation.
* @see wp_get_active_and_valid_themes().
*/
wp_installing( true );
// This helper is fired on the init hook.
_register_theme_block_patterns();
$registered = wp_list_pluck( $registry->get_all_registered(), 'name' );
// Cleanup.
wp_installing( false );
$this->assertEmpty( array_intersect( $theme_patterns, $registered ), 'Theme patterns were were incorrectly registered.' );
}
}