スタッフブログ Staff Blog

Google Analytics APIでサイト内のアクセスランキングを実装(2)

前回Google Analytics APIでサイト内のアクセスランキングを実装する方法をご紹介しましたが、その実装を発展させてCMSと連携する方法をご紹介します。

前回の方法では、ランキングのタイトルやリンク先などをGoogle Analyticsのカスタムディメンションに保存していましたが、その方法ではページの公開後にタイトルやURLなどを変更すると別ページのアクセスとしてカウントされたランキングとなる問題がありました(APIのdata_ga->get()メソッドで複数のカスタムディメンションを指定した際にand検索となっているため)。

今回の実装方法ではその問題を解消し、さらにより多くの情報を取得可能になります。

CMSと連携する仕組み

今回のCMSと連携する方法では、CMSでページを生成した際にCMSが持つページ固有のIDをカスタムディメンションに保存します。
そうすることでカスタムディメンションにタイトルなどの情報を保存する必要がなく、タイトルなどの情報を取り出す際はそのIDを利用してPHPから動的にCMSに保存した情報を取り出すことで実現します。

ページIDはユニークな値であり、作成後に変更されることがありませんのでページ公開後にタイトルを変更した場合でもランキングに影響が出ず、さらに最新のタイトルを反映することが可能になります。

Movable Typeの記事から情報を取得する

今回はMovable Typeの記事として作成したページの情報を取り出す方法をご紹介します。
引数の「$entry_id」はカスタムディメンションに保存したIDを取り出して渡します。

以下のサンプルではMovable Typeの記事からタイトル、公開ステータス、公開日時、パーマリンクを取得しています。

function getEntryObject($entry_id) {
  $mt_dir = '/powercms/app/sites/01/mt/';
  require_once($mt_dir . 'php/mt.php');

  $blog_id = 1;
  $mt = MT::get_instance($blog_id, $mt_dir. 'mt-config.cgi');
  $entry = $mt->db()->fetch_entry($entry_id);
  $permalink = $mt->db()->entry_link($entry_id, 'Individual');

  $entry_obj_value = array();
  if (isset($entry->status) && isset($entry->title) && isset($entry->created_on) && isset($permalink)) {
    $status = $entry->status;
    $title = $entry->title;
    $date = new DateTime($entry->created_on);
    $date = $date->format('y-m-d');
    $url = $permalink;

    $entry_obj_value['status'] = $status;
    $entry_obj_value['title'] = $title;
    $entry_obj_value['date'] = $date;
    $entry_obj_value['url'] = $url;
  }
  return $entry_obj_value;
}

カスタムフィールドの情報を取り出す

カスタムフィールドの情報を取り出す場合は$entry->{'entry_field.カスタムフィールドのベースネーム'}で取り出すことが可能です。

function getEntryObject($entry_id) {
  $mt_dir = '/path/to/mt/';
  require_once($mt_dir . 'php/mt.php');

  $blog_id = 1;
  $mt = MT::get_instance($blog_id, $mt_dir. 'mt-config.cgi');
  $entry = $mt->db()->fetch_entry($entry_id);

  if (isset($entry->{'entry_field.カスタムフィールドのベースネーム'})) {
    $sub_title = $entry->{'entry_field.カスタムフィールドのベースネーム'};
  }
}

Movable Typeの記事から情報を取得してランキングのJSONを返すPHPの実装

では、前回の実装と組み合わせて、Movable Typeの記事から情報を取得してランキングのJSONを返すPHPを実装します。 尚、Movable Typeから記事の情報を動的に取得するように変更したことで記事ステータスが公開中のもののみ表示することが可能です。

これによりランキング入りしたページが削除や非公開となった場合にランキングに表示しない(表示が残る場合はリンク切れとなります)ことが出来ます。

header("Content-Type: application/json; charset=UTF-8");

// ライブラリのパス
require_once 'vendor/autoload.php';
// サービスアカウントを作成した際に取得したJSONのパス
define('KEY_FILE_LOCATION', 'json/auth.json');
// Google AnalyticsのビューID
define('VIEW_ID', 'xxxxxxxxx');

