web-dev-qa-db-ja.com

未定義のプロパティ:general-template.phpのstdClass :: $ labels post_type_archive_title()

標準のタグ分類が追加されたカスタム投稿タイプがあります:'taxonomies' => array('post_tag')。このCPTのいくつかの投稿にいくつかのタグを追加しました。これらはテンプレートタグthe_tags()でフロントエンドに表示され、それが生成するリンクはhttp://local.mysite.dev/tag/tag1/という形式です。このようなリンクをクリックすると、tag.phpテンプレートを使用して投稿のないページが生成されますが、?post_type=seron_mycptをURLの最後に追加すると、http://local.mysite.dev/tag/tag1/?post_type=seron_mycpt関連する投稿のあるページ同じテンプレートを使用して生成されますが、今回はdebug.logに次の行も追加します:

PHP Notice:  Undefined property: stdClass::$labels in /...sitepath.../wp-includes/general-template.php on line 665
PHP Notice:  Trying to get property of non-object in /...sitepath.../wp-includes/general-template.php on line 665

これらの通知は、header.phpテンプレートでwp_title()が呼び出されたときに生成されます。書き換えルールに従って、要求はクエリtag=tag1&post_type=seron_mycptに変換されます。

デバッグのために、print_r(get_queried_object());header.phpに入れて、これを取得しました:

MYSITEstdClass Object
(
 [term_id] => 27
 [name] => tag1
 [slug] => tag1
 [term_group] => 0
 [term_taxonomy_id] => 27
 [taxonomy] => post_tag
 [description] =>
 [parent] => 0
 [count] => 2
)

WPはlabelsプロパティを持つCPTオブジェクトを期待しますが、そのプロパティを持たない代わりにこのオブジェクトを取得すると思います。

同じタグで通常のpostにタグを付けると、同じheader.phpおよびtag.phpテンプレートが使用され、http://local.mysite.dev/tag/tag1/ URLを使用するとその投稿が表示されます。 print_r(get_queried_object())は非常によく似たオブジェクトを示していますが、PHP通知はdebug.logで生成されません。たぶんWPはgeneral-template.phpの通知生成行に決して到達しないでしょう。

このオブジェクトが何であり、なぜCPTオブジェクトの代わりに渡されるのか理解できません。誰か説明できますか?

3
seron

これはバグ(私が以前に遭遇したもの)であり、 trac のチケットを使って行うことができます。 )

問題は、複数のis_*クエリフラグをtrueに設定するリクエスト(特に、単一の投稿、ページ、投稿の種類と用語のアーカイブなどのオブジェクトを表すフラグ)から始まります。

これは「照会されたオブジェクト」は1つしか存在できないためです(あなたの場合はそれが用語です)。

wp_title()がふらつきを投げるように見える理由はそれが呼び出す別の関数にあります:

function post_type_archive_title( $prefix = '', $display = true ) {
    if ( ! is_post_type_archive() )
        return;

    $post_type_obj = get_queried_object();
    $title = apply_filters('post_type_archive_title', $post_type_obj->labels->name );

    if ( $display )
        echo $prefix . $title;
    else
        return $title;
}

is_post_type_archiveフラグはtrueなので、照会されたオブジェクトはpost型であると想定し、実際にはtermオブジェクトであるものの未定義のプロパティにアクセスしようとします。

修正が複数のクエリされたオブジェクトの可能性を広げることであるか、またはそれらのより厳密なチェックを実装することであるかどうか、私は確信がありません、そして私はそれをtracで手に入れるでしょう。

更新:エラー(その他の可能性があるもの)を抑制するために、フラグの1つを "オフにする":

add_action( 'parse_query', 'wpse_71157_parse_query' );
function wpse_71157_parse_query( $wp_query )
{
    if ( $wp_query->is_post_type_archive && $wp_query->is_tax )
        $wp_query->is_post_type_archive = false;
}
5
TheDeadMedic

これが私がしたことです。私の分類アーカイブテンプレートでは、追加のdivタグを出力するためにis_post_type_archive()に依存していました。

add_action( 'parse_query', 'orb_parse_query' );

function orb_parse_query( $wp_query ) {  
    global $post_type_obj;

    if ( $wp_query->is_post_type_archive && $wp_query->is_tax ) {
        $post_type_obj = get_queried_object();

        if (empty($post_type_obj->labels)) {
            $post_type_obj->labels = new stdClass();
            $post_type_obj->labels->name = 'dev/hack to fix WordPress Bug';
        }
    }
}
1

助けてくれてありがとう。現在のカスタム投稿タイプの名前を表示するために、lordspaceのソリューションを使用し、それを少し修正しました。

add_action( 'parse_query', 'orb_parse_query' );

function orb_parse_query( $wp_query ) {  
    global $post_type_obj;

    if ( $wp_query->is_post_type_archive && $wp_query->is_tax ) {
        $post_type_obj = get_queried_object();

        if (empty($post_type_obj->labels)) {
            $currentPostType = $wp_query->query['post_type'];
            $currentPostTypeName = get_post_type_object($currentPostType)->labels->name;
            $post_type_obj->labels = new stdClass();
            $post_type_obj->labels->name = $currentPostTypeName;
        }
    }
}
0
Kuzvac