我试着对此做了一些研究,但还没有发现任何可靠的东西。我有一个插件,在上一个版本和新版本之间,我们对小部件进行了一些更新,更改了一些设置名称(在后端),但我在创建升级例程时遇到了问题。
到目前为止,我所做的(主要)工作是:
$widget = get_option( \'widget_name\' );
if( is_array( $widget ) && ! empty( $widget ) ) {
foreach( $widget as $a => $b ) {
if( ! is_array( $b ) ) {
continue;
}
foreach( $b as $k => $v ) {
$widget[$a][\'setting1\'] = $widget[$a][\'oldsetting1\'];
$widget[$a][\'setting2\'] = $widget[$a][\'oldsetting2\'];
}
}
update_option( \'widget_name\', $widget );
}
在我的大多数测试中,这都是正常的,但问题是旧的小部件不再显示其输出。只显示小部件的标题。我可以通过保存每个小部件来解决这个问题,然后它就会正常工作,但我不想让我的用户这样做。
我想这样可能行得通:
$settings = $widgets->get_settings();
foreach( $settings as $s ) {
$s[\'setting1\'] = $s[\'oldsetting1\'];
$s[\'setting2\'] = $s[\'oldsetting2\'];
$widgets->save_settings( $s );
}
但似乎
save_settings()
调用必须是错误的,因为这会完全删除小部件。
我很难找到像这样的东西的任何标准,我只想听听你可能需要做这样的事情的想法、想法或链接。
提前感谢您的帮助。
编辑:
这实际上不是跟踪许可证密钥或升级不在WP repo上托管的插件的问题。更重要的是,当用户升级时,在插件的两个版本之间更新设置。
示例:
版本1.0.0有一个设置字段name
在版本1.1.0中,我们决定同时需要名字和姓氏,所以我们将旧设置更改为first_name
然后添加新设置last_name
.
如果将这些选项另存为自定义帖子类型的帖子元,则可以传输这些选项:
$old_name = get_post_meta( $post->ID, \'name\', true );
$first_name = update_post_meta ( $post->ID, \'first_name\', true );
delete_post_meta( $post->ID, \'name\' );
所以这部分很简单。我遇到的问题似乎并不容易,就是要做同样的事情,但要做的是小部件设置。
希望这将消除任何困惑,并有助于使这更容易回答。
编辑2:
的结果echo \'<pre>\' . print_r( $widget, true ) . \'</pre>\';
从上面的第一个代码块:
Array
(
[2] => Array
(
[title] => Class Schedule
[id] => 23
[display_type] => grid
[order] => asc
[display_title_text] => Events on
[paging] => 1
[list_max_num] => 7
[list_max_length] => days
[list_start_offset_num] => 0
[list_start_offset_direction] => back
[gce_per_page_num] => 7
[gce_events_per_page] => days
)
[3] => Array
(
[title] => Examples
[id] => 24
[display_type] => grid
[order] => asc
[display_title_text] => Events on
[paging] => 1
[list_max_num] => 7
[list_max_length] => days
[list_start_offset_num] => 0
[list_start_offset_direction] => back
[gce_per_page_num] => 7
[gce_events_per_page] => days
)
[_multiwidget] => 1
)
最合适的回答,由SO网友:gmazzap 整理而成
我做了一个快速测试,只是改变了选项,它似乎奏效了。
我所做的是:
编写了一个小部件,它只有两个字段:“Title”和“Name”。将此小部件的多个实例添加到我的侧栏。确保它们在前端显示正确编辑类以使用3个字段:“Title”和“First Name”(替换“Name”),并添加了“Last Name”编辑了在上注册小部件的函数\'widgets_init\'
要调用更新小部件选项的函数,请执行以下操作:
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
}
编写了一个简单的类来更新小部件选项:
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;
}
}
我编辑了widget类以保存选项
"is_{$widget_name}_updated"
内部
update()
方法,这样就不会为从未安装旧小部件的新用户调用更新程序类
class My_Example_Widget {
...
public function update($new_instance, $old_instance) {
...
$widget_name = \'my_example_widget\';
update_option("is_{$widget_name}_updated", 1);
}
}
我访问了我的网站,使用旧选项保存的小部件使用新选项显示,没有问题。(当然,“姓氏”始终为空)。
一个好主意是更换"is_{$widget_name}_updated"
选项,该选项存储小部件的实际版本,这样下次需要更新时就很方便了。
SO网友:Fernando
我在插件方面也遇到了同样的问题(升级时如何更新旧实例中的小部件选项),我解决了以下问题:
第1步:检查插件升级
您可以使用upgrader_process_complete
钩子,但它只在WordPress自动更新时触发,如果您手动上传插件,则不会触发。您可以在下面的代码参考中看到此挂钩的示例developer.wordpress.org.
所以,我用版本控制完成了:1。-定义新/当前版本的常量,以及2。-将此值保存在wp_options
一旦我们完成了更新过程。
示例:if ( $saved_version != CURRENT_VERSION ) $needs_update = true;
您还可以使用version_compare()
php函数。
第2步:更新选项
在中创建新方法WP_Widget
类并从构造函数调用它,例如$this->mywidget_check_version()
.
此方法检查是否有版本更改(如步骤1所述),并可以使用访问所有小部件实例$this->get_settings()
.
使用foreach()
您只需读取每个实例并更新所需的键和值。您只需要维护实例id。例如,您可以创建一个新数组来添加和删除新/旧键和值:
$new_instances[$id][$key] = isset( $old_instances[$id][$key] ? $old_instances[$id][$key] : $default_value[$key];
完成后,使用$this更新->;保存\\u设置($new\\u实例)并在wp\\u选项中更新版本密钥。
使用这些WP_Widget
方法而不是get_option()
/update_option()
, 确保完整性和兼容性。WP_Widget
定义wp_options
键,实例ID并添加键$settings[\'_multiwidget\'] = 1
.
当做
费尔南多。