プラグインのアップグレード:ウィジェット設定


9

私はこれについていくつかの研究を試みましたが、まだ確かなものは何も見つかりませんでした。私が作業しているプラ​​グインがあり、前のバージョンと新しいバージョンの間で、(バックエンドの)設定名の一部を変更するウィジェットにいくつかの更新を行いました。これを行うためのアップグレードルーチンの作成に問題があります。

これまで(ほとんど)機能しているように思われるのは次のとおりです。

$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リポジトリでホストされていないプラグインのアップグレードに関する問題ではありません。これは、ユーザーがアップグレードするときに、プラグインの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' );

その部分は簡単です。私が困っているのは簡単ではないようですが、これと同じことを行うのはウィジェット設定です。

うまくいけば、これで混乱が解消され、簡単に答えられるようになります。

編集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
)

今日、Tutsplusでこの記事を見たばかりですが、まだ全部は読んでいませんが、あなたの味方のようです。ライセンス管理されたテーマとプラグイン更新システムを作成する
OnethingSimple

@OnethingSimple返信ありがとうございます。これは、私が求めているものとはかなり異なります。より明確にするために質問を更新します。
Nick Young

何らかの設定値を変更する必要がある場合でも、ウィジェットの設定構造が読み込んでいるように見える可能性があります。それは何が悪いのかを理解するのに役立つかもしれません。たとえば、「<pre>」をエコーし​​ます。print_r($ widget、true)。"</ pre>";
Privateer、2015

@Privateer OPの下部に追加されました。
Nick Young

回答:


3

私はオプションを変更するだけで簡単なテストを行いましたが、うまくいくようです。

私がしたことは:

  1. 「タイトル」と「名前」の2つのフィールドのみを持つウィジェットを作成しました。このウィジェットのいくつかのインスタンスをサイドバーに追加します。フロントエンドで正しく表示されることを確認しました。
  2. 「Title」と「First Name」の3つのフィールドを使用するようにクラスを編集し(「Name」を置き換えるため)、「Last Name」を追加しました。
  3. '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
    }
  4. ウィジェットオプションを更新する単純なクラスを記述します。

    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;
      }
    }
  5. ウィジェットクラスを編集して、オプション"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);
        }
    }
  6. 私のサイトを訪問しました。古いオプションで保存されたウィジェットは、新しいオプションを使用しても問題なく表示されます。(もちろん、「姓」は常に空です)。

"is_{$widget_name}_updated"オプションをウィジェットの実際のバージョンを格納するオプションに置き換えることをお勧めします。これにより、次に更新が必要になったときに便利です。


SOはまだテストせずに答えを調べています。それはちょうど私がupdate_option正しいを使用して行ったことに似ているようですか?フックが重要なのかどうか私は今疑問に思っていますか?フックに引っ掛けていinitます。widgets_init代わりにフックに追加することで大きな違いはありますか?私は彼らが同時に発砲すると確信していました。ご協力いただきありがとうございます。
Nick Young

@NickYoungフックに違いはありません。しかし、最初のコードスニペット(私のものに似ています)では、2番目(内部)foreachは間違っています。
gmazzap

私はあなたが書いたコードを実装する機会を得ました。それはうまく機能しますが、以前と同じ問題がまだ発生しています。オプションは正常に転送されますが、プラグインのアップグレードルーチンを実行した後、ウィジェットはメインHTMLの出力を停止し、ウィジェットのタイトルのみを表示します。ウィジェットの設定に行き、単に保存ボタンをクリックすると、再びポップアップします。何かご意見は?
Nick Young

私の最後のコメントに追加します。オプションが正しく更新されているようですが、実際のインスタンスはそうではありません。それも可能ですか?
Nick Young

いいえ、すべてのキャッシュが無効になっています。また、同じ問題を持つ2つの異なるホストでテストされました。
Nick Young

1

プラグインの更新時にすべての設定を自動アップグレードするのではなく、別の角度から比較検討するだけで、「古い」設定を確認し、その場で「新しい」設定にマッピングします。

function widget( $args, $instance ) {
    if ( isset( $instance['old_setting'] ) )
         $instance = self::_version_compat( $instance );
}

static function _version_compat( $instance ) {
    $instance['new_setting'] = $instance['old_setting'];
    // etc.

    return $instance;
}

0

私の頭の上で、ウィジェットの各インスタンスには、ある種の一意のIDが与えられています。それがウィジェットのキーのプレフィックスになると言いたいです。

少し前にこれを突っついたのを覚えていますが、申し訳ありませんが、正確な内容を思い出せません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.