Skip to content

Commit 376539e

Browse files
committed
Widgets: Ensure a widget is registered prior to checking its ID in is_active_widget().
This avoids a possible PHP warning due to an undefined array key. Developed in #10710 Follow-up to [11090], [7080]. Props sageth, josephscott, Ipstenu, mindctrl, westonruter. See #8441, #6023. Fixes #57518. git-svn-id: https://develop.svn.wordpress.org/trunk@61466 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 7682e9a commit 376539e

File tree

3 files changed

+52
-1
lines changed

3 files changed

+52
-1
lines changed

src/wp-includes/widgets.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ function is_active_widget( $callback = false, $widget_id = false, $id_base = fal
925925
if ( is_array( $widgets ) ) {
926926
foreach ( $widgets as $widget ) {
927927
if ( ( $callback && isset( $wp_registered_widgets[ $widget ]['callback'] ) && $wp_registered_widgets[ $widget ]['callback'] === $callback ) || ( $id_base && _get_widget_id_base( $widget ) === $id_base ) ) {
928-
if ( ! $widget_id || $widget_id === $wp_registered_widgets[ $widget ]['id'] ) {
928+
if ( ! $widget_id || ( isset( $wp_registered_widgets[ $widget ]['id'] ) && $widget_id === $wp_registered_widgets[ $widget ]['id'] ) ) {
929929
return $sidebar;
930930
}
931931
}

tests/phpunit/tests/widgets.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1412,4 +1412,45 @@ public function test_wp_map_sidebars_widgets_converts_null_sidebar_to_empty_arra
14121412
$this->assertArrayHasKey( 'primary', $new_sidebars );
14131413
$this->assertSame( array(), $new_sidebars['primary'], 'Primary sidebar should be an empty array after normalization.' );
14141414
}
1415+
1416+
/**
1417+
* Tests that is_active_widget() does not generate a PHP warning when
1418+
* a widget ID exists in sidebars_widgets but is not in $wp_registered_widgets,
1419+
* and the function is called with id_base and widget_id parameters.
1420+
*
1421+
* This can happen when a widget is saved to a sidebar but the widget class
1422+
* has not yet been registered (e.g., during early plugin/theme loading).
1423+
*
1424+
* @ticket 57518
1425+
* @covers ::is_active_widget
1426+
*/
1427+
public function test_is_active_widget_with_unregistered_widget_and_id_base_match() {
1428+
global $wp_registered_widgets;
1429+
1430+
// Set up a sidebar with a widget that is NOT registered in $wp_registered_widgets.
1431+
update_option(
1432+
'sidebars_widgets',
1433+
array(
1434+
'wp_inactive_widgets' => array(),
1435+
'sidebar-1' => array( 'search-2' ),
1436+
'array_version' => 3,
1437+
)
1438+
);
1439+
1440+
// Ensure the widget is NOT in $wp_registered_widgets.
1441+
unset( $wp_registered_widgets['search-2'] );
1442+
1443+
/*
1444+
* Call is_active_widget() with id_base and widget_id parameters.
1445+
* This should NOT generate a PHP warning about accessing array offset on null.
1446+
*
1447+
* The bug occurs because when matching by id_base, the code checks
1448+
* _get_widget_id_base( $widget ) === $id_base without verifying
1449+
* $wp_registered_widgets[ $widget ] exists, then tries to access
1450+
* $wp_registered_widgets[ $widget ]['id'] on the next line.
1451+
*/
1452+
$result = is_active_widget( false, 'search-2', 'search', true );
1453+
1454+
$this->assertFalse( $result, 'The widget is not registered, so the function should return false.' );
1455+
}
14151456
}

tests/phpunit/tests/widgets/wpBlockThemeRegisterClassicSidebar.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ public function tear_down() {
3232
public function test_a_sidebar_should_be_registered() {
3333
global $wp_registered_sidebars;
3434

35+
// Register a sidebar for testing if none exist.
36+
if ( empty( $wp_registered_sidebars ) ) {
37+
register_sidebar( array( 'id' => 'test-sidebar' ) );
38+
}
39+
3540
$sidebar_id = array_key_first( $wp_registered_sidebars );
3641
$this->assertNotEmpty( $sidebar_id );
3742
}
@@ -42,6 +47,11 @@ public function test_a_sidebar_should_be_registered() {
4247
public function test_should_reregister_previous_theme_sidebar() {
4348
global $wp_registered_sidebars;
4449

50+
// Register a sidebar for testing if none exist.
51+
if ( empty( $wp_registered_sidebars ) ) {
52+
register_sidebar( array( 'id' => 'test-sidebar' ) );
53+
}
54+
4555
$sidebar_id = array_key_first( $wp_registered_sidebars );
4656

4757
switch_theme( 'block-theme' );

0 commit comments

Comments
 (0)