問題描述
我已經嘗試了一些研究,但還沒有找到任何堅實的東西。我有一個我正在工作的外掛,在最後一個版本和新版本之間,我們對更改某些設定名稱 (在後端) 的視窗小工具進行了一些更新,我無法建立升級例程來執行此操作。
到目前為止,我所做的這個 (大部分) 工作是這樣的:
$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 );
}
在我的大部分測試中,這樣做的確可以,但是問題就是舊的 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 上託管的外掛的問題。這更重要的是在使用者升級時更新 2 版本的外掛之間的設定。
例:
版本 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' );
所以這部分很容易。我遇到麻煩,似乎並不容易做同樣的事情,但 WIDGET 設定。
希望這將清除任何混亂和幫助,使這更容易回答。
編輯 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
)
最佳解決方案
我已經做了一個快速測試,只是改變選項,它似乎工作。
我所做的是:
-
寫了一個只有 2 個欄位的小工具:”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; } } -
我編輯了視窗小工具類,以便將
"is_{$widget_name}_updated"選項儲存在update()方法中,這樣就不會為沒有安裝舊視窗小工具的新使用者呼叫 updater 類class My_Example_Widget { ... public function update($new_instance, $old_instance) { ... $widget_name = 'my_example_widget'; update_option("is_{$widget_name}_updated", 1); } } -
我訪問了我的網站,使用舊選項儲存的小工具顯示沒有問題使用新的選項。 (當然”last name” 一直是空的) 。
一個好主意可能是替換"is_{$widget_name}_updated"選項,並具有儲存實際版本的小工具的選項,這樣,下次您需要更新時將會很方便。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。