[wp-trac] [WordPress Trac] #26897: Widgets that share callback functions don't get displayed - wp_list_widgets (wp-admin/includes/widgets.php)
WordPress Trac
noreply at wordpress.org
Tue Jan 21 11:51:06 UTC 2014
#26897: Widgets that share callback functions don't get displayed - wp_list_widgets
(wp-admin/includes/widgets.php)
------------------------------+-----------------------------
Reporter: benjamin.jakobus | Owner:
Type: defect (bug) | Status: new
Priority: normal | Milestone: Awaiting Review
Component: Widgets | Version: trunk
Severity: normal | Keywords: has-patch
------------------------------+-----------------------------
'''Summary''': When registering widgets that share the same callback
function using ''wp_register_sidebar_widget'' , Wordpress will only ever
display the first widget registered - all other widgets that share the
callback function will be ignored. BUT all widgets are being registered -
they just weren't displayed. I examined the core and the culprit lies in
wp_list_widgets:
However now that we have a list of static widgets as well as custom
widgets created by the user (e.g. My Custom Files Widget, My Custom
Communities Widget etc), we only need one callback function - that is,
each widget is registered using its unique ID, BUT a common callback
function is used - this function pulls the settings from the database and
then decides on what to do. A key aspect here is that the
wp_register_sidebar_widget function requires the function name of the
callback function as a string (it can't deal with anonymous functions).
Now to the bug: when creating custom widgets, Wordpress would only ever
display the first widgets - all other widgets were being ignored. BUT all
widgets were being registered - they just weren't displayed. I examined
the core and the culprit lies in ''wp_list_widgets'':
{{{
foreach ( $sort as $widget ) {
if ( in_array( $widget['callback'], $done, true ) ) // We
already showed this multi-widget
continue;
$sidebar = is_active_widget( $widget['callback'],
$widget['id'], false, false );
$done[] = $widget['callback'];
if ( ! isset( $widget['params'][0] ) )
$widget['params'][0] = array();
$args = array( 'widget_id' => $widget['id'], 'widget_name'
=> $widget['name'], '_display' => 'template' );
if (
isset($wp_registered_widget_controls[$widget['id']]['id_base']) &&
isset($widget['params'][0]['number']) ) {
$id_base =
$wp_registered_widget_controls[$widget['id']]['id_base'];
$args['_temp_id'] = "$id_base-__i__";
$args['_multi_num'] =
next_widget_id_number($id_base);
$args['_add'] = 'multi';
} else {
$args['_add'] = 'single';
if ( $sidebar )
$args['_hide'] = '1';
}
$args = wp_list_widget_controls_dynamic_sidebar( array( 0
=> $args, 1 => $widget['params'][0] ) );
call_user_func_array( 'wp_widget_control', $args );
}
}}}
to ensure that widgets aren't being listed twice, it keeps track of those
that are already being displayed using the $done array - this array
however uses the callback function and NOT the widget ID. Which in essence
means that users can only ever created one custom widgets - as opposed to
N. Using the ID fixes this problem. i.e.
{{{
foreach ( $sort as $widget ) {
if ( in_array( $widget['callback'], $done, true ) ) // We
already showed this multi-widget
continue;
$sidebar = is_active_widget( $widget['callback'],
$widget['id'], false, false );
$done[] = $widget['id'];
if ( ! isset( $widget['params'][0] ) )
$widget['params'][0] = array();
$args = array( 'widget_id' => $widget['id'], 'widget_name'
=> $widget['name'], '_display' => 'template' );
if (
isset($wp_registered_widget_controls[$widget['id']]['id_base']) &&
isset($widget['params'][0]['number']) ) {
$id_base =
$wp_registered_widget_controls[$widget['id']]['id_base'];
$args['_temp_id'] = "$id_base-__i__";
$args['_multi_num'] =
next_widget_id_number($id_base);
$args['_add'] = 'multi';
} else {
$args['_add'] = 'single';
if ( $sidebar )
$args['_hide'] = '1';
}
$args = wp_list_widget_controls_dynamic_sidebar( array( 0
=> $args, 1 => $widget['params'][0] ) );
call_user_func_array( 'wp_widget_control', $args );
}
}}}
Patch attached.
--
Ticket URL: <https://core.trac.wordpress.org/ticket/26897>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform
More information about the wp-trac
mailing list