Make WordPress Core

Opened 6 years ago

Closed 6 years ago

#31465 closed defect (bug) (fixed)

Fix JS for sidebar_widgets customizer control to not return undefined items in getWidgetFormControls method

Reported by: westonruter Owned by: ocean90
Milestone: 4.2 Priority: normal
Severity: normal Version: 4.2
Component: Customize Keywords: has-patch
Focuses: javascript Cc:

Description (last modified by westonruter)

Dynamically-created Customizer settings were introduced in #30936. Specifically for widgets in the Customizer, since the dynamic settings for widgets get set up before widgets_init so that any newly-created widget instances will get registered as widgets in $wp_registered_widgets, the WP_Customize_Widgets::sanitize_sidebar_widgets() method was changed in r31370 to remove the sanitizing check to ensure that all widget IDs in a given sidebar correspond to actually-registered widgets.

The side-effect to the sanitization change is that a sidebars_widgets[...] Customizer setting may end up containing widget IDs that do not have corresponding widget_{id_base}[{number}] settings. This, in turn, causes a problem for wp.customize.controlConstructor.sidebar_widgets.prototype.getWidgetFormControls() which is currently incorrectly assuming that every widget ID in a sidebar has a corresponding widget setting/control. If there is no corresponding control/setting for a widget ID, then an exception currently gets thrown when trying to open the Available Widgets Panel (in wp.customize.Widgets.AvailableWidgetsPanelView.prototype.open()) due to control being undefined:

// Wide widget controls appear over the preview, and so they need to be collapsed when the panel opens
_( this.currentSidebarControl.getWidgetFormControls() ).each( function( control ) {
        if ( control.params.is_wide ) { // ERROR: control may be undefined
} );

Current installs can be money patched to fix the problem via a plugin doing:

var oldMethod = wp.customize.controlConstructor.sidebar_widgets.prototype.getWidgetFormControls;
wp.customize.controlConstructor.sidebar_widgets.prototype.getWidgetFormControls = function () {
        return _.filter(
                oldMethod.apply( this, arguments ),
                function ( control ) {
                        return !! control;

The problem can be easily reproduced in JS by opening the console and entering:

wp.customize('sidebars_widgets[sidebar-1]')( wp.customize('sidebars_widgets[sidebar-1]')().concat( 'foo-123' ) )

And then attempt to add a widget by opening the available widgets panel.

Attachments (1)

31465.diff (900 bytes) - added by westonruter 6 years ago.

Download all attachments as: .zip

Change History (4)

#1 @westonruter
6 years ago

  • Description modified (diff)

#2 @westonruter
6 years ago

  • Keywords has-patch added
  • Owner set to ocean90
  • Status changed from new to reviewing

#3 @ocean90
6 years ago

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

In 31570:

Customize Widgets: Don't return undefined items in getWidgetFormControls method.

props westonruter.
fixes #31465.

Note: See TracTickets for help on using tickets.