Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backport: Store legacy sidebars when switching to a block theme #3893

Closed
1 change: 1 addition & 0 deletions src/wp-includes/default-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@
add_action( 'after_setup_theme', 'wp_setup_widgets_block_editor', 1 );
add_action( 'init', 'wp_widgets_init', 1 );
add_action( 'change_locale', array( 'WP_Widget_Media', 'reset_default_labels' ) );
add_action( 'widgets_init', '_wp_block_theme_register_classic_sidebars', 1 );

// Admin Bar.
// Don't remove. Wrong way to disable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,10 @@ public function prepare_item_for_response( $item, $request ) {
$sidebar['class'] = '';
}

if ( wp_is_block_theme() ) {
$sidebar['status'] = 'inactive';
}

$fields = $this->get_fields_for_response( $request );
if ( rest_is_field_included( 'widgets', $fields ) ) {
$sidebars = wp_get_sidebars_widgets();
Expand Down
8 changes: 7 additions & 1 deletion src/wp-includes/theme.php
Original file line number Diff line number Diff line change
Expand Up @@ -733,11 +733,12 @@ function locale_stylesheet() {
* @global array $wp_theme_directories
* @global WP_Customize_Manager $wp_customize
* @global array $sidebars_widgets
* @global array $wp_registered_sidebars
*
* @param string $stylesheet Stylesheet name.
*/
function switch_theme( $stylesheet ) {
global $wp_theme_directories, $wp_customize, $sidebars_widgets;
global $wp_theme_directories, $wp_customize, $sidebars_widgets, $wp_registered_sidebars;
Mamaduka marked this conversation as resolved.
Show resolved Hide resolved

$requirements = validate_theme_requirements( $stylesheet );
if ( is_wp_error( $requirements ) ) {
Expand Down Expand Up @@ -814,6 +815,11 @@ function switch_theme( $stylesheet ) {
}
}

// Stores classic sidebars for later use by block themes.
if ( $new_theme->is_block_theme() ) {
set_theme_mod( 'wp_classic_sidebars', $wp_registered_sidebars );
}

update_option( 'theme_switched', $old_theme->get_stylesheet() );

/**
Expand Down
26 changes: 26 additions & 0 deletions src/wp-includes/widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -2105,3 +2105,29 @@ function wp_check_widget_editor_deps() {
}
}
}

/**
* Registers the previous theme's sidebars for the block themes.
*
* @since 6.2.0
* @access private
*
* @global array $wp_registered_sidebars Registered sidebars.
*/
function _wp_block_theme_register_classic_sidebars() {
global $wp_registered_sidebars;

if ( ! wp_is_block_theme() ) {
return;
}

$classic_sidebars = get_theme_mod( 'wp_classic_sidebars' );
if ( empty( $classic_sidebars ) ) {
return;
}

// Don't use `register_sidebar` since it will enable the `widgets` support for a theme.
foreach ( $classic_sidebars as $sidebar ) {
$wp_registered_sidebars[ $sidebar['id'] ] = $sidebar;
}
}
67 changes: 67 additions & 0 deletions tests/phpunit/tests/rest-api/rest-sidebars-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,73 @@ public function test_get_items_inactive_widgets() {
);
}

/**
* @ticket 57531
* @covers WP_Test_REST_Sidebars_Controller::prepare_item_for_response
*/
public function test_prepare_item_for_response_to_set_inactive_on_theme_switch() {
$request = new WP_REST_Request( 'GET', '/wp/v2/sidebars/sidebar-1' );

// Set up the test.
wp_widgets_init();
$this->setup_widget(
'widget_rss',
1,
array(
'title' => 'RSS test',
)
);
$this->setup_widget(
'widget_text',
1,
array(
'text' => 'Custom text test',
)
);
$this->setup_sidebar(
'sidebar-1',
array(
'name' => 'Sidebar 1',
),
array( 'text-1', 'rss-1' )
);

// Validate the state before a theme switch.
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$data = $this->remove_links( $data );

$this->assertSame( 'active', $data['status'] );
$this->assertFalse(
get_theme_mod( 'wp_classic_sidebars' ),
'wp_classic_sidebars theme mod should not exist before switching to block theme'
);

switch_theme( 'block-theme' );
wp_widgets_init();

// Validate the state after a theme switch.
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$data = $this->remove_links( $data );

$this->assertSame(
'inactive',
$data['status'],
'Sidebar status should have changed to inactive'
);
$this->assertSame(
array( 'text-1', 'rss-1' ),
$data['widgets'],
'The text and rss widgets should still in sidebar-1'
);
$this->assertArrayHasKey(
'sidebar-1',
get_theme_mod( 'wp_classic_sidebars' ),
'sidebar-1 should be in "wp_classic_sidebars" theme mod'
);
}

/**
* @ticket 41683
*/
Expand Down
89 changes: 89 additions & 0 deletions tests/phpunit/tests/widgets/wpBlockThemeRegisterClassicSidebar.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
/**
* Tests for _wp_block_theme_register_classic_sidebars().
*
* @group widgets
* @covers ::_wp_block_theme_register_classic_sidebars
*/
class Tests_Widgets_WpBlockThemeRegisterClassicSidebars extends WP_UnitTestCase {
/**
* Original global $wp_registered_sidebars.
*
* @var array
*/
private static $wp_registered_sidebars;

public static function set_up_before_class() {
global $wp_registered_sidebars;
parent::set_up_before_class();

// Store the original global before running tests.
static::$wp_registered_sidebars = $wp_registered_sidebars;
}

public function tear_down() {
// Restore the global after each test.
global $wp_registered_sidebars;
$wp_registered_sidebars = static::$wp_registered_sidebars;

parent::tear_down();
}

public function test_a_sidebar_should_be_registered() {
global $wp_registered_sidebars;

$sidebar_id = array_key_first( $wp_registered_sidebars );
$this->assertNotEmpty( $sidebar_id );
}

/**
* @ticket 57531
*/
public function test_should_reregister_previous_theme_sidebar() {
global $wp_registered_sidebars;

$sidebar_id = array_key_first( $wp_registered_sidebars );

switch_theme( 'block-theme' );
unregister_sidebar( $sidebar_id );

// Test before.
$this->assertArrayNotHasKey(
$sidebar_id,
$wp_registered_sidebars,
'Sidebar should not be in registered sidebars after unregister'
);

_wp_block_theme_register_classic_sidebars();

// Test after.
$this->assertArrayHasKey(
$sidebar_id,
$wp_registered_sidebars,
'Sidebar should be in registered sidebars after invoking _wp_block_theme_register_classic_sidebars()'
);
}

/**
* @ticket 57531
*/
public function test_should_bail_out_when_theme_mod_is_empty() {
global $wp_registered_sidebars;

// Test state before invoking.
$this->assertFalse(
get_theme_mod( 'wp_classic_sidebars' ),
'Theme mod should not be set before invoking _wp_block_theme_register_classic_sidebars()'
);

$before = $wp_registered_sidebars;
_wp_block_theme_register_classic_sidebars();

// Test state after invoking.
$this->assertSameSetsWithIndex(
$before,
$wp_registered_sidebars,
'No change should happen after invoking _wp_block_theme_register_classic_sidebars()'
);
}
}