5


I have interesting question about widget instances saved in wp_options table. I have spent pretty much time until I figured it out but still don't know why is it happening.

Problem:
So the problem is that when I drag any widget and drop it on any sidebar in my Admin Dashboard its ID starts with 2. For example when I drop Text widget its ID is widget_text-2 despite of fact that it's first widget. What's more interesting, when I go to wp_options table and unserialize serialized data from widget_text option, what I get is array with indexes starting from 2. Why?

6

The why part can be found in ticket #24889.

Let me quote @azaozz:

When support for multi-use widgets was introduced, a lot of widgets got converted from "single" to "multi" at the same time. To keep backward compatibility and not break the existing widgets, there was some conversion code that would set the "single" widgets instances to *-1 (not sure why not *-0, it was a long time ago). In order to not overwrite the converted data, the new multi-widgets instances had to start form 2. As @tyxla mentions, this doesn't break anything and if changed to -0 or -1, in theory can still overwrite someone's single widgets.

The available Text widget is listed in the global $wp_registered_widgets as:

[text-1] => Array
    (
        [name] => Text
        [id] => text-1
        [callback] => Array
            (
                [0] => WP_Widget_Text Object
                    (
                        [id_base] => text
                        [name] => Text
                        [option_name] => widget_text
                        [alt_option_name] => 
                        [widget_options] => Array
                            (
                                [classname] => widget_text
                                [customize_selective_refresh] => 1
                                [description] => Arbitrary text or HTML.
                            )

                        [control_options] => Array
                            (
                                [id_base] => text
                                [width] => 400
                                [height] => 350
                            )

                        [number] => 1
                        [id] => text-1
                        [updated] => 
                    )

                [1] => display_callback
            )

        [params] => Array
            (
                [0] => Array
                    (
                        [number] => -1
                    )

            )

        [classname] => widget_text
        [customize_selective_refresh] => 1
        [description] => Arbitrary text or HTML.
    )

I think the 1, in the text-1 id, comes from this part of the WP_Widget::_register():

if ( $empty ) {
    // If there are none, we register the widget's existence with a generic template.
    $this->_set( 1 );
    $this->_register_one();
}

When the available multi widgets are listed with wp_list_widgets(), the next_widget_id_number() function is used to calculate the next widget id number. It's defined as:

function next_widget_id_number( $id_base ) {
    global $wp_registered_widgets;
    $number = 1;

    foreach ( $wp_registered_widgets as $widget_id => $widget ) {
        if ( preg_match( '/' . $id_base . '-([0-9]+)$/', $widget_id, $matches ) )
            $number = max($number, $matches[1]);
    }
    $number++;

    return $number;
}

For the text-1 id, the next widget id number is max( 1, 1 ) + 1 = 2.

So when we drag the first multi Text widget over an available sidebar, the widget_text option is stored as (adjusted for better readability):

a:2:{
i:2;a:3:{s:5:"title";s:0:"";s:4:"text";s:0:"";s:6:"filter";b:0;}s:12:"_multiwidget";i:1;
}

where we notice the i:2 part and the sidebars_widgets option will contain the text_2 instance.

Hope it helps.

|improve this answer|||||
  • Thanks! It explains a lot. I spent a lot of time trying to figure it out but couldn't find why it's 2. I expected 0 or 1 but definetly not 2. Now I see why it happens. Thanks again! – Sebastian Kaczmarek Dec 28 '16 at 7:34
  • You're welcome, glad to hear it helped. I agree that it's not easy to dig through the core code to get an overview of how the widget system works. I think I only scratched the surface here ;-) @SebastianKaczmarek – birgire Dec 28 '16 at 11:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.