Оновлення плагінів: налаштування віджетів


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 репо. Більш того, це стосується оновлення налаштувань між двома версіями плагіна, коли користувач оновлює.

Приклад:

версія 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.

Сподіваємось, це усуне будь-яку плутанину і допоможе полегшити відповідь на це.

EDIT 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 Дякую за відповідь, але це не зовсім схоже на те, що я збираюся. Я оновлю питання, щоб зробити це більш зрозумілим.
Нік Янг

Будь-який шанс, ми можемо отримати дамп того, як виглядає структура налаштувань віджетів, яку ви читаєте (навіть якщо вам доведеться змінити деякі значення). Це може допомогти дати уявлення про те, що йде не так. наприклад відлуння "<pre>". print_r ($ віджет, правда). "</pre>";
Приватник

@Privateer Додано зараз до нижньої частини ОП.
Нік Янг

Відповіді:


3

Я зробив швидкий тест на просто зміну опції, і, здається, це працює.

Що я зробив:

  1. Написав віджет, який містить всього 2 поля: "Назва" та "Ім'я". Додайте кілька примірників цього віджета на мої бічні панелі. Переконайтесь, що вони відображаються правильно у фронтальному періоді.
  2. Відредагував клас, використовуючи 3 поля: "Назва" та "Ім'я" (замінити "Ім'я") та додав "Прізвище".
  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"опції з опцією, що зберігає фактичну версію віджета, і це стане в нагоді наступного разу, коли вам потрібно оновлення.


Так що переглядаю вашу відповідь, не перевіряючи її ще. Це здається схожим на те, що я робив, лише використовуючи update_optionправильний? Мені зараз цікаво, чи може гачок має значення? Я зачіплюю його на initгачок. Чи є величезна різниця, додавши widgets_initзамість цього гачок? Я був майже впевнений, що вогонь вогонь одночасно. Спасибі за вашу допомогу.
Нік Янг

@NickYoung У гачку немає різниці. Але у вашому першому фрагменті коду (це той, що схожий на шахту) другий (внутрішній) foreachпомиляється.
gmazzap

Я щойно отримав шанс реалізувати написаний вами код. Це чудово працює, але я все одно отримую ту саму проблему, як і раніше. Він передає параметри успішно, але після запуску програми оновлення плагіна віджет перестає виводити його основний HTML і показує лише заголовок віджета. Якщо я перейду до налаштувань віджетів і просто натисніть кнопку збереження, то він знову з’явиться. Будь-які думки?
Нік Янг

Щоб додати до мого останнього коментаря. Наче параметри оновлюються правильно, але фактичний екземпляр не є. Це навіть можливість?
Нік Янг

Nope не відключив усе кешування. Тестували також на двох різних хостах з однаковою проблемою.
Нік Янг

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

Кожному екземпляру віджета вгорі голови надається якийсь унікальний ідентифікатор. Хочу сказати, що він стає префіксом ключів віджета.

Я пам’ятаю, що давно творив на це, але не можу пригадати, які були вимоги, вибачте.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.