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


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.