플러그인 업그레이드 : 위젯 설정


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

그래서 그 부분은 쉽습니다. 내가 어려움을 겪고있는 것은 쉬운 일이 아닌 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
)

방금 Tutsplus에서이 기사를 보았습니다. 전혀 읽지는 않았지만 동맹국 인 것 같습니다. 라이센스 제어 테마 및 플러그인 업데이트 시스템 만들기
OnethingSimple

@OnethingSimple 답장을 보내 주셔서 감사합니다.하지만 제가 원하는 것 같지는 않습니다. 질문을 더 명확하게하기 위해 업데이트하겠습니다.
Nick Young

우리는 위젯 설정 구조가 읽고있는 것처럼 보일 수 있습니다 (일부 값을 변경해야하더라도). 그것은 무엇이 잘못되고 있는지에 대한 아이디어를 제공하는 데 도움이 될 수 있습니다. 예를 들어 echo "<pre>"입니다. print_r ($ widget, true)입니다. "</ pre>";
Privateer

@Privateer 지금 OP의 맨 아래에 추가되었습니다.
Nick Young

답변:


3

옵션을 변경하는 것에 대한 빠른 테스트를 수행했으며 작동하는 것 같습니다.

내가 한 일은 :

  1. "제목"과 "이름"필드 만있는 위젯을 작성했습니다. 이 위젯의 ​​여러 인스턴스를 사이드 바에 추가하십시오. 프론트 엔드에 올바르게 표시되는지 확인하십시오.
  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대신 후크 에 추가하여 큰 차이가 있습니까? 나는 그들이 동시에 발사되는 것을 확신했다. 당신의 도움을 주셔서 감사합니다.
Nick Young

@NickYoung 후크에는 차이가 없습니다. 그러나 첫 번째 코드 스 니펫 (내 것과 비슷한 코드)에서는 두 번째 (내부) 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.