こんにちは。
記事の中に流行りのネタ(すごーい!とか)を入れてみようと思ったけど、無理矢理感が凄いので諦めてしまった木村です。
さて、お気づきの方もいるかと思いますが、4月1日にホームページとブログがリニューアルしました!(ぱちぱち)
リニューアルにおけるこだわりは他のメンバーに追々語って頂くとして…今回は、リニューアル合わせて「ブログトップにあるPopular Posts(いわゆる人気の記事)をGoogleアナリティクスのデータを元に取得する」というプラグインを作成しましたので、必要な準備や実装手順をご紹介します。
前提条件
- PHP 7.0
- WordPress 4.7.3
何故アナリティクスからの取得を行うのか
ご存じの方も多いと思いますが、WordPressにはアクセス数から人気の記事を計算してよしなにしてくれるプラグインが多数存在します。(代表的なのはWordPress Popular Postsとかですかね)
ただ、これだとウィジェットに追加されるという扱いなので…
今回のように、ヘッダー部に表示したいという場合には不向きでした。
他にも探してみたのですがこれといって見つからず、「どう考えても作った方が早い」という結論に至ったのでサクッと作ってみる事にしました。
準備
そうと決まれば、まずはGoogleアナリティクスから取得する手段を探す所からです。これについてはReporting API v4が唯一無二の選択肢でした。
他のGoogle APIsと同じようにPHPのライブラリが用意されているのがうれしいですね。
APIの有効化
まず最初に、Reporting APIの有効化を行います。
API Managerを開いて、「ダッシュボード」の「APIを有効にする」を選択して、「Google Analytics Reporting API」を有効にします。
画像は有効になった状態のものです。ちなみに、「Analytics API」というのもありますが、これではないので注意が必要です。
また、API Managerを開いたタイミングなどでプロジェクトの作成を指示される場合がありますが、これは画面の指示に従えばOKです。
続けて、認証情報を作成します。
サイドバーから「認証情報」を選択して、「認証情報を作成」から「サービスアカウントキー」を選択します。
すると、こんな画面に推移します。
サービスアカウントは「新しいサービスアカウント」を選択します。
すると、入力フィールドが増えるので、サービスアカウント名とサービスアカウントIDを入力します。
サービスアカウント名とサービスアカウントIDは任意のもので問題ありませんが、「サービスアカウントID@プロジェクトID.iam.gserviceaccount.com」というメールアドレス(のような文字列)は後ほど利用するのでメモしておきます。
キーのタイプはJSONのままでOKです。
全て入力して「作成」を選択すると、認証情報の入ったJSONがダウンロードされるので、保管しておきます。
もし先ほどのメールアドレスをメモし忘れた場合は、「サービスアカウントの管理」から確認できます。
しかし、認証情報の入ったJSONは再発行ができないため、もし無くした場合は再度サービスアカウントキーの作成を再度行う必要があるので注意が必要です。
アナリティクスの設定
アナリティクス側にも設定をする必要があるので、忘れずに行っておきます。
といっても難しいものではなく、参照したいデータのビュー(または、それが属するアカウントやプロパティ)の「ユーザー管理」から、メモしたメールアドレスに対して権限を付与するだけです。
権限は「表示と分析」で大丈夫です。
取得&構築条件
では準備も整ったので実装に…の前に、取得条件や実装における方針を決める必要があります。
今回はシンプルに、「全期間でユニークPV数の多い順」「4件」という方針にしました。
また、テーマ上では「記事タイトル」「リンク先URL」「アイキャッチ画像」を利用するので、関数からはこのあたりの情報を返すそうな中身を構築します。
そして、アクセス毎にAPIへのリクエストを行ってしまうと上限に達してしまう可能性も十分にありますので、キャッシュをデータベースへ保存し、最後の取得から1時間以上経過している場合に最後取得処理を行うよう変更します。
構築
いよいよ本当に実装に入ります…が、その前にAPIライブラリを入れなければなりません。
今回はComposer経由でインストールするので、作業用ディレクトリ上で次のコマンドを実行します。
1 |
$ composer require google/apiclient:^2.0 |
もし手動で入れる場合は、上記ページを参考にしてみてください。
また、先ほどダウンロードしたJSONも設置しておきます。
今回はauthというディレクトリを作成して、その中に設置しました。
そして、プラグイン本体はfunctions.phpの中に記述します。
ここまでの構造を図にするとこんな感じです。
1 2 3 4 5 6 7 8 9 |
. ├── auth │ └── ダウンロードしたJSON.json ├── composer.json ├── composer.lock ├── functions.php └── vendor ├── autoload.php └── ライブラリ色々 |
(ちなみに、こういうディレクトリ構造をテキストで作りたい時はtreeコマンドが便利です。Homebrewから入れました)
そのfunctions.phpの中身はこんな感じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
<?php /* Plugin Name: PopularPosts Description: GoogleAnalyticsから人気の投稿を取得するプラグイン Version: 1.0 Author: SRIA Author URI: https://www.sria.co.jp/ */ // composer読み込み require_once __DIR__ . '/vendor/autoload.php'; // 証明書データ define('KEY_LOCATION', __DIR__ . '/auth/ダウンロードしたJSON.json'); // 取得するビューID define('VIEW_ID', YOUR_VIEW_ID); // 取得する投稿数 define('GET_COUNT', 4); // キャッシュ時間(秒) define('CACHE_TIME', 3600); // テーマから使用する関数 function pp_get_popularposts() { $ret = []; // 最終取得時間を取得 $updateTime = get_option('pp_update_time'); // データが無いか、キャッシュ時間を経過していたら取得 // そうでない場合はキャッシュを取得 if (!$updateTime || $updateTime + CACHE_TIME <= time()) { // クラスの初期化と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); // 日付の範囲指定 $dateRange = new Google_Service_AnalyticsReporting_DateRange(); $dateRange->setStartDate('2011-01-01'); $dateRange->setEndDate('today'); // メトリクス指定 $metrics = []; $configureMetrics = ['ga:uniquePageviews']; 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:uniquePageviews'); $orderBy->setSortOrder('DESCENDING'); // リクエスト構築 $request = new Google_Service_AnalyticsReporting_ReportRequest(); $request->setViewId(VIEW_ID); $request->setDateRanges($dateRange); $request->setMetrics($metrics); $request->setDimensions($dimension); $request->setOrderBys($orderBy); $request->setPageSize(GET_COUNT); // GAに問い合わせ $body = new Google_Service_AnalyticsReporting_GetReportsRequest(); $body->setReportRequests([$request]); $result = $analytics->reports->batchGet($body); // データ取得 // getReports()の結果配列は1つしかないので[0]を指定 $report = $result->getReports()[0]->getData()->getRows(); // 加工 foreach ($report as $r) { // ディメンションをとってくる // 1つしかないので[0]固定で指定 $uri = $r->getDimensions()[0]; // URLを分解して、5番目の要素(投稿名)から投稿データを取得する $params = explode('/', $uri); $posts = get_page_by_path($params[4], 'OBJECT', 'post'); // 取得したデータを展開、及びそれを利用してアイキャッチやパーマリンクを再取得 // それらを結果変数へ設置 $ret[] = [ 'title' => $posts->post_title, 'post_thumbnail' => get_the_post_thumbnail_url($posts->ID), 'permalink' => get_permalink($posts->ID) ]; } // 最終取得時間とキャッシュデータを更新 update_option('pp_posts_data', $ret); update_option('pp_update_time', time()); } else { // キャッシュ取得 $ret = get_option('pp_posts_data'); } return $ret; } |
あとはコピペして頂いて終わりでも良いのですが、せっかくですので上から解説を入れていきます。
1 2 3 4 5 6 7 |
/* Plugin Name: PopularPosts Description: GoogleAnalyticsから人気の投稿を取得するプラグイン Version: 1.0 Author: SRIA Author URI: https://www.sria.co.jp/ */ |
ここは、WordPressのプラグインである事を示しているコメントです。
詳しい内容はCodexに載っていますが、最低限はPlugin Nameのみでも良いようです。
ただ、それだとプラグイン画面が寂しいので、寂しくならない程度の情報を入れています。
1 2 3 4 5 6 7 8 |
// 証明書データ define('KEY_LOCATION', __DIR__ . '/auth/ダウンロードしたJSON.json'); // 取得するビューID define('VIEW_ID', YOUR_VIEW_ID); // 取得する投稿数 define('GET_COUNT', 4); // キャッシュ時間(秒) define('CACHE_TIME', 3600); |
この辺では定数を利用して各種設定を行っています。
内容はコメントにある通りで、CACHE_TIMEが秒換算なのでそこだけ注意が必要です。
また、「YOUR_VIEW_ID」の部分は取得したいデータの含まれるビューのIDに置換してください。そのビューに対して、作成したアカウントの権限が付与されている事が必要です。
1 2 3 |
// テーマから使用する関数 function pp_get_popularposts() { |
いよいよ本実装の部分に入ります。この関数をテーマから呼び出すことで、取得を行います。
1 2 3 4 5 6 |
// 最終取得時間を取得 $updateTime = get_option('pp_update_time'); // データが無いか、キャッシュ時間を経過していたら取得 // そうでない場合はキャッシュを取得 if (!$updateTime || $updateTime + CACHE_TIME <= time()) { |
まずは、get_option()を利用して、”pp_update_time”という値を取得します。この設定には、「最後にデータを取得した時刻(unixtime)」が入っている想定です。
直後のif文で、「そもそも設定が入ってない or 規定秒数を超えている」という場合にアナリティクスからの取得処理を行うようにします。
1 2 3 4 5 6 |
// クラスの初期化と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); |
先ほどのif文を通過した場合の処理を行います。
まずはAPIライブラリの初期化処理を行う必要がありますが、ここでスコープや取得した権限情報のパスを指定します。
setApplicationName()は任意の名前にします。
1 2 3 4 |
// 日付の範囲指定 $dateRange = new Google_Service_AnalyticsReporting_DateRange(); $dateRange->setStartDate('2011-01-01'); $dateRange->setEndDate('today'); |
次にレポート取得に必要な条件の指定を行います。
最初にGoogle_Service_AnalyticsReporting_DateRangeを利用して日付の範囲指定を作成します。
要件に合わせて、setStartDateとsetEndDateを範囲で設定します。
1 2 3 4 5 6 7 8 9 |
// メトリクス指定 $metrics = []; $configureMetrics = ['ga:uniquePageviews']; foreach ($configureMetrics as $metric) { $rMetric = new Google_Service_AnalyticsReporting_Metric(); $rMetric->setExpression($metric); $metrics[] = $rMetric; } |
続けてメトリクスです。
今回はユニークPV数を利用するので、ga:uniquePageviewsを利用します。
複数指定したい場合は、その分だけGoogle_Service_AnalyticsReporting_Metricを増やす必要があります。
上記のコードはそれに対応しているため、そのまま使う場合は$configureMetricsの中身を増やせば複数のメトリクスに対応できます。
1 2 3 |
// ディメンション指定 $dimension = new Google_Service_AnalyticsReporting_Dimension(); $dimension->setName('ga:pagePath'); |
そしてディメンション。
後の処理でパスを利用するので、ga:pagePathを利用します。
ここも複数指定したい場合はGoogle_Service_AnalyticsReporting_Dimensionを増やします。
ちなみに、ディメンションとメトリクスを探すのは「Dimensions & Metrics Explorer」が便利です。
1 2 3 4 |
// ソート順の設定 $orderBy = new Google_Service_AnalyticsReporting_OrderBy(); $orderBy->setFieldName('ga:uniquePageviews'); $orderBy->setSortOrder('DESCENDING'); |
最後にソート順です。
ユニークPV数(ga:uniquePageviews)の多い順(DECENDING)なので、こんな感じの指定をしています。
ここまででは日付・メトリクス・ディメンション・ソート順の設定を行いましたが、他にも様々な指定が可能です。(例えば、ディメンションの絞り込み(DimensionFilter)とか)
リファレンスを見ると色々載っていますので、用途に合わせて探してみると良いでしょう。
項目名に合わせたクラス(Goole_Service_AnalyticsReporting_○○)が用意されているので、それを利用します。
1 2 3 4 5 6 7 8 |
// リクエスト構築 $request = new Google_Service_AnalyticsReporting_ReportRequest(); $request->setViewId(VIEW_ID); $request->setDateRanges($dateRange); $request->setMetrics($metrics); $request->setDimensions($dimension); $request->setOrderBys($orderBy); $request->setPageSize(GET_COUNT); |
ここまで作成した条件を利用して、リクエストを作成します。
最初に設定したビューのIDや取得する件数をここで指定します。
1 2 3 4 5 6 7 8 9 |
// GAに問い合わせ $body = new Google_Service_AnalyticsReporting_GetReportsRequest(); $body->setReportRequests([$request]); $result = $analytics->reports->batchGet($body); // データ取得 // getReports()の結果配列は1つしかないので[0]を指定 $report = $result->getReports()[0]->getData()->getRows(); |
そして、アナリティクスへの問い合わせです。
結果はオブジェクトで返ってきますが、ただ単にパスを取り出したいけなのに中々深い階層にあるので大変です。
今回の場合はgetReports()は配列が1つしかない前提なので[0]を直に指定していますが、条件によって変わるので置き変えてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// 加工 foreach ($report as $r) { // ディメンションをとってくる // 1つしかないので[0]固定で指定 $uri = $r->getDimensions()[0]; // URLを分解して、5番目の要素(投稿名)から投稿データを取得する $params = explode('/', $uri); $posts = get_page_by_path($params[4], 'OBJECT', 'post'); // 取得したデータを展開、及びそれを利用してアイキャッチやパーマリンクを再取得 // それらを結果変数へ設置 $ret[] = [ 'title' => $posts->post_title, 'post_thumbnail' => get_the_post_thumbnail_url($posts->ID), 'permalink' => get_permalink($posts->ID) ]; } |
ディメンションにパスのみ取得するよう指定しましたので、パスしか取れていません。まぁ当たり前ですね。
これを元にタイトルやアイキャッチのURLを取得します。
長いので箇条書きにするとこんな感じです。
- getDimensons()でディメンションを取得
- ディメンションは今回1つしか指定していませんので、[0]を直に指定しています
- explode()で「/」で分解
- 「/blog/年/月/投稿名」というURL構造のため、これで投稿名を取得します
- 投稿名を利用して、get_page_by_path()で記事データを取得
- 取得したデータを元に、タイトルやアイキャッチなどの情報を取得して配列に入れる
という処理をURL毎に行います。
パーマリンクに投稿者が含まれている場合はこの処理となりますが、もし基本や数字ベースの設定になっている場合はURL末尾の数字が記事IDなので、その数字を利用してget_post()で取得する処理に変更します。
1 2 3 |
// 最終取得時間とキャッシュデータを更新 update_option('pp_posts_data', $ret); update_option('pp_update_time', time()); |
最後に、取得した文字列と処理時間を、それぞれ”pp_posts_data”と”pp_update_time”にupdate_option()で書き込みます。
ここまでで、キャッシュを利用しない場合の処理は完了です。
1 2 3 4 |
} else { // キャッシュ取得 $ret = get_option('pp_posts_data'); } |
キャッシュを利用する場合(最初のifで条件に合致しなかった場合)は、get_option()で前回の取得結果を取ってきて変数に入れるだけです。
最後に、取得したデータをreturnして完了です。
後は、WordPressの/wp-content/plugins/以下へ展開し、管理画面から有効にしてテーマから取得する処理を書き込みます。
実行結果は配列となりますので、foreach()で回すといい感じになります。
おわり
という事で、アナリティクスからランキングを取得して表示できるようにするプラグインの作り方ご紹介でした。
作ってみた感想としては、あまり使わない用語(メトリクスとか)があるので、その辺の理解に時間がかかったり、ドキュメントが言うほど充実してないのでサンプルを見ながらとか調べながらというのがあったので少し苦労しました…。
とはいえ、処理自体は複雑ではないので慣れてしまえば簡単に作れそうな気がします。
これを使うと表現の自由度が多少上がりますので、もう少し幅を持たせてみたいなという方は是非試してみてください。