Peningkatan plugin: Pengaturan widget

9

Saya sudah mencoba melakukan penelitian tentang ini tetapi belum menemukan sesuatu yang solid. Saya memiliki plugin yang sedang saya kerjakan dan antara versi terakhir dan versi baru kami membuat beberapa pembaruan pada widget yang mengubah beberapa nama pengaturan (di backend) dan saya mengalami masalah dalam membuat rutin upgrade untuk melakukan ini.

Apa yang telah saya lakukan sejauh ini yang tampaknya (sebagian besar) berhasil adalah ini:

$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 );
}

Dalam sebagian besar pengujian saya ini berhasil, tetapi masalahnya adalah bahwa widget lama tidak lagi menampilkan outputnya. Hanya judul widget yang akan ditampilkan. Saya dapat memperbaikinya dengan membuka dan menyimpan masing-masing widget dan kemudian itu akan berfungsi dengan baik, tetapi saya tidak ingin membuat pengguna saya melakukan itu.

Saya pikir sesuatu seperti ini mungkin berhasil:

$settings = $widgets->get_settings();

foreach( $settings as $s ) {

    $s['setting1'] = $s['oldsetting1'];
    $s['setting2'] = $s['oldsetting2'];

    $widgets->save_settings( $s );

}

Tapi sepertinya save_settings()panggilan itu pasti salah karena ini menghapus widget sepenuhnya.

Saya mengalami kesulitan menemukan standar apa pun untuk sesuatu seperti ini dan hanya ingin mendengar pemikiran, gagasan, atau tautan apa pun yang mungkin harus Anda lakukan seperti ini.

Terima kasih sebelumnya atas bantuannya.

EDIT:

Ini sebenarnya bukan pertanyaan tentang melacak kunci lisensi atau meningkatkan plugin yang tidak di-host di WP repo. Tentang ini adalah memperbarui pengaturan antara 2 versi plugin ketika pengguna melakukan upgrade.

Contoh:

versi 1.0.0 memiliki bidang pengaturan name

Nah di versi 1.1.0 kami memutuskan kami membutuhkan nama depan dan belakang sehingga kami mengubah pengaturan lama menjadi first_namedan kemudian menambahkan pengaturan baru last_name.

Mentransfer opsi-opsi ini jika disimpan sebagai meta pos untuk jenis pos khusus tidak ada masalah:

$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' );

Sehingga bagian itu mudah. Apa yang saya mengalami masalah dengan yang tampaknya tidak mudah adalah melakukan hal yang sama tetapi untuk pengaturan WIDGET.

Semoga ini akan menjernihkan kebingungan dan membantu membuat ini menjadi lebih mudah untuk dijawab.

EDIT 2:

Hasil dari echo '<pre>' . print_r( $widget, true ) . '</pre>';potongan kode pertama di atas:

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
)
Nick Young
sumber
Saya baru saja melihat artikel ini pada hari ini di Tutsplus, saya bahkan belum membaca semuanya, tetapi sepertinya menjadi teman Anda. Buat Lisensi Terkendali Tema dan Sistem Pembaruan Plugin
OnethingSimple
@OnethingSimple Terima kasih atas balasannya tetapi itu tidak seperti yang saya maksud. Saya akan memperbarui pertanyaan untuk membuatnya lebih jelas.
Nick Young
Kesempatan apa pun yang kami dapatkan dari struktur pengaturan widget yang Anda baca (meskipun Anda harus mengubah beberapa nilai). Itu mungkin membantu memberi gambaran tentang apa yang salah. misalnya gema "<pre>". print_r ($ widget, true). "</pre>";
Prajurit
@Privateer Tambahkan ke bagian bawah OP sekarang.
Nick Young

Jawaban:

3

Saya telah melakukan tes cepat pada hanya mengubah opsi dan sepertinya berhasil.

Apa yang saya lakukan adalah:

  1. Tulis widget yang hanya memiliki 2 bidang: "Judul" dan "Nama". Tambahkan beberapa contoh widget ini ke sidebar saya. Sudah yakin bahwa mereka ditampilkan dengan benar di frontend.
  2. Mengedit kelas untuk menggunakan 3 bidang: "Judul" dan "Nama Depan" (untuk mengganti "Nama") dan menambahkan "Nama Belakang".
  3. Mengedit fungsi yang mendaftarkan widget 'widgets_init'untuk memanggil fungsi yang memperbarui opsi widget:

    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. Menulis kelas sederhana untuk memperbarui opsi widget:

    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. Saya mengedit kelas widget untuk menyimpan opsi "is_{$widget_name}_updated"di dalam update()metode, dengan cara ini kelas pembaru tidak akan pernah dipanggil untuk pengguna baru yang tidak pernah menginstal widget lama

    class My_Example_Widget {
    
        ...
    
        public function update($new_instance, $old_instance) {
            ...
    
            $widget_name = 'my_example_widget';
            update_option("is_{$widget_name}_updated", 1);
        }
    }
  6. Saya mengunjungi situs saya dan widget yang disimpan dengan opsi lama ditampilkan tanpa masalah menggunakan opsi baru. (Tentu saja "nama belakang" selalu kosong).

Ide yang bagus mungkin menggantikan "is_{$widget_name}_updated"opsi, dengan opsi yang menyimpan versi widget yang sebenarnya, dengan cara ini akan berguna saat Anda membutuhkan pembaruan.

gmazzap
sumber
SO melihat jawaban Anda tanpa mengujinya dulu. Tampaknya mirip dengan apa yang telah saya lakukan dengan menggunakan yang update_optionbenar? Saya bertanya-tanya sekarang apakah kaitannya mungkin? Saya mengaitkannya ke initkait. Apakah ada perbedaan besar dengan menambahkannya ke widgets_inithook? Saya cukup yakin mereka menembak pada saat yang sama. Terima kasih atas bantuan Anda.
Nick Young
@NickYoung Tidak ada perbedaan dalam kaitannya. Tetapi dalam cuplikan kode pertama Anda (itu mirip dengan milik saya) yang kedua (dalam) foreachsalah.
gmazzap
Saya baru saja mendapat kesempatan untuk mengimplementasikan kode yang Anda tulis. Ini bekerja dengan baik, tetapi saya masih mendapatkan masalah yang sama seperti sebelumnya. Ini berhasil memindahkan opsi, tetapi setelah menjalankan pemutakhiran rutin untuk plugin, widget berhenti mengeluarkan HTML utama dan hanya menampilkan judul widget. Jika saya pergi ke pengaturan widget dan cukup klik tombol simpan maka muncul lagi. Adakah pikiran?
Nick Young
Untuk menambahkan komentar terakhir saya. Ini seperti opsi sedang diperbarui dengan benar tetapi contoh sebenarnya tidak. Apakah itu suatu kemungkinan?
Nick Young
Tidak menonaktifkan semua caching. Juga diuji pada 2 host yang berbeda dengan masalah yang sama.
Nick Young
1

Hanya untuk mempertimbangkan dari sudut yang berbeda - alih-alih memperbarui otomatis semua pengaturan pada pembaruan plugin, cukup periksa pengaturan "lama" & petakan ke pengaturan "baru" secara langsung:

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;
}
TheDeadMedic
sumber
0

Di atas kepala saya, setiap instance widget diberikan semacam ID unik. Saya ingin mengatakan itu menjadi prexfix untuk tombol untuk widget.

Saya ingat mengetuk ini beberapa waktu lalu tetapi tidak ingat persis apa tepatnya, maaf.

Kepala Alchemist
sumber