「Cocoon」のカテゴリー別人気記事が表示されない原因の調査と対応

WordPress WordPress

WordPressテーマ「Cocoon」を使用していたところ、サイドバーに設置したカテゴリー別人気記事ランキングがなぜか表示されませんでした。
その原因の調査でいろいろと調べました。

なお、今回のバージョンは以下の通りです。

  • Cocoon 1.5.5.1
スポンサーリンク

WordPressテーマ「Cocoon」の人気記事ランキング

Cocoonで人気記事ランキングを表示させるには、「Cocoon設定」⇒「アクセス集計」でアクセス集計を有効化しておく必要があります。

Cocoonカテゴリー別人気記事ランキング

そして、人気記事ランキングのウィジェットが用意されているので、それを使って任意の場所に設置することができます。

Cocoonカテゴリー別人気記事ランキング

ウィジェットの設定では、以下の2つの表示モードを選択できます。

  • 全ての人気記事
  • カテゴリ別人気記事

「全ての人気記事」は全記事のランキングで、全てのページで表示されます。
一方、「カテゴリ別人気記事」はカテゴリごとのランキングなので、投稿・カテゴリページで表示され、トップページやタグページなどでは表示されなくなります。

そして、「全ての人気記事」を選択すると問題なくランキングが表示されるのですが、「カテゴリ別人気記事」を選択すると、投稿ページやカテゴリーページを見ても画面には「人気記事は見つかりませんでした。」と出ています…なぜ?

Cocoonカテゴリー別人気記事ランキング

PV数は増えているので集計はされているのに…。

Cocoonカテゴリー別人気記事ランキング

カテゴリー別人気記事が表示されない原因の調査

ひとまず思い当たるところから、以下の内容を見ていきました。

  • 設定の漏れ
  • 競合するプラグインなど
  • キャッシュ

しかし、Cocoonの設定でそれらしきものも見当たらず、ググっても有益な情報は見つからず…。
キャッシュ系のプラグインやアクセス集計のプラグインは入れておらず…。
Cocoonのキャッシュを削除して、ブラウザキャッシュを削除して、サーバーのキャッシュ機能を無効にして、ブラウザをプライベートモードで閲覧しても変わらず…。

ローカルでデバッグして原因が判明

仕方なくローカル環境でデバッグして、表示されない原因を探りました。
WordPressのデバッグ方法については、こちらの記事を参照してください。

人気記事ランキングは独自のウィジェットが作られているので、ウィジェットを追加するWordPressの関数は「register_widget」だから、文字列検索してみるとそれっぽいのが見つかりました。
そこから以下の順に辿り、「access-func.php」に辿り着きます。

  1. cocoon-master\lib\widgets\popular-entries.php
    • PopularEntryWidgetItem::widget
  2. cocoon-master\lib\html-forms.php
    • generate_popular_entries_tag
  3. cocoon-master\lib\page-access\access-func.php
    • get_access_ranking_records

「access-func.php」内の「get_access_ranking_records」関数で人気記事のデータを以下のようなSQLで取得していますが、これの結果が0件になっています。

SELECT
    ID,
    sum_count,
    post_title,
    post_author,
    post_date,
    post_modified,
    post_status,
    post_type,
    comment_count
FROM
    (
        SELECT
            terms_accesses.post_id,
            SUM(terms_accesses.count) AS sum_count,
            terms_accesses.term_taxonomy_id,
            terms_accesses.taxonomy
        FROM
            (
                #カテゴリとアクセステーブルを内部結合してグルーピングし並び替えた結果
                SELECT
                    wp_cocoon_accesses.post_id,
                    wp_cocoon_accesses.count,
                    wp_term_relationships.term_taxonomy_id,
                    wp_term_taxonomy.taxonomy
                FROM
                    wp_term_relationships
                    INNER JOIN
                        wp_cocoon_accesses
                    ON  wp_term_relationships.object_id = wp_cocoon_accesses.post_id
                    INNER JOIN
                        wp_term_taxonomy
                    ON  wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id
                WHERE
                    wp_cocoon_accesses.post_type = 'post'
                AND wp_cocoon_accesses.date BETWEEN '2019-01-16' AND '2019-01-23'
                AND wp_term_relationships.term_taxonomy_id IN(170)
                AND wp_term_taxonomy.taxonomy = 'category' #WHERE句
                GROUP BY
                    wp_cocoon_accesses.id
            ) AS terms_accesses #カテゴリとアクセステーブルを内部結合した仮の名前
        GROUP BY
            terms_accesses.post_id
        ORDER BY
            sum_count DESC
        LIMIT 5
    ) AS ranks_posts
    INNER JOIN
        wp_posts
    ON  ranks_posts.post_id = wp_posts.id
