PHP Zend_GdataライブラリでGoogle API バージョン3を利用する

ここ数ヶ月、Google Appsと連携するアプリケーションを仕事と趣味の両方で作っています。
2011年1月現在、PHP Zendライブラリは、Google APIのバージョン3に対応していないため、Appsと連携するアプリを作る場合2Legged OAuthが使えなかったり、追加された関数を使えなかったりと何かと制限が出てきてしまいます。
かと言って、HTTPリクエストとXMLの操作を自分で実装するのはライブラリを使ったとしても若干面倒です。
Google APIプロトコル自体とてもシンプルなので、Zendのライブラリに任せられるところは任せて楽をしたいと思い調べてみました。

インクルードするライブラリ

ZendPHPのGoogleライブラリを利用するにはまず、以下をincludeする必要があります。
今回は、Google DocumentList APIを利用したのでGoogle

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Oauth_Consumer');
Zend_Loader::loadClass('Zend_Gdata_Docs');

Zend_Http_Clientの準備

以下は、2 Legged OAuthによる認証を行うZend_Http_Clientオブジェクトを生成するまでのコードです。

$APPS_OAUTH_OPTIONS = array(
   'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
   'version' => '1.0',
   'signatureMethod' => 'HMAC-SHA1',
   'consumerKey' => 'xxxxxxxxxx.apps.googleusercontent.com', # Consumer key of CakeForm retrieved from Google Marketplace
   'consumerSecret' => 'xxxxxxxxxxx' # Consumer secret of CakeForm retrieved from Google Marketplace
);
$token = new Zend_Oauth_Token_Access();
$httpClient = $token->getHttpClient($APPS_OAUTH_OPTIONS);

Google Appsのコンシューマキーとコンシューマシークレットを確認する方法は、2つの方法があります。

  1. Google Appsドメイン管理から(プレミアエディションのみ、参考RailsでGoogle AppsのOAuthを試す)
  2. Google Apps MarketPlaceに登録するアプリの場合は、My Vendor Profileの画面にある[View OAuth Consumer Key »]で確認できます

Standard Editionの場合は、3Legged OAuthを利用しなくてはならなくなってしまいすが、MarketPlaceに登録して公開しなければプレミアエディション同様のアクセスが可能になります(ライセンス的には微妙そうですが)

Feed URLを指定したデータの取得

次は、アプリにログインしたアカウントがGoogle Docsで参照可能なドキュメントの一覧を表示するまでのコードです。
ここでは、Google AppsアカウントでOpenIDまたはSAML連携によってアプリケーションにシングルサインオンし、セッションにアカウントが登録されているものとします。

$account='hrendoh@infoscoop.org';//実際には$_SESSIONなどからアカウントを取得
$serviceDocs = new Zend_Gdata_Docs($httpClient);
$service_url ='https://docs.google.com/feeds/default/private/full?v=3&xoauth_requestor_id='.urlencode($account);
$feed = $serviceDocs->getFeed($service_url, 'Zend_Gdata_Docs_DocumentListFeed');
echo "<ul>\n";
foreach($feed->entries as $folder){
	echo "  <li>".$folder->title->text."</li>\n";
}
echo "<ul>";

以上の様に、URLを指定してFeedオブジェクトを取得するというコードになっているので、プロトコルのドキュメントを見つつ実装するということが簡単にできるようになります。
ライブラリで関数の動き確認しながら実装するより楽かも。

実行可能なコード全体も載せておきます。

<?php
ini_set('include_path',"/var/www/cakeform/vendors/ZendGdata-1.10.8/library");

require_once 'Zend/Loader.php';
Zend_Loader::loadClass('Zend_Gdata');
Zend_Loader::loadClass('Zend_Oauth_Consumer');
Zend_Loader::loadClass('Zend_Gdata_Docs');

$APPS_OAUTH_OPTIONS = array(
   'requestScheme' => Zend_Oauth::REQUEST_SCHEME_HEADER,
   'version' => '1.0',
   'signatureMethod' => 'HMAC-SHA1',
   'consumerKey' => 'xxxxxxxxxx.apps.googleusercontent.com', # Consumer key of CakeForm retrieved from Google Marketplace
   'consumerSecret' => 'xxxxxxxxxxx' # Consumer secret of CakeForm retrieved from Google Marketplace
);
$token = new Zend_Oauth_Token_Access();
$httpClient = $token->getHttpClient($APPS_OAUTH_OPTIONS);

$account='hrendoh@infoscoop.org';//実際には$_SESSIONなどからアカウントを取得
$serviceDocs = new Zend_Gdata_Docs($httpClient);
$service_url ='https://docs.google.com/feeds/default/private/full?v=3&xoauth_requestor_id='.urlencode($account);
$feed = $serviceDocs->getFeed($service_url, 'Zend_Gdata_Docs_DocumentListFeed');

echo "<meta http-equiv='Content-Type' content='text/html; charset=UTF-8' />\n";
echo "<ul>\n";
foreach($feed->entries as $folder){
	echo "  <li>".$folder->title->text."</li>\n";
}
echo "<ul>";
?>

Zend_Gdata_Queryオブジェクトを使ったデータの取得

Queryオブジェクトを使う場合は、setParam関数でバージョン(v)とxoauth_requestor_idを指定します。
以下は、Google Codeのドキュメントの例ですが、以下の太字の文を追加します。

function retrieveExactTitleMatches($gdClient, $html, $title) {
  $docsQuery = new Zend_Gdata_Docs_Query();
  $docsQuery->setTitle($title);
  $docsQuery->setTitleExact(true);
  $docsQuery->setParam('v','3');
  $docsQuery->setParam('xoauth_requestor_id', $account['Account']['account']);
  $feed = $gdClient->getDocumentListFeed($docsQuery);

  printDocumentsFeed($feed, $html);
}