Make WordPress Core

Opened 3 years ago

Closed 3 years ago

#53479 closed defect (bug) (fixed)

Unable to add widgets after Opting out of the Widgets Block Editor in WordPress 5.8-Beta2

Reported by: jamesros161's profile jamesros161 Owned by: desrosj's profile desrosj
Milestone: 5.8 Priority: normal
Severity: blocker Version: 5.8
Component: Customize Keywords: has-screenshots has-patch has-unit-tests commit
Focuses: Cc:

Description

So, in the process of testing our theme Crio to ensure compatibility with WordPress 5.8 once it is released, I seem to have stumbled upon a rather breaking bug in the Customizer > Widgets panel when opting out of the new Widgets Block Editor.

Long story short, some of our custom controls don't play nicely with the new widget editor, so we are choosing to opt-out of the new widget editor at the time of the 5.8 release, to give us time to overhaul the controls to be more Gutenberg friendly. In the following ticket, https://core.trac.wordpress.org/ticket/53424, it has been made clear that the instructions for opting out are not correct in the documentation, so instead of hooking the remove_theme_support to after_setup_theme hook as instructed in the article, I am hooking to widgets_init as suggested by @Mamaduka in the ticket thread. This seems to work fine to force the traditional widget editor to be used, however; anytime I try to add a widget, I receive an 'invalid data' error, and the added widget does not save. I tested this in our theme, Crio, and then I also tested it on Twenty Fifteen ( I chose an older default theme, because I wanted to test this on a theme that also did not have block support built in to it, but afterwards I tested in Twenty Twenty One as well, and had the same results ). and was able to replicate in both, which is why I believe it is a core bug.
So.... Steps to replicate.

  1. Install any theme, however i've only tested this with Crio, Twenty Fifteen, and Twenty Twenty One.
  2. Create a function in the functions.php ( or wherever is most fitting for your theme ), in that function place remove_theme_support( 'widgets-block-editor' ); and then add that function as an action on the widgets_init hook.
  3. Open the customizer, and as expected, you should see the old familiar widgets interface.
  4. Attempt to add a widget. Any widget will do.
  5. After adding the widget, the 'Invalid value' error will display within that widget's box in the customizer panel, and the widget will fail to appear in the preview pane.

NOTE: While there are no console or PHP errors logged at this point, there is a customizer_changeset XHR response, indicating that for the widget added, there is an invalid_value object with the message being 'invalid value' and the data being 'null'
My particular response was as follows:

{"success":true,"data":{"contents":{"widget[media_gallery-3]":[""]},"errors":[],"setting_validities":{"sidebars_widgets[sidebar-1]":true,"widget_media_gallery[3]":{"invalid_value":{"message":"Invalid value.","data":null}}},"nav_menu_instance_args":[]}}
  1. Upon trying to then publish, the 'Unable to save due to 1 invalid setting' error is displayed. Once again, no console log errors or php errors logged at this point, but this time an admin_ajax.php XHR response indicated the same error as before. My particular response was this:
{"success":false,"data":{"message":"Unable to save due to 1 invalid setting.","code":"transaction_fail","setting_validities":{"sidebars_widgets[sidebar-1]":true,"widget_media_gallery[3]":{"invalid_value":{"message":"Invalid value.","data":null}}}}}

I am also attached some screenshots, and a gif demonstrating this.

Attachments (7)

widget_bug.gif (893.8 KB) - added by jamesros161 3 years ago.
This gif is demonstrating the issue occuring while using the Twenty Fifteen theme, slightly modified to opt-out of the widget block editor.
image (13).png (9.9 KB) - added by jamesros161 3 years ago.
This screenshot shows the error message shown inside the widget's box which displays immediately after adding the widget
image (14).png (28.1 KB) - added by jamesros161 3 years ago.
This image shows the error message displayed when trying to publish after adding a widget
functions_php.png (48.3 KB) - added by jamesros161 3 years ago.
This is a screenshot showing where the change was made in twenty twenty one to opt-out. Line 368 of functions.php
スクリーンショット 2021-06-23 16.40.28.png (37.6 KB) - added by naoki0h 3 years ago.
2021-06-23 at 18.29.07.mp4 (1.1 MB) - added by ixkaito 3 years ago.
2021-06-23 at 18.29.07.gif (7.4 MB) - added by ixkaito 3 years ago.
This is same as 2021-06-23 at 18.29.07.mp4

Change History (23)

@jamesros161
3 years ago

This gif is demonstrating the issue occuring while using the Twenty Fifteen theme, slightly modified to opt-out of the widget block editor.

@jamesros161
3 years ago