$analytics = initAnalytics();
getPageviewsRanking($analytics, VIEW_ID);

function initAnalytics() {
  $client = new Google_Client();
  $client->setApplicationName('Analytics Reporting');
  $client->setAuthConfig(KEY_FILE_LOCATION);
  $client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
  $analytics = new Google_Service_Analytics($client);
  return $analytics;
}

function getPageviewsRanking($analytics) {
  $json = array(
    'status' => '',
    'message' => '',
    'data' => array()
  );
  $start = isset($_GET['start']) ? htmlspecialchars($_GET['start'], ENT_QUOTES) : '';
  $end = isset($_GET['end']) ? htmlspecialchars($_GET['end'], ENT_QUOTES) : '';
  $is_error = false;
  $error_message = '';

  if (empty($start) || empty($end)) {
    $is_error = true;
    $error_message = 'パラメータが指定されていません。start/endを指定してください。';
  } else if (!strptime($start, '%Y-%m-%d') || !strptime($end, '%Y-%m-%d')) {
    $is_error = true;
    $error_message = 'パラメータの指定が正しくありません。start/endをYYYY-mm-ddの形式で指定してください。';
  }

  if (!$is_error) {
    $results = $analytics->data_ga->get(
      'ga:' . VIEW_ID,
      $start,
      $end,
      'ga:pageviews',
      array(
        'dimensions' => urlencode('ga:dimension1,ga:dimension2'),
        'sort' => urlencode('-ga:pageviews'),
        'max-results' => '10'
      )
    );

    if (count($results->getRows()) > 0) {
      $rows = $results->getRows();
      foreach ($rows as $row) {
        $id = isset($row[1]) ? $row[1] : '';
        $pv = isset($row[2]) ? $row[2] : '';
        $entry_obj_value = getEntryObject($id);
        if (isset($entry_obj_value['status']) && $entry_obj_value['status'] === '2') {
          $entry = array(
            'status' => $entry_obj_value['status'],
            'id' => $id,
            'title' => $entry_obj_value['title'],
            'url' => $entry_obj_value['url'],
            'date' => $entry_obj_value['date'],
            'pv' => $pv
          );
          $json['data'][] = $entry;
          if (count($json['data']) === 10) {
            break;
          }
        }
      }
      if (isset($json['data']) && count($json['data']) > 0) {
        $json['status'] = 'success';
        echo json_encode($json);
      } else {
        $is_error = true;
        $error_message = '指定期間内のランキングがありません。';
      }
    } else {
      $is_error = true;
      $error_message = '指定期間内のランキングがありません。';
    }
  }

  if ($is_error) {
    $json['status'] = 'error';
    $json['message'] = $error_message;
    die(json_encode($json));
  }
}

function getEntryObject($entry_id) {
  $mt_dir = '/powercms/app/sites/01/mt/';
  require_once($mt_dir . 'php/mt.php');

  $blog_id = 1;
  $mt = MT::get_instance($blog_id, $mt_dir. 'mt-config.cgi');
  $entry = $mt->db()->fetch_entry($entry_id);
  $permalink = $mt->db()->entry_link($entry_id, 'Individual');

  $entry_obj_value = array();
  if (isset($entry->status) && isset($entry->title) && isset($entry->created_on) && isset($permalink)) {
    $status = $entry->status;
    $title = $entry->title;
    $date = new DateTime($entry->created_on);
    $date = $date->format('y-m-d');
    $url = $permalink;

    $entry_obj_value['status'] = $status;
    $entry_obj_value['title'] = $title;
    $entry_obj_value['date'] = $date;
    $entry_obj_value['url'] = $url;
  }
  return $entry_obj_value;
}

まとめ

今回はMovable Typeの記事の情報を取り出す方法をご紹介しましたが、DBから情報を取得する手段があれば他CMSにも応用可能です。

また、ランキングに記事のサムネイルや概要文を表示する場合など、より多くの情報を取り出すことが出来ますのでCMSを利用している場合には前回ご紹介した方法よりも良いと言えるでしょう。

お問い合わせ Contact

制作のご依頼、ご相談などは下記のフォームからご連絡ください。