Make WordPress Core

Changeset 51277 for trunk


Ignore:
Timestamp:
06/30/2021 10:40:21 AM (3 years ago)
Author:
SergeyBiryukov
Message:

REST API: Allow multiple widgets to be deleted in a single batch request.

This resets the WP_Widget::$updated flag when deleting a widget, to avoid blocking all future updates in a request.

Props noisysocks, andraganescu.
Fixes #53557.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/rest-api/endpoints/class-wp-rest-widgets-controller.php

    r51248 r51277  
    290290     * @since 5.8.0
    291291     *
    292      * @global array $wp_registered_widget_updates The registered widget update functions.
     292     * @global array             $wp_registered_widget_updates The registered widget update functions.
     293     * @global WP_Widget_Factory $wp_widget_factory
    293294     *
    294295     * @param WP_REST_Request $request Full details about the request.
     
    296297     */
    297298    public function delete_item( $request ) {
    298         global $wp_registered_widget_updates;
     299        global $wp_registered_widget_updates, $wp_widget_factory;
    299300
    300301        retrieve_widgets();
     
    344345            $_POST    = $original_post;
    345346            $_REQUEST = $original_request;
     347
     348            $widget_object = $wp_widget_factory->get_widget_object( $id_base );
     349
     350            if ( $widget_object ) {
     351                /*
     352                 * WP_Widget sets `updated = true` after an update to prevent more than one widget
     353                 * from being saved per request. This isn't what we want in the REST API, though,
     354                 * as we support batch requests.
     355                 */
     356                $widget_object->updated = false;
     357            }
    346358
    347359            wp_assign_widget_to_sidebar( $widget_id, '' );
     
    521533            $widget_object->_register_one( $number );
    522534
    523             // WP_Widget sets updated = true after an update to prevent more
    524             // than one widget from being saved per request. This isn't what we
    525             // want in the REST API, though, as we support batch requests.
     535            /*
     536             * WP_Widget sets `updated = true` after an update to prevent more than one widget
     537             * from being saved per request. This isn't what we want in the REST API, though,
     538             * as we support batch requests.
     539             */
    526540            $widget_object->updated = false;
    527541        }
  • trunk/tests/phpunit/tests/rest-api/rest-widgets-controller.php

    r51248 r51277  
    166166
    167167    private function setup_widget( $id_base, $number, $settings ) {
     168        $this->setup_widgets( $id_base, array( $number => $settings ) );
     169    }
     170
     171    private function setup_widgets( $id_base, $settings ) {
    168172        global $wp_widget_factory;
    169173
    170174        $option_name = "widget_$id_base";
    171         update_option(
    172             $option_name,
    173             array(
    174                 $number => $settings,
    175             )
    176         );
     175        update_option( $option_name, $settings );
    177176
    178177        $widget_object = $wp_widget_factory->get_widget_object( $id_base );
    179         $widget_object->_set( $number );
    180         $widget_object->_register_one( $number );
     178        foreach ( array_keys( $settings ) as $number ) {
     179            $widget_object->_set( $number );
     180            $widget_object->_register_one( $number );
     181        }
    181182    }
    182183
     
    13801381
    13811382    /**
     1383     * @ticket 53557
     1384     */
     1385    public function test_delete_item_multiple() {
     1386        $this->setup_widgets(
     1387            'text',
     1388            array(
     1389                2 => array( 'text' => 'Text widget' ),
     1390                3 => array( 'text' => 'Text widget' ),
     1391                4 => array( 'text' => 'Text widget' ),
     1392            )
     1393        );
     1394        $this->setup_sidebar(
     1395            'sidebar-1',
     1396            array(
     1397                'name' => 'Test sidebar',
     1398            ),
     1399            array( 'text-2', 'text-3', 'text-4' )
     1400        );
     1401
     1402        $request = new WP_REST_Request( 'POST', '/batch/v1' );
     1403        $request->set_body_params(
     1404            array(
     1405                'requests' => array(
     1406                    array(
     1407                        'method' => 'DELETE',
     1408                        'path'   => '/wp/v2/widgets/text-2?force=1',
     1409                    ),
     1410                    array(
     1411                        'method' => 'DELETE',
     1412                        'path'   => '/wp/v2/widgets/text-3?force=1',
     1413                    ),
     1414                    array(
     1415                        'method' => 'DELETE',
     1416                        'path'   => '/wp/v2/widgets/text-4?force=1',
     1417                    ),
     1418                ),
     1419            )
     1420        );
     1421        $response = rest_do_request( $request );
     1422
     1423        $this->assertSame(
     1424            array(
     1425                'sidebar-1' => array(),
     1426            ),
     1427            wp_get_sidebars_widgets()
     1428        );
     1429        $this->assertSame(
     1430            array(
     1431                '_multiwidget' => 1,
     1432            ),
     1433            get_option( 'widget_text' )
     1434        );
     1435    }
     1436
     1437    /**
    13821438     * The test_prepare_item() method does not exist for sidebar.
    13831439     */
Note: See TracChangeset for help on using the changeset viewer.