I’ve did a quick test on just changing the option and it seems to work.
What I did is:
- Wrote a widget that has just 2 fields: “Title” and “Name”. Add several instances of this widget to my sidebars. Been sure that they are shown correctly in frontend.
- Edited the class to use 3 fields: “Title” and “First Name” (to replace “Name”) and added “Last Name”.
-
Edited the function that register the widget on
'widgets_init'
to call a function that update the widget options:add_action( 'widgets_init', 'my_example_widget_register' ); function my_example_widget_register() { $widget_name="my_example_widget"; // <-- You will probably replace this $options = get_option("widget_{$widget_name}"); // if the widget is not updated, run a function that updates it if ($options && ! get_option("is_{$widget_name}_updated")) { // use class below to update options $updater = new MyExampleWidgetUpdater($widget_name, $options); $updater->update(); } register_widget('My_Example_Widget'); // <-- You will probably replace this }
-
Wrote a simple class to update widget options:
class MyExampleWidgetUpdater { private $name; private $options; public function __construct($name, $options) { $this->name = $name; $this->options = $options; } public function update() { // loop all the options array_walk($this->options, function(&$option, $key) { if (is_array($option) && is_numeric($key)) { $option = $this->getOption($option); } }); // update all options in DB update_option("widget_{$this->name}", $this->options); // set the widget as updated update_option("is_{$this->name}_updated", 1); } private function getOption($options) { if (!isset($options['name'])) { return $options; } $options['first_name'] = $options['name']; $options['last_name'] = ''; unset($options['name']); return $options; } }
-
I edited the widget class to save the option
"is_{$widget_name}_updated"
inside theupdate()
method, in this way the updater class will never be called for new users that never installed old widgetclass My_Example_Widget { ... public function update($new_instance, $old_instance) { ... $widget_name="my_example_widget"; update_option("is_{$widget_name}_updated", 1); } }
-
I visited my site and the widgets saved with old options are displayed with no issue using new options. (Of course “last name” is always empty).
A good idea may be replace the "is_{$widget_name}_updated"
option, with an option that store the actual version of the widget, in this way it will be handy next time you need an update.