Skip to content

Commit c683208

Browse files
committed
Widgets: Prevent fatal errors in PHP 8 when retrieve_widgets() and wp_map_sidebars_widgets() attempt to merge non-array values.
Props kesselb, lakshyajeet, hellofromTonya, janthiel, ikriv, audrasjb, mtg169, bartnv, pmbaldha, mindctrl, westonruter, jrf. Fixes #57469. git-svn-id: https://develop.svn.wordpress.org/trunk@60732 602fd350-edb4-49c9-b593-d223f7449a82
1 parent db9654e commit c683208

File tree

2 files changed

+67
-0
lines changed

2 files changed

+67
-0
lines changed

src/wp-includes/widgets.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,6 +1350,13 @@ function retrieve_widgets( $theme_changed = false ) {
13501350
$sidebars_widgets = _wp_remove_unregistered_widgets( $sidebars_widgets, $registered_widgets_ids );
13511351
$sidebars_widgets = wp_map_sidebars_widgets( $sidebars_widgets );
13521352

1353+
// Replace non-array values inside the array with an empty array.
1354+
foreach ( $sidebars_widgets as $key => $value ) {
1355+
if ( ! is_array( $value ) ) {
1356+
$sidebars_widgets[ $key ] = array();
1357+
}
1358+
}
1359+
13531360
// Find hidden/lost multi-widget instances.
13541361
$shown_widgets = array_merge( ...array_values( $sidebars_widgets ) );
13551362
$lost_widgets = array_diff( $registered_widgets_ids, $shown_widgets );
@@ -1511,6 +1518,13 @@ function wp_map_sidebars_widgets( $existing_sidebars_widgets ) {
15111518

15121519
$old_sidebars_widgets = _wp_remove_unregistered_widgets( $old_sidebars_widgets );
15131520

1521+
// Replace non-array values inside the array with an empty array.
1522+
foreach ( $new_sidebars_widgets as $key => $value ) {
1523+
if ( ! is_array( $value ) ) {
1524+
$new_sidebars_widgets[ $key ] = array();
1525+
}
1526+
}
1527+
15141528
if ( ! empty( $old_sidebars_widgets ) ) {
15151529

15161530
// Go through each remaining sidebar...

tests/phpunit/tests/widgets.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,4 +1359,57 @@ public function test_sidebar_guessing_one_menu_per_sidebar() {
13591359
);
13601360
$this->assertSameSetsWithIndex( $expected_sidebars, $new_next_theme_sidebars );
13611361
}
1362+
1363+
/**
1364+
* Ensures null sidebar values are converted to empty arrays in retrieve_widgets().
1365+
*
1366+
* @covers ::retrieve_widgets
1367+
* @ticket 57469
1368+
*/
1369+
public function test_retrieve_widgets_converts_null_sidebar_to_empty_array() {
1370+
global $sidebars_widgets;
1371+
wp_widgets_init();
1372+
$this->register_sidebars( array( 'primary', 'secondary', 'wp_inactive_widgets' ) );
1373+
1374+
$sidebars_widgets = array(
1375+
'primary' => null,
1376+
'secondary' => array( 'text-1' ),
1377+
'extra_sidebar' => array( 'unregistered_widget-1' ),
1378+
'wp_inactive_widgets' => array(),
1379+
);
1380+
1381+
$result = retrieve_widgets( true );
1382+
$this->assertArrayHasKey( 'primary', $result );
1383+
$this->assertSame( array(), $result['primary'], 'Primary sidebar should be an empty array after normalization.' );
1384+
$this->assertArrayNotHasKey( 'extra_sidebar', $result, 'Unregistered sidebar should be removed.' );
1385+
}
1386+
1387+
/**
1388+
* Ensures wp_map_sidebars_widgets() normalizes null sidebar widget arrays.
1389+
*
1390+
* @covers ::wp_map_sidebars_widgets
1391+
* @ticket 57469
1392+
*/
1393+
public function test_wp_map_sidebars_widgets_converts_null_sidebar_to_empty_array() {
1394+
$this->register_sidebars( array( 'primary', 'wp_inactive_widgets' ) );
1395+
// Theme data containing a null so the normalization loop runs.
1396+
set_theme_mod(
1397+
'sidebars_widgets',
1398+
array(
1399+
'time' => time(),
1400+
'data' => array(
1401+
'primary' => null,
1402+
),
1403+
)
1404+
);
1405+
1406+
$prev_theme_sidebars = array(
1407+
'primary' => null,
1408+
'wp_inactive_widgets' => array(),
1409+
);
1410+
1411+
$new_sidebars = wp_map_sidebars_widgets( $prev_theme_sidebars );
1412+
$this->assertArrayHasKey( 'primary', $new_sidebars );
1413+
$this->assertSame( array(), $new_sidebars['primary'], 'Primary sidebar should be an empty array after normalization.' );
1414+
}
13621415
}

0 commit comments

Comments
 (0)