web-dev-qa-db-ja.com

WordPress 4.4以降がWalker Extensionを壊す

WordPressを4.2.2から4.5.1にアップグレードしたところ、Walkerクラスを拡張した機能が壊れました。 Walkerエクステンション

class ReturnWalker extends Walker{

public $db_fields = array( 'parent' => 'parent', 
                           'id' => 'term_id' );
public $show_all = FALSE;       

/*
*
*   @param array
*   @param object
*   @param int
*   @param
*   @return NULL
*/
public function start_el( &$output, $category, $depth = 0, $args = array(), $current_object_id = 0) {
    if( !is_array($output) )
        $output = array();

    $id = $this->db_fields['id'];
    $parent = $this->db_fields['parent'];

    if( $depth == 0 || (!$category->$parent) ){
        $output[$category->term_id] = $category;
    } else if( $depth > 0){
        $this->search( $output, $category->$parent, $category );
    }
}

/*
*
*   @param array
*   @param int 
*   @param object
*/
private function search( &$output, $key, $category){

    $id = $this->db_fields['id'];
    $parent = $this->db_fields['parent'];


    if( count($output) ){
        foreach( $output as $k => &$object){
            if( $k == $key ){
                $object->children[$category->term_id] = $category;
                return;
            } else if( isset($object->children[$key]) ){
                $this->search( $object->children, $category->$parent, $category );
            }
        }
    } else if( $this->show_all){
        $output[$category->$id] = $category;
    }
}

/*
*   sets the field names used for id and parent id
*   @param array(
*               'id' => string
*               'parent' => string
*          )
*   @return NULL
*/
public function setDbFields( array $db_fields){
    $this->db_fields = array_merge( $this->db_fields, $db_fields );
}
}

「get_the_terms()」を使用して取得したカテゴリを取得し、それをwalkメソッドに渡します。

$breadcrumbs = new ReturnWalker;
$category = get_the_terms( $post->ID, 'category' );
$struct = $breadcrumbs->walk( $category, 0 );

注意深く観察した結果、$ categoryがWP_Termオブジェクトの配列になり、WP_Termクラスがfinalになったことに気付きました。これは、プロパティ "children"を追加する機能に依存していたために拡張が中断されましたが、クラスは変更不可能であるため、もはや不可能です。

最終的な成果は、この機能が、投稿の元になっていたカスタム分類法に基づいてURLとパンくずリストを作成することです。このタイプの問題に対して何か良い解決策がありますか?

更新 -
WP_Termsを模したクラスを作成し、get_the_terms()によって返されたオブジェクトを私の* _Termsクラスにコピーするとうまくいきました。クラスをインスタンス化するときに返されたオブジェクトを渡すと、コンストラクタがヒットし、コアコードの変更を気にせずに制御できるプロパティのコピーが作成されます。

                $categoryTerms = get_the_terms( $post->ID, 'category' );

                foreach( $categoryTerms as $categoryTerm ){
                    $category[] = new MyTerm( $categoryTerm );
                }

                $breadcrumbs = new MyWalker;
                $struct = $breadcrumbs->walk( $category, 0, array());
5
Jon Krane

更新 - WP_Termsを模したクラスを作成し、get_the_terms()によって返されたオブジェクトを私の* _Termsクラスにコピーするとうまくいきました。クラスをインスタンス化するときに返されたオブジェクトを渡すと、コンストラクタがヒットし、コアコードの変更を気にせずに制御できるプロパティのコピーが作成されます。

            $categoryTerms = get_the_terms( $post->ID, 'category' );

            foreach( $categoryTerms as $categoryTerm ){
                $category[] = new MyTerm( $categoryTerm );
            }

            $breadcrumbs = new MyWalker;
            $struct = $breadcrumbs->walk( $category, 0, array());
0
Jon Krane

あなたの最初の解決策はハックでした、そしてそれが失敗したのは当然のことでした。一般に、クラスや将来の開発を管理していないオブジェクトにメソッドや属性を追加しないでください。

正しい方法は、ウォーカーに渡す独自のオブジェクトを作成することです。構築時にカテゴリオブジェクトを渡し、フィールドに値を設定することはカテゴリオブジェクトと同様の方法であるか、またはそのためのアクセサ関数を作成します(フルハッキングの場合は_get()および_set();を使用します)。十分に設計しておけば、ウォーカーコードはまったく変更する必要はなく、初期化だけが変更されます。

3
Mark Kaplun