This screenshot shows the error message shown inside the widget's box which displays immediately after adding the widget

#1 @desrosj
3 years ago

  • Milestone changed from Awaiting Review to 5.8

Thanks @jamesros161! Moving to the milestone for investigation.

@jamesros161
3 years ago

This image shows the error message displayed when trying to publish after adding a widget

@jamesros161
3 years ago

This is a screenshot showing where the change was made in twenty twenty one to opt-out. Line 368 of functions.php

#2 @caseymilne
3 years ago

  • Keywords needs-testing added

In testing this let's check a couple of other hooks to see if that changes the result.

#3 @naoki0h
3 years ago

I could reproduce this bug in Twenty Twenty too.

#4 @naoki0h
3 years ago

I find this bug is caused in send function in wp-util.js.

https://github.com/WordPress/wordpress-develop/blob/master/src/js/_enqueues/wp/util.js#L82

Also , I find the error dose not happen when I comment out the code below.

request = self._currentRequest = wp.ajax.send( null, {
data: data,
url: api.settings.url.self
} );

https://github.com/WordPress/wordpress-develop/blob/master/src/js/_enqueues/wp/customize/selective-refresh.js#L773-L776

Last edited 3 years ago by naoki0h (previous) (diff)

@ixkaito
3 years ago

This is same as 2021-06-23 at 18.29.07.mp4

#5 @ixkaito
3 years ago

This bug still exists with the after_setup_theme hook.

And I found that if you change the state of the widget, the error disappears.

https://core.trac.wordpress.org/raw-attachment/ticket/53479/2021-06-23%20at%2018.29.07.gif

#6 @zieladam
3 years ago

The issue seems to be somewhere in the widgets handling code on the backend, not on the frontend. I just confirmed that the request body is the same in the WP trunk version after opting-out from the new screen, and in the previous WordPress version.

#7 @zieladam
3 years ago

The culprit is the return line in wp-includes/class-wp-customize-widgets.php:

        public function sanitize_widget_instance( $value, $id_base = null ) {
                global $wp_widget_factory;

                if ( array() === $value ) {
                        return;
                }

In 5.7, this said return $value;, so empty array in = empty array out. This played well with the following logic in wp-includes/class-wp-customize-manager.php:

        $value = $setting->sanitize( $unsanitized_value );
        if ( is_null( $value ) ) {
                $validity = false;
        }

But now sanitize returns a null value instead of an empty array, hence the $validity becomes false. The change was introduced in the following commit by @noisysocks:

https://github.com/WordPress/wordpress-develop/commit/00bc227eb8e7b09e9eb6390a74a23a3f3fcc2383

@noisysocks, would you elaborate on the return; part? Will anything break if we return $value instead of null? If the answer is yes, we could condition the behavior on the widget editor used (as awful as it sounds :p).

This ticket was mentioned in Slack in #core by caseymilne. View the logs.


3 years ago

#9 @noisysocks
3 years ago

Hey @zieladam, good debugging. It should be return $value;. I likely changed it to return; thinking that this was a simplification not realising the semantic difference between array() and null.

This ticket was mentioned in PR #1424 on WordPress/wordpress-develop by noisysocks.


3 years ago
#10

  • Keywords has-patch has-unit-tests added; needs-patch removed

#11 @noisysocks
3 years ago

I added the fix @zieladam described plus a regression test plus some tests I noticed were missing. The PR fixes the issue in my testing.

#12 @zieladam
3 years ago

@noisysocks Looks good to me, I approved the change on Github

#13 @hellofromTonya
3 years ago

  • Keywords commit added

Marking PR 1424 for commit as it reverts a regression introduced in [50996] and it adds tests to validate it.

#14 @desrosj
3 years ago

  • Keywords needs-testing removed
  • Owner set to desrosj
  • Status changed from new to reviewing

This ticket was mentioned in Slack in #core by hellofromtonya. View the logs.


3 years ago

#16 @desrosj
3 years ago

  • Resolution set to fixed
  • Status changed from reviewing to closed

In 51232:

Widgets: Fix an “Invalid value” warning when adding a new widget in the Customizer.

This fixes a regression introduced in [50996] where sites that have been opted-out of the block-based widget editor experienced an “Invalid value.” error when adding a new widget to a sidebar in the Customizer.

This was caused by the early return value was changed to null from $value when set to an empty array, resulting in the widget being evaluated as invalid elsewhere.

Props jamesros161, caseymilne, naoki0h, ixkaito, zieladam, noisysocks, hellofromTonya.
Fixes #53479.

Note: See TracTickets for help on using tickets.