Skip to content

Commit

Permalink
[Sidebars endpoint] Save function-based widgets (WordPress#24792)
Browse files Browse the repository at this point in the history
* Update the sidebars endpoint to correctly save legacy widgets regardless of their id pattern

* Add tests
  • Loading branch information
adamziel authored Aug 26, 2020
1 parent 7dd02c2 commit beced05
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 8 deletions.
29 changes: 21 additions & 8 deletions lib/class-wp-rest-sidebars-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public function update_item( $request ) {
$sidebar_widgets_ids = array();
foreach ( $input_widgets as $input_widget ) {
ob_start();
if ( isset( $wp_registered_widget_updates[ $input_widget['id_base'] ] ) ) {
if ( isset( $input_widget['id_base'] ) && isset( $wp_registered_widget_updates[ $input_widget['id_base'] ] ) ) {
// Class-based widget.
$update_control = $wp_registered_widget_updates[ $input_widget['id_base'] ];
if ( ! isset( $input_widget['id'] ) ) {
Expand Down Expand Up @@ -176,11 +176,23 @@ public function update_item( $request ) {
$wp_registered_widgets[ $input_widget['id'] ]['callback'][0] = $new_object;
}
}
} elseif ( $wp_registered_widget_updates[ $input_widget['id'] ] ) {
// Old-style widget.
$update_control = $wp_registered_widget_updates[ $input_widget['id'] ];
$_POST = wp_slash( $input_widget['settings'] );
call_user_func( $update_control['callback'] );
} else {
$registered_widget_id = null;
if ( isset( $wp_registered_widget_updates[ $input_widget['id'] ] ) ) {
$registered_widget_id = $input_widget['id'];
} else {
$numberless_id = substr( $input_widget['id'], 0, strrpos( $input_widget['id'], '-' ) );
if ( isset( $wp_registered_widget_updates[ $numberless_id ] ) ) {
$registered_widget_id = $numberless_id;
}
}

if ( $registered_widget_id ) {
// Old-style widget.
$update_control = $wp_registered_widget_updates[ $registered_widget_id ];
$_POST = wp_slash( $input_widget['settings'] );
call_user_func( $update_control['callback'] );
}
}
ob_end_clean();

Expand Down Expand Up @@ -213,6 +225,7 @@ public function get_items( $request ) {

$data[] = $this->prepare_item_for_response( $sidebar, $request )->get_data();
}

return rest_ensure_response( $data );
}

Expand Down Expand Up @@ -350,7 +363,7 @@ public static function get_widgets( $sidebar_id ) {
* Prepare a single sidebar output for response
*
* @param array $raw_sidebar Sidebar instance.
* @param WP_REST_Request $request Request object.
* @param WP_REST_Request $request Request object.
*
* @return WP_REST_Response $data
*/
Expand Down Expand Up @@ -390,7 +403,7 @@ public function prepare_item_for_response( $raw_sidebar, $request ) {
foreach ( $schema['properties']['widgets']['items']['properties'] as $property_id => $property ) {
if ( isset( $widget[ $property_id ] ) && gettype( $widget[ $property_id ] ) === $property['type'] ) {
$widget_data[ $property_id ] = $widget[ $property_id ];
} elseif ( 'settings' === $property_id && 'array' === gettype( $widget[ $property_id ] ) ) {
} elseif ( 'settings' === $property_id && isset( $widget[ $property_id ] ) && 'array' === gettype( $widget[ $property_id ] ) ) {
$widget_data[ $property_id ] = $widget['settings'];
} elseif ( isset( $property['default'] ) ) {
$widget_data[ $property_id ] = $property['default'];
Expand Down
92 changes: 92 additions & 0 deletions phpunit/class-rest-sidebars-controller-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,98 @@ public function test_update_item() {
);
}

/**
*
*/
public function test_update_item_legacy_widget_1() {
$this->do_test_update_item_legacy_widget( 'testwidget-1' );
}

/**
*
*/
public function test_update_item_legacy_widget_2() {
$this->do_test_update_item_legacy_widget( 'testwidget' );
}

/**
*
*/
public function do_test_update_item_legacy_widget( $widget_id ) {
// @TODO: Use @dataProvider instead (it doesn't work with custom constructors like the one we have in this class)
wp_register_widget_control(
$widget_id,
'WP test widget',
function() {
$settings = get_option( 'widget_testwidget' );

// check if anything's been sent.
if ( isset( $_POST['update_testwidget'] ) ) {
$settings['id'] = $_POST['test_id'];
$settings['title'] = $_POST['test_title'];

update_option( 'widget_testwidget', $settings );
}
},
100,
200
);
wp_register_sidebar_widget(
$widget_id,
'WP test widget',
function() {
$settings = get_option( 'widget_testwidget' ) ? get_option( 'widget_testwidget' ) : array(
'id' => '',
'title' => '',
);
echo '<h1>' . $settings['id'] . '</h1><span>' . $settings['title'] . '</span>';
}
);
$this->setup_sidebar(
'sidebar-1',
array(
'name' => 'Test sidebar',
),
array( $widget_id )
);

$request = new WP_REST_Request( 'POST', '/__experimental/sidebars/sidebar-1' );
$request->set_body_params(
array(
'widgets' => array(
array(
'id' => $widget_id,
'name' => 'WP test widget',
'settings' => array(
'test_id' => 'My test id',
'test_title' => 'My test title',
'update_testwidget' => true,
),
),
),
)
);
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertEquals(
array(
'id' => 'sidebar-1',
'name' => 'Test sidebar',
'description' => '',
'status' => 'active',
'widgets' => array(
array(
'id' => $widget_id,
'settings' => array(),
'rendered' => '<h1>My test id</h1><span>My test title</span>',
'name' => 'WP test widget',
),
),
),
$data
);
}

/**
* The test_delete_item() method does not exist for sidebar.
*/
Expand Down

0 comments on commit beced05

Please sign in to comment.