Make WordPress Core

Changeset 60732


Ignore:
Timestamp:
09/12/2025 06:03:16 PM (3 months ago)
Author:
westonruter
Message:

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.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/widgets.php

    r59702 r60732  
    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 ) );
     
    15111518
    15121519        $old_sidebars_widgets = _wp_remove_unregistered_widgets( $old_sidebars_widgets );
     1520
     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        }
    15131527
    15141528        if ( ! empty( $old_sidebars_widgets ) ) {
  • trunk/tests/phpunit/tests/widgets.php

    r56559 r60732  
    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}
Note: See TracChangeset for help on using the changeset viewer.