[wp-hackers] Replace One Plugin With Another

Matt Slocum mattslocum at sharefaith.com
Fri May 25 04:38:39 UTC 2012

Hi all,

Background:  I have a plugin that I wrote to replace another widget that is
missing features. The problem is that I need to programmatically replace
the widget with the new one. I wrote a function that replaces them that
hooks on the 'admin_init'. I picked that because it runs after the widgets
are loaded. I wanted to be able to use the functions such
as get_settings(), save_settings(), wp_get_sidebars_widgets(),
and wp_set_sidebars_widgets(). I guess I could have done all this before
the widgets were loaded, but I already have it working this way... but 1

Problem: The widget does not display the form properly on the page load
when the widget switch happens. The widget's ['callback'] property when it
gets set to 'wp_widget_control' returns false with is_callable(). This
makes the widget settings empty. When viewing the other widgets objects
that weren't converted, they have the same properties, but it returns true.
I can't figure out the difference. I'm guessing that my widget's object
isn't initialized properly. I've been looking through the WP source, and I
can't figure out what is wrong. Is there a way to do a new init of a widget
object later?

I know this isn't that big of a problem because on the 2nd page load it all
loads properly because it is now saved in the database. It is just really
bothering me because I can't figure out how to do it. It also is very
confusing to the user because it feels like things broke until they reload
the page.

Any tips or suggestions?


Here is my code if it helps:


    public function convert_widgets() {
        global $wp_registered_widgets, $wp_widget_factory,
$_wp_sidebars_widgets, $sidebar
        $SF_Obj = $wp_widget_factory->widgets['SF_Image_Widget'];
 $Simple_Obj = $wp_widget_factory->widgets['WP_Widget_Simple_Image'];

        $simple_widgets = $Simple_Obj->get_settings();
        $SF_widgets = $SF_Obj->get_settings();

        $all_widgets = wp_get_sidebars_widgets();

        $changed = false;
        foreach ( (array) $simple_widgets as $number => $settings ) {
            $changed = true;
            // setup new settings
            $settings = array_merge($settings, array(
                'url' => $settings['link']
            if (!empty($settings['new_window'])) {
                $settings['target'] = '_blank';

            // append new settings
            $SF_widgets[] = $settings;

            // replace sidebar widget array value
            $newNumber = end(array_keys($SF_widgets));
            $newName = 'sf_image_widget-'. $newNumber;
            $oldName = 'simpleimage-'.$number;
            foreach ( $all_widgets as $id => $sidebar) {
                foreach ( $sidebar as $i => $name) {
                    if ($oldName == $name)
                        $all_widgets[$id][$i] = $newName;

            // update $wp_registered_widgets
            $SF_Obj->number = $newNumber;
            $SF_Obj->id = $newName;
            $widget = array(
                'name' => $SF_Obj->name,
                'id' => $newName,
                'callback' => array($SF_Obj, 'display_callback'),
                '_callback' => 'wp_widget_control', // attempt to make new
widgets display form without another refresh
                'params' => array(array('number' => $newNumber)),
                'classname' => $SF_Obj->widget_options['classname'],
                'description' => $SF_Obj->widget_options['description']
            $wp_registered_widgets[$newName] = $widget;

        if (!$changed) return;

//      print_r($wp_registered_widgets);
        // save widgets settings

        // save widget array
        if (!is_admin()) {
            $_wp_sidebars_widgets = $sidebars_widgets = $all_widgets;


More information about the wp-hackers mailing list