Make WordPress Core

Changeset 61466 for trunk


Ignore:
Timestamp:
01/10/2026 06:28:18 PM (3 months ago)
Author:
westonruter
Message:

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 https://github.com/WordPress/wordpress-develop/pull/10710

Follow-up to [11090], [7080].

Props sageth, josephscott, Ipstenu, mindctrl, westonruter.
See #8441, #6023.
Fixes #57518.

Location:
trunk
Files:
3 edited

Legend:

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

    r61432 r61466  
    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                        }
  • trunk/tests/phpunit/tests/widgets.php

    r60732 r61466  
    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}
  • trunk/tests/phpunit/tests/widgets/wpBlockThemeRegisterClassicSidebar.php

    r55200 r61466  
    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 );
     
    4247    public function test_should_reregister_previous_theme_sidebar() {
    4348        global $wp_registered_sidebars;
     49
     50        // Register a sidebar for testing if none exist.
     51        if ( empty( $wp_registered_sidebars ) ) {
     52            register_sidebar( array( 'id' => 'test-sidebar' ) );
     53        }
    4454
    4555        $sidebar_id = array_key_first( $wp_registered_sidebars );
Note: See TracChangeset for help on using the changeset viewer.