it-swarm.com.de

Plugin-Aktualisierung: Widget-Einstellungen

Ich habe einige Nachforschungen angestellt, aber noch nichts Festes gefunden. Ich habe ein Plugin, an dem ich arbeite, und zwischen der letzten Version und der neuen Version haben wir einige Aktualisierungen am Widget vorgenommen, die einige der Einstellungsnamen (im Backend) ändern, und ich habe Probleme, eine Aktualisierungsroutine zu erstellen, um dies zu tun.

Was ich bis jetzt getan habe, was (meistens) zu funktionieren scheint, ist folgendes:

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

In den meisten meiner Tests funktioniert dies in Ordnung, aber das Problem wird, dass das alte Widget seine Ausgabe nicht mehr anzeigt. Nur der Titel des Widgets wird angezeigt. Ich kann dieses Problem beheben, indem ich jedes einzelne Widget speichere. Dann funktioniert es einwandfrei, aber ich möchte meine Benutzer nicht dazu bringen, dies zu tun.

Ich dachte, so etwas könnte funktionieren:

$settings = $widgets->get_settings();

foreach( $settings as $s ) {

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

    $widgets->save_settings( $s );

}

Es scheint jedoch, dass der Aufruf von save_settings() falsch sein muss, da dadurch das Widget vollständig entfernt wird.

Ich habe Probleme, einen Standard für so etwas zu finden, und möchte nur Gedanken, Ideen oder Links hören, die Sie möglicherweise dazu benötigen.

Vielen Dank im Voraus für jede Hilfe.

BEARBEITEN:

Dies ist eigentlich keine Frage zum Nachverfolgen von Lizenzschlüsseln oder zum Aktualisieren von Plug-ins, die nicht auf dem Repo WP gehostet werden. Hier geht es darum, die Einstellungen zwischen zwei Versionen eines Plugins zu aktualisieren, wenn ein Benutzer ein Upgrade durchführt.

Beispiel:

version 1.0.0 hat ein Einstellungsfeld name

Nun, in Version 1.1.0 entscheiden wir, dass wir sowohl Vor- als auch Nachnamen benötigen, also ändern wir die alte Einstellung in first_name und fügen dann eine neue Einstellung last_name hinzu.

Das Übertragen dieser Optionen als Post-Meta für einen benutzerdefinierten Post-Typ ist kein Problem:

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

Dieser Teil ist also einfach. Was ich Probleme damit habe, scheint nicht einfach zu sein, ist dasselbe zu tun, aber für WIDGET-Einstellungen.

Hoffentlich wird dies Verwirrung beseitigen und die Beantwortung erleichtern.

EDIT 2:

Ergebnis von echo '<pre>' . print_r( $widget, true ) . '</pre>'; aus dem ersten obigen Codeabschnitt:

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
)
9
Nick Young

Ich habe einen kurzen Test zum Ändern der Option durchgeführt und es scheint zu funktionieren.

Was ich getan habe ist:

  1. Schrieb ein Widget mit nur 2 Feldern: "Titel" und "Name". Mehrere Instanzen dieses Widgets zu meinen Seitenleisten hinzufügen. Stellen Sie sicher, dass sie im Frontend korrekt angezeigt werden.
  2. Die Klasse wurde so bearbeitet, dass 3 Felder verwendet werden: "Titel" und "Vorname" (anstelle von "Name") und "Nachname" hinzugefügt.
  3. Die Funktion zum Registrieren des Widgets in 'widgets_init' wurde bearbeitet, um eine Funktion aufzurufen, mit der die Widget-Optionen aktualisiert werden:

    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. Schrieb eine einfache Klasse, um Widget-Optionen zu aktualisieren:

    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. Ich habe die Widget-Klasse bearbeitet, um die Option "is_{$widget_name}_updated" innerhalb der update()-Methode zu speichern. Auf diese Weise wird die Updater-Klasse niemals für neue Benutzer aufgerufen, die das alte Widget nie installiert haben

    class My_Example_Widget {
    
        ...
    
        public function update($new_instance, $old_instance) {
            ...
    
            $widget_name = 'my_example_widget';
            update_option("is_{$widget_name}_updated", 1);
        }
    }
    
  6. Ich habe meine Website besucht und die mit alten Optionen gespeicherten Widgets werden ohne Probleme mit neuen Optionen angezeigt. (Natürlich ist "Nachname" immer leer).

Eine gute Idee ist es, die Option "is_{$widget_name}_updated" durch eine Option zu ersetzen, in der die aktuelle Version des Widgets gespeichert ist. Auf diese Weise ist es hilfreich, wenn Sie das nächste Mal ein Update benötigen.

3
gmazzap

Nur um die Einstellungen aus einem anderen Blickwinkel zu betrachten - anstatt alle Einstellungen beim Plugin-Update automatisch zu aktualisieren, prüfen Sie einfach, ob eine "alte" Einstellung vorhanden ist und ordnen Sie sie "neuen" Einstellungen zu:

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;
}
1
TheDeadMedic

Jede Instanz eines Widgets erhält eine eindeutige ID. Ich möchte sagen, das wird ein Prexfix für die Schlüssel für das Widget.

Ich erinnere mich, dass ich vor einiger Zeit darüber gestochert habe, aber ich kann mich nicht erinnern, wie genau das war, sorry.

0
Chief Alchemist