Google AnalyticsでWordPressのタグとカテゴリのランキングを実装する方法

一休コンシェルジュの開発を担当している @hayatoise です。

概要

何が分かるの?

  • Google Analytics APIを叩いて、タグ( example.com/tag/example )及びカテゴリ( example.com/category/example )のPV数を取得し、それを独自テーブルにインサートする方法です。
  • とりわけ、本記事はWordPressに導入することを想定しています。

どうやってやるの?

  1. 独自テーブル( e.g. term_pageviews )を作成
  2. APIを叩き、データを取得し、タグとカテゴリのデータだけ独自テーブルにインサートするためのバッチファイルを作成
  3. CRONで定期的にバッチファイルを実行

前提条件

  • PHP 5.4.0 以上

本記事が想定しているURLの例

Tag : https://www.example.com/tag/example
Category : https://www.example.com/category/example

確認済みのバージョン

  • WordPress 4.9.1
  • PHP 5.6.X(確認してないが、PHP7でも動くはず)
  • さくらのVPS

準備

Google Analytics Reporting APIの有効化

  1. API Manager にアクセス
  2. APIとサービスの有効化 をクリック
  3. Google Analytics Reporting APIを検索し、有効にする をクリック

認証情報を作成

  1. API Manager に戻る
  2. 左のメニューから 認証情報 を選択
  3. 認証情報を作成 をクリックし、ドロップダウンメニューから サービスアカウントキー を選択

google_setsumei_1.png

4 上記のようにフォームを埋めた上で、作成をクリック
5. 秘密鍵のJSONファイルがダウンロードされる

Google Analyticsの設定

  1. ダウンロードしたJSONファイルを開き、client_email に記載されているメールアドレスをコピー
  2. Google Analyticsにログインし、左のメニューの 管理 をクリック
  3. 任意の ユーザー管理 をクリックし、右上の ボタンもクリック
  4. 先程コピーしたメールアドレスを貼り、表示と分析 にチェックを追加し、ADD する

これで準備は完了です。

実装

バッチファイルのコード

google-analytics.php
<?php

require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/../../../wp-load.php';

// 認証情報のJSONファイルを定義
define( 'KEY_LOCATION', __DIR__ . '/example.json' );
// ビューIDを定義
define( 'VIEW_ID', '123456789' );

$report = getGoogleAnalyticsReport();

global $wpdb;

db_query( 'START TRANSACTION' );
try {
    db_query( 'DELETE FROM term_pageviews;' );
    save_term_pageviews( $report );

    db_query( 'COMMIT' );

} catch ( Exception $e ) {
    echo $e->getMessage() . PHP_EOL;
    db_query( 'ROLLBACK' );
    exit( 1 );
}

/**
 * @return array
 */
function getGoogleAnalyticsReport() {
    // Class及びAPIの初期化
    $client = new Google_Client();
    $client->setApplicationName( 'Analytics Reporting' );
    $client->setAuthConfig( KEY_LOCATION );
    $client->setScopes( [ 'https://www.googleapis.com/auth/analytics.readonly' ] );
    $analytics = new Google_Service_AnalyticsReporting( $client );

    // データ取得範囲の指定(過去1日分)
    $date_range = new Google_Service_AnalyticsReporting_DateRange();
    $date_range->setStartDate( 'yesterday' );
    $date_range->setEndDate( 'yesterday' );

    // メトリクスの指定
    $metrics          = [];
    $configureMetrics = [ 'ga:pageviews' ];
    foreach ( $configureMetrics as $metric ) {
        $rMetric = new Google_Service_AnalyticsReporting_Metric();
        $rMetric->setExpression( $metric );

        $metrics[] = $rMetric;
    }

    // ディメンションの指定
    $dimension = new Google_Service_AnalyticsReporting_Dimension();
    $dimension->setName( 'ga:pagePath' );

    // ソート順の指定
    $orderBy = new Google_Service_AnalyticsReporting_OrderBy();
    $orderBy->setFieldName( 'ga:pageviews' );
    $orderBy->setSortOrder( 'DESCENDING' );

    // リクエストの構築
    $request = new Google_Service_AnalyticsReporting_ReportRequest();
    $request->setViewId( VIEW_ID );
    $request->setDateRanges( $date_range );
    $request->setMetrics( $metrics );
    $request->setDimensions( $dimension );
    $request->setOrderBys( $orderBy );

    // Google Analyticsにレポートをリクエスト
    $body = new Google_Service_AnalyticsReporting_GetReportsRequest();
    $body->setReportRequests( [ $request ] );

    $result = $analytics->reports->batchGet( $body );

    $reports = $result->getReports();

    if ( ! isset( $reports[0] ) ) {
        return [];
    }

    // データを取得
    return $reports[0]->getData()->getRows();
}

