0

I am currently using a loop that goes trough all sidebars looking for widgets than loop those again in order to get all widgets options.

Doing this on

add_filter('sidebars_widgets', array($this, 'sidebars_widgets'));

filter and it just does not seem right that I need to loop this much just to get all options

I took this example from display widgets plugin and it just does not seem right

function sidebars_widgets($sidebars) {    
    if ( is_admin() ) {
        return $sidebars;
    }

    global $wp_registered_widgets;

    foreach ( $sidebars as $s => $sidebar ) {
        if ( $s == 'wp_inactive_widgets' || strpos($s, 'orphaned_widgets') === 0 || empty($sidebar) ) {
            continue;
        }

        foreach ( $sidebar as $w => $widget ) {
            // $widget is the id of the widget
            if ( !isset($wp_registered_widgets[$widget]) ) {
                continue;
            }

                $opts = $wp_registered_widgets[$widget];
                $id_base = is_array($opts['callback']) ? $opts['callback'][0]->id_base : $opts['callback'];

                if ( !$id_base ) {
                    continue;
                }

                $instance = get_option('widget_' . $id_base);

                if ( !$instance || !is_array($instance) ) {
                    continue;
                }

                if ( isset($instance['_multiwidget']) && $instance['_multiwidget'] ) {
                    $number = $opts['params'][0]['number'];
                    if ( !isset($instance[$number]) ) {
                        continue;
                    }

                    $instance = $instance[$number];
                    unset($number);
                }

                unset($opts);

                print_r($instance);// here they are



            unset($widget);
        }
        unset($sidebar);
    }

    return $sidebars;
}

would you know a better , faster way to do this ?

2 Answers 2

2

This actually seems like a quite plausible approach - to me.

There is nothing wrong with looping through it, sometimes it is the only/fastest way anyway.

I don't know how you get your sidebars, but for this

$sidebars_widgets = get_option( 'sidebars_widgets' );

can be used. Which gives you an associative array containing a list of widgets per sidebar and a list of all inactive widgets.

2
  • do you think if there would be a problem with this approach github.com/ThemeFuse/Unyson/issues/568#issuecomment-103085491 instead of the loop above ?
    – Benn
    May 18, 2015 at 14:55
  • It really just depends, if you want all settings of all widgets, then you most likely have to loop. And, as said, there is nothing wrong with doing so. If you want the settings of one widget at a time some other approaches - depending on context - might be suitable. Another thing is, you probably could do the data collection only on sidebar/widget changes, saving the data as option/transient, which means, most of the time you just grab the saved data instead of looping. @Benn May 18, 2015 at 15:45
0

This function may help:

function get_all_widgets_data($sidebar_id=null){
    $result = [];
    $sidebars_widgets = get_option('sidebars_widgets');

    if(is_array($sidebars_widgets)){

        foreach ($sidebars_widgets as $key => $value) {

            if(is_array($value)){
                foreach ($value as $widget_id) {
                    $pieces = explode('-', $widget_id);
                    $multi_number = array_pop($pieces);
                    $id_base = implode('-', $pieces);
                    $widget_data = get_option('widget_' . $id_base);
                    
                    // Remove inactive widgets 
                    if($key != 'wp_inactive_widgets' ) {
                        unset($widget_data['_multiwidget']);
                        $result[$key] = $widget_data;
                    }
                }
            }
        }
    }
    if($sidebar_id){
        return isset($result[$sidebar_id]) ? $result[$sidebar_id] : [] ;
    }
    return $result;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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