Make WordPress Core

Changeset 60732


Ignore:
Timestamp:
09/12/2025 06:03:16 PM (12 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.