マルチサイトで、Simple GA Rankingを使ってランキングを表示する

# 補足
Simple GA Rankingは今のところ、旧アナリティクス（ユニバーサルアナリティクス）にのみ対応しているような気がするので、GA4を使っているサイトでは、そもそもこのプラグインは使えません。。

# はじめに
WordPressでランキングを表示したいときには、「[WordPress Popular Posts](https://ja.wordpress.org/plugins/wordpress-popular-posts/)」というプラグインが便利ですが、こちらはWordPress本体のDBにアクセス情報などを保存するので、マルチサイトだとDBの容量を圧迫するなどの問題点があります。

そこをカバーするために、Google Analyticsと連動して、サイト内のランキングを表示する「[Simple GA Ranking](http://simple-ga-ranking.org/ja/)」というプラグインがあります。

Google API ConsoleでOAuth認証などを使用しているので、ちょっと敷居が高く感じますが、設定方法は以下の記事でわかりやすく説明されていました↓
[軽量で正確！「Simple GA Ranking」でAnalyticsから人気ランキングをブログに設置しよう](http://simple-ga-ranking.org/ja/)

普通のWordPressのサイトなら問題なく表示できるのですが、マルチサイトで設定する際にハマったので、書いておきます。

[人気記事ランキング「Simple GA Ranking」の設定とカスタマイズ方法](https://www.itti.jp/web-design/simple-ga-ranking/)
↑こちらの記事を読むとスムーズにできたようなので、本当はマルチサイトでも普通に設定できるのかも？

# プラグインの設定
私はマルチサイトで、ランキングを表示したいサイトだけ個別にプラグインを有効化しています。

# 対応１
`filter`のパラメーターを使いましょう。
そこにサイトのスラッグを設定すると、対象のサイトのランキングが取得できます。

ちなみに正規表現は苦手なので、よく分かっていません。

```php
if(function_exists('sga_ranking_get_date')):

    //親サイトのURL
    $networkHomeUrl = network_home_url();

    //現在のサイトのURL
    $homeUrl = get_home_url();

    //サイトのスラッグを取得します
    $siteSlug = str_replace($networkHomeUrl, '', $homeUrl);

    //filterの引数にサイトのスラッグを設定します
    //post_typeなどは、ご自身のサイトごとに合わせてください
    $rankingArgs = [
        'display_count'           => 10,
        'period'                  => 30,
        'post_type'               => 'page',
        'filter'        => 'ga:pagePath=~^/' . $siteSlug . '/',
    ];
    $ranking_data = sga_ranking_get_date($rankingArgs);

    if(!empty($ranking_data)): ?>
        <ul class="ranking-ul">
            <?php foreach($ranking_data as $post_id): 
                $title = get_the_title($post_id);
                ?>
                <li>
                    <a href="<?= get_the_permalink($post_id) ?>">
                        <?php if(has_post_thumbnail($post_id)): ?>
                            <img class="ranking-img" src="<?= get_the_post_thumbnail_url($post_id, [160, 84]); ?>" alt="<?= $title ?>">
                        <?php else: ?>
                            <img class="ranking-img" src="<?= get_template_directory_uri(); ?>/images/no_thumb.jpg" alt="<?= $title ?>">
                        <?php endif; ?>
                        <p class="ranking-page-title"><?= $title ?></p>
                    </a>
                </li>
            <?php endforeach; ?>
        </ul>
    <?php endif;
endif;

```

原因としては、

- マルチサイト全体でGoogle Analyticsを設定している
- プラグインでは、マルチサイト全体のアクセス数をカウントしている
- ランキングの10件を取得するが、対象のサイトには存在しないので、投稿が取得できない。

# 対応２
プラグインの`simple-ga-ranking.php`に、以下の分岐があります。

```php
$id = get_transient($transient_key);

if ( $id !== false ) {
    return  apply_filters( 'sga_ranking_ids', $id);
} else {
    //実際にGoogleアナリティクスから取得する処理
}

```

多分、結果がキャッシュされていないとき、キャッシュが切れているとき、$idは`false`で返ってくる必要があるのですが、なんか入っちゃてます。

このプラグインのコードでは、キャッシュ用で以下の３つの関数を使用しています。

- get_transient
- set_transient
- delete_transient

こちらを、マルチサイト用の関数に置き換えました。

- get_site_transient
- set_site_transient
- delete_site_transient

とりあえず、この関数に置き換えたら、なぜかマルチサイトでもちゃんと動きました！


WordPressにデータベースにキャッシュするための関数があるのは初めて知りました。
この関数でセットした値は、`wp_x_options`テーブルに保存されます。
マルチサイト用の関数で保存した値は`wp_sitemeta`テーブルに保存されます。

WordPressでデータをDBにキャッシュしたいときは

1. `set_transient`関数で、key、value、有効期限をセット
2. `get_transient`関数で、キャッシュされたデータを取得
3. もしキャッシュの有効期限が切れていれば、新しく作り直し

という流れでいい感じですね。


# 余談１
最初は固定ページが取れないのかと試行錯誤していたのですが、原因が分からずプラグインのコードを読んで、ログを出しながらコードを追っていったら、マルチサイトの別のサイトの結果を取得していることが分かりました...
（上位10件なのでね）

合計4時間くらいはこれでハマっていたような気がします。

# 余談２
「Simple GA Ranking」には、デバッグモードがついていますが、こちらはGoogleAnalyticsと連携せずに、投稿を適当に出力してくれる機能です。
ローカルで見た目を修正しようと思っても、ドメインで紐付いているため、ランキングが表示できないという問題があります。
その場合はデバッグモードをONにすると、とりあえず適当に投稿を持ってきてくれるので、見た目などを修正しやすいです。