WHERE
    post_status = 'publish'
AND post_type = 'post'

なぜ0件なのか、SQLを細かく分けて実行していくと、入れ子になっている一番内側のWHERE句の条件「wp_term_relationships.term_taxonomy_id IN(170)」が原因のようです。

WordPress Codexを参考に、カテゴリー関係のテーブル「wp_terms」「wp_term_taxonomy」「wp_term_relationships」を順に見ていくと、実データは以下のようになっています。

「wp_terms」:カテゴリーのデータが保存されているテーブル。

term_idnameslugterm_group
170Windowswindows0

「wp_term_taxonomy」:カテゴリーの分類用テーブル。

term_taxonomy_idterm_idtaxonomydescriptionparentcount
284170category046

「wp_term_relationships」:記事とカテゴリーを関連付けるテーブル。

object_idterm_taxonomy_idterm_order
58712840

プログラムでカテゴリーID(term_id):170を取得してSQLの条件を組み立てていますが、term_taxonomy_idに対して検索しており、284と一致せず、0件になっているようです。

しかし、別のWordPressサイトのデータを見てみると、term_idとterm_taxonomy_idは一致していて問題なくカテゴリー別人気記事が表示されているんですよね…。

本来は一致しているものなのか?
それとも、カテゴリー・タグの見直しやサーバー・ドメイン移行など行って運用してきて、いろいろと修正を加えてきましたので、それで一致しなくなったのか?
謎のままです。

カテゴリー別人気記事を表示させるように修正

ということで、一旦プログラムを修正してカテゴリー別人気記事を表示させました。
「access-func.php」内の条件設定箇所を1行コメントアウトにして、以下のようにterm_idに対する条件へと修正しました。

//カテゴリー指定
    if (is_ids_exist($cat_ids)) {
      $cat_ids = implode(',', $cat_ids);
      //$where .= " AND {$term_relationships}.term_taxonomy_id IN ({$cat_ids}) ".PHP_EOL;
      $where .= " AND {$term_taxonomy}.term_id IN ({$cat_ids}) ".PHP_EOL;
    }

これで、カテゴリーページや投稿ページで属するカテゴリーの人気記事が表示されるようになりました。

Cocoonカテゴリー別人気記事ランキング

この件は、後でフォーラムで聞いてみたいと思います。
以上です。

【2019年1月29日 追記】最新テーマで問題対応済み

Cocoonフォーラムで問い合わせたところ、こちらの問題の対応をソースコードに反映していただきました。
GitHubの最新のテーマでは対応済みです。
WordPressのテーマ更新の配信はもう少し後で、v1.5.7以降で対応済みのようです。

スポンサーリンク
スポンサーリンク
WordPress
えふめんをフォローする
この記事が気に入ったら
いいね!しよう
最新情報をお届けします。
俺の開発研究所

コメント

  1. こむたん より:

    まさにこれと同じ理由でかなり前から悩んでいたので助かりました!

  2. えふめん えふめん より:

    >こむたんさん
    コメントありがとうございます。
    お役に立てて良かったです。
    Cocoonフォーラムで聞いてみたところ、早速対応していただき、この問題の対応をソースコードに反映してくれました。
    最新のテーマで対応済みです。
    WordPressでのテーマ更新の配信はもう少し後で、v1.5.7以降で対応済みのようです。

タイトルとURLをコピーしました