/**
 * @param $sql
 *
 * @return int 取得/変更した件数
 * @throws Exception
 */
function db_query( $sql ) {
    global $wpdb;
    $result = $wpdb->query( $sql );
    if ( $result === false ) {
        throw new Exception( 'Failed to execute SQL:' . $sql );
    }

    return $result;
}

/**
 * @param $report
 *
 * @return array
 * @throws Exception
 */
function save_term_pageviews( $report ) {
    global $wpdb;
    // データからTermを絞る
    foreach ( $report as $r ) {
        $uri        = $r->getDimensions()[0];
        $page_views = $r->metrics[0]->values[0];
        $slug       = get_slug( $uri );

        if ( empty( $slug ) ) {
            continue;
        }

        $term_id = $wpdb->get_var(
            $wpdb->prepare(
                "SELECT term_id FROM $wpdb->terms WHERE slug = %s", rawurlencode( $slug )
            )
        );

        if ( is_null( $term_id ) ) {
            printf( "Term not found for slug: %s(%s)\n", $slug, $uri );
            continue;
        }

        $term_id    = intval( $term_id );
        $page_views = intval( $page_views );

        db_query(
            $wpdb->prepare(
                "
        INSERT INTO term_pageviews
        (
          term_id,
          pageviews
        )
        VALUES
        (
          %d,
          %d
        )
        ON DUPLICATE KEY UPDATE
          pageviews = pageviews + VALUES(pageviews)
      ",
                array(
                    $term_id,
                    $page_views
                )
            )
        );
    }
}

/**
 * @param $uri
 *
 * @return string
 */
function get_slug( $uri ) {
    $parts = parse_url( $uri );
    if ( ! isset( $parts['path'] ) ) {
        return '';
    }

    $path = $parts['path'];

    $parts = array_filter( explode( '/', $path ) );

    if ( ! isset( $parts[0] ) || ( $parts[0] !== 'tag' & $parts[0] !== 'category' ) ) {
        return '';
    }

    $slug        = '';
    $page_counts = 0;
    foreach ( $parts as $part ) {
        if ( $part === 'page' ) {
            $page_counts ++;
        } else {
            continue;
        }
    }

    if ( $page_counts === 0 ) {
        $slug = array_pop( $parts );
    } elseif ( $page_counts === 1 ) {
        array_pop( $parts ); // page numberを取り除く
        array_pop( $parts ); // pageを取り除く
        $slug = array_pop( $parts ); // 変数にslugを代入する
    } else {
        echo 'Unexpected Error';
    }

    return $slug ?: '';
}

ディレクトリの構造

├── auth
│   └── example.json
├── google-analytics.php
├── batch.php
├── composer.json
├── composer.lock
├── composer.phar
└── vendor
  • example.json は準備のフェーズでダウンロードしたファイルです。
google-analytics.php
require_once __DIR__ . '/vendor/autoload.php';
require_once __DIR__ . '/../../../wp-load.php';
  • 僕の場合、これらのファイルを wp-content/plugins/batch というディレクトリにまとめています。
batch.php
<?php
/*
Plugin Name: batch
Plugin URI: https://example.com
Description: 独自のバッチファイルを格納するためのプラグイン
Version: 1.0
Author: hayatoise
Author URI: https://example.com/author/hayatoise
*/
  • batch.phpの中身は上記の通りです。WordPressにプラグインとして認識してもらうための説明文です。

テーブルの構造

example.sql
CREATE TABLE `term_pageviews` (
  `term_id` bigint(20) unsigned NOT NULL,
  `pageviews` int(11) unsigned NOT NULL,
  PRIMARY KEY (`term_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
  • term_idpageviews だけのシンプルなテーブル構造です。

データの取得期間を変更する方法

example.php
// データ取得範囲の指定(過去1日分)
$date_range = new Google_Service_AnalyticsReporting_DateRange();
$date_range->setStartDate( 'yesterday' );
$date_range->setEndDate( 'yesterday' );

1週間分のデータを取得したい場合 yesterday から 8daysAgo にしましょう。

example.php
$date_range->setStartDate( '2017-12-18' );
$date_range->setEndDate( '2017-12-19' );

また、日付形式で書くことも可能です。

おまけ

ランキングデータを取得するSQL文

example.sql
SELECT t.*, v.*
FROM wp_terms t
INNER JOIN term_pageviews v ON t.term_id = v.term_id
ORDER BY v.pageviews DESC;

最後に

明日は @zimathon さんの「データ分析基盤、その後」です。

一休.com Developers Blog

参考URL

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.