22.10. Google Base の使用法

Google Base データ API は、開発者が以下のことを行えるように設計されています。

アイテムのフィードには二種類があります。snippets フィードと customer items フィードです。 snippets フィードにはすべての Google Base のデータが含まれ、 認証なしで誰でも問い合わせることができます。 customer items フィードは特定の顧客に特化したデータの一部で、 そのカスタマー/オーナーだけがフィードにアクセスしてデータを追加、更新、削除することができます。 どちらのフィードに対しても、クエリの作成方法は同じです。

Google Base API についての詳細は http://code.google.com/apis/base を参照ください。

22.10.1. Base サービスへの接続

Google Base API は、他の GData API と同様に Atom Publishing Protocol (APP) を使用しています。これは、ウェブベースのリソースを扱うための XML 形式のフォーマットです。クライアントと Booble Base サーバとの間は HTTP による通信を行い、認証済みの接続と未認証の接続の両方に対応しています。

トランザクションを実行するには、まずこの接続を作成する必要があります。 Base サーバへの接続を作成するには、次の二段階の手順を踏みます。 まずは HTTP クライアントを作成し、それから Zend_Gdata_Gbase サービスのインスタンスをそのクライアントにバインドします。

22.10.1.1. 認証

Google Base API は、公開 (public) フィードと非公開 (private) フィードの両方にアクセスすることができます。 公開フィードへのアクセスには認証は不要です。 しかし読み込み専用のアクセスとなり、機能も制限されます。 非公開フィードに対してはほぼすべての機能を使用できますが、 Base サーバに対する認証済みの接続が必要となります。 Google Base がサポートする認証方式には三種類あります。

  • ClientAuth は、ユーザ名/パスワードによる認証を Base サーバに対して直接行います。 この方式では、アプリケーションが直接パスワードを扱う必要があります。 したがって、この認証方式を使うのは、他の方式が使えない場合のみにしましょう。

  • AuthSub は、Google プロキシサーバを経由した認証を行います。 ClientAuth と同じくらい簡単に使用でき、セキュリティのリスクもありません。 ウェブベースのアプリケーションでは、これが最も望ましい方式です。

Zend_Gdata ライブラリは、これら三種類の認証方式にすべて対応しています。 本章のこれ以降では、読者が認証方式についてよく知っていること、 そして認証済み接続の作成方法を知っていることを前提として説明を進めます。 詳細な情報は、項22.1.4. 「Google Data クライアント認証」 あるいは Google Data API Developer's Guide の Authentication Overview を参照ください。

22.10.1.2. サービスのインスタンスの作成

Google Base に対する作業を行うために Zend_Gdata_Gbase サービスクラスが用意されています。 このクラスは Google Data および Atom Publishing Protocol に対する共通のインターフェイスを提供し、 Base サーバとの間のリクエストのやりとりを支援します。

使用する認証方式が決まったら、次に行うのは Zend_Gdata_Gbase のインスタンスを作成することです。 このクラスの引数には Zend_Http_Client のインスタンスを指定します。これが AuthSub および ClientAuth 認証へのインターフェイスとなる認証済みの HTTP クライアントです。 引数を省略した場合は、未認証の Zend_Http_Client のインスタンスを自動的に作成します。

以下の例は、ClientAuth 認証を使用した Base サービスクラスを作成するものです。

// ClientAuth 認証用のパラメータ
$service = Zend_Gdata_Gbase::AUTH_SERVICE_NAME;
$user = "sample.user@gmail.com";
$pass = "pa$$w0rd";

// 認証済み HTTP クライアントを作成します
$client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);

// Base サービスのインスタンスを作成します
$service = new Zend_Gdata_Gbase($client);

            

AuthSub を使用した Base サービスの作成方法も同様ですが、少し冗長になります。


/*
 * 現在の URL を取得し、AuthSub サーバが認証完了後に
 * リダイレクトする先を取得できるようにします
 */
function getCurrentUrl()
{
    global $_SERVER;

    // php_self をフィルタリングし、セキュリティ脆弱性を避けます
    $php_request_uri =
        htmlentities(substr($_SERVER['REQUEST_URI'],
                            0,
                            strcspn($_SERVER['REQUEST_URI'], "\n\r")),
                     ENT_QUOTES);

    if (isset($_SERVER['HTTPS']) &&
        strtolower($_SERVER['HTTPS']) == 'on') {
        $protocol = 'https://';
    } else {
        $protocol = 'http://';
    }
    $host = $_SERVER['HTTP_HOST'];
    if ($_SERVER['HTTP_PORT'] != '' &&
        (($protocol == 'http://' && $_SERVER['HTTP_PORT'] != '80') ||
        ($protocol == 'https://' && $_SERVER['HTTP_PORT'] != '443'))) {
        $port = ':' . $_SERVER['HTTP_PORT'];
    } else {
        $port = '';
    }
    return $protocol . $host . $port . $php_request_uri;
}

/**
 * AuthSub 認証済みの HTTP を取得し、必要に応じて
 * AuthSub サーバにリダイレクトします
 */
function getAuthSubHttpClient()
{
    global $_SESSION, $_GET;

    // AuthSub セッションやワンタイムトークンがない場合は、
    // ユーザを AuthSub サーバにリダイレクトしてそれを取得させます
    if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])) {
        // AuthSub サーバに渡すパラメータ
        $next = getCurrentUrl();
        $scope = "http://www.google.com/base/feeds/items/";
        $secure = false;
        $session = true;

        // ユーザを AuthSub サーバにリダイレクトし、サインインさせます

        $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
                                                             $scope,
                                                             $secure,
                                                             $session);
         header("HTTP/1.0 307 Temporary redirect");

         header("Location: " . $authSubUrl);

         exit();
    }

    // AuthSub ワンタイムトークンを、必要に応じてセッションに変換します
    if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
        $_SESSION['sessionToken'] =
            Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
    }

    // この時点で AuthSub による認証がすんでおり、
    // 認証済みの HTTP クライアントのインスタンスを取得することができます

    // 認証済みの HTTP クライアントを作成します
    $client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
    return $client;
}

// -> スクリプトの実行はここから始まります <-

// http://code.google.com/apis/gdata/reference.html#Queriesthat
// より、ユーザは正規のセッションを保持しています。そこで
// AuthSub セッショントークンを保存します
session_start();

// Base サービスのインスタンスを作成し、必要に応じて
// AuthSub サーバにリダイレクトします
$service = new Zend_Gdata_Gbase(getAuthSubHttpClient());

 

最後に、snippets フィード用の未認証のサーバを作成する方法を示します。

// Base サービスのインスタンスを、未認証の HTTP クライアントで作成します
$service = new Zend_Gdata_Gbase();

 

22.10.2. アイテムの取得

customer items フィードや snippets フィードに問い合わせて、 アイテムを取得することができます。 これは、まずクエリを送信して 返ってきたフィードを順に取得するという二段階の手順で行います。

22.10.2.1. 構造化クエリの送信

構造化クエリを送信することで、あなた自身の customer items フィードや公開 snippets フィードの内容を問い合わせることができます。

Base API でデータを取得する際には、特別な構造のクエリ URL を使用してどんなイベントがほしいのかを指定します。 Zend_Gdata_Gbase_ItemQuery および Zend_Gdata_Gbase_SnippetQuery クラスのおかげで、この作業が簡単にできるようになります。 パラメータを指定すると、これらのクラスがクエリ URL を作成してくれるのです。

22.10.2.1.1. Customer Items フィードに対する問い合わせ

customer items フィードに対するクエリを実行するには newItemQuery() メソッドおよび getGbaseItemFeed() メソッドを実行します。

$service = new Zend_Gdata_Gbase($client);
$query = $service->newItemQuery();
$query->setBq('[title:Programming]');
$query->setOrderBy('modification_time');
$query->setSortOrder('descending');
$query->setMaxResults('5');
$feed = $service->getGbaseItemFeed($query);

                

使用できるパラメータの一覧は、Customer Items フィードのドキュメントにある クエリパラメータのセクション を参照ください。

22.10.2.1.2. Snippets フィードに対する問い合わせ

公開 snippets フィードに対するクエリを実行するには newSnippetQuery() メソッドおよび getGbaseSnippetFeed() メソッドを実行します。

$service = new Zend_Gdata_Gbase();
$query = $service->newSnippetQuery();
$query->setBq('[title:Programming]');
$query->setOrderBy('modification_time');
$query->setSortOrder('descending');
$query->setMaxResults('5');
$feed = $service->getGbaseSnippetFeed($query);

                

使用できるパラメータの一覧は、Snippets フィードのドキュメントにある クエリパラメータのセクション を参照ください。

22.10.2.2. アイテムに対する順次処理

Google Base のアイテムには、<g:main_ingredient><g:weight> といったアイテム固有の属性が含まれています。

指定したアイテムのすべての属性を順に処理するには、 getGbaseAttributes() を実行してその結果を処理します。

foreach ($feed->entries as $entry) {
  // すべての属性を取得し、各属性について名前とテキスト値を表示します
  $baseAttributes = $entry->getGbaseAttributes();
  foreach ($baseAttributes as $attr) {
    echo "属性 " . $attr->name . " : " . $attr->text . "<br>";
  }
}

            

あるいは、特定の属性の名前を指定してそれにマッチする結果を取得することもできます。

foreach ($feed->entries as $entry) {
  // すべての主原料 <g:main_ingredient> を表示します
  $baseAttributes = $entry->getGbaseAttribute("main_ingredient");
  foreach ($baseAttributes as $attr) {
    echo "主原料: " . $attr->text . "<br>";
  }
}

            

22.10.3. Customer Items の追加、更新、削除

カスタマー/オーナーは、自分自身の Customer Items フィードに対する追加、更新あるいは削除を行うことができます。 これらの操作は、公開 snippets フィードに対して行うことはできません。

実際に処理を行う前に、どのような操作が行われるのかを確かめることができます。 その場合は dry-run フラグ ($dryRun) を true に設定します。期待通りの結果が得られることを確認したら、このフラグを false にして実際の操作を行います。

22.10.3.1. アイテムの追加

アイテムを追加するには、Base サービスの insertGbaseItem() メソッドを使用します。

$service = new Zend_Gdata_Gbase($client);
$newEntry = $service->newItemEntry();

// タイトルを追加します
$title = "PHP Developer Handbook";
$newEntry->title = $service->newTitle(trim($title));

// コンテンツを追加します
$content = "Essential handbook for PHP developers.";
$newEntry->content = $service->newContent($content);
$newEntry->content->type = 'text';

// 製品の型を定義します
$itemType = "Products";
$newEntry->itemType = $itemType;

// アイテム固有の属性を追加します
$newEntry->addGbaseAttribute("product_type", "book", "text");
$newEntry->addGbaseAttribute("price", "12.99 USD", "floatUnit");
$newEntry->addGbaseAttribute("quantity", "10", "int");
$newEntry->addGbaseAttribute("weight", "2.2 lbs", "numberUnit");
$newEntry->addGbaseAttribute("condition", "New", "text");
$newEntry->addGbaseAttribute("author", "John Doe", "text");
$newEntry->addGbaseAttribute("edition", "First Edition", "text");
$newEntry->addGbaseAttribute("pages", "253", "number");
$newEntry->addGbaseAttribute("publisher", "My Press", "text");
$newEntry->addGbaseAttribute("year", "2007", "number");
$newEntry->addGbaseAttribute("payment_accepted", "Google Checkout", "text");

$dryRun = true;
$createdEntry = $service->insertGbaseItem($newEntry, $dryRun);

            

22.10.3.2. アイテムの変更

アイテムの各属性要素の値を変更することができます。

// タイトルを更新します
$newTitle = "PHP Developer Handbook Second Edition";
$entry->title = $service->newTitle($newTitle);

// <g:price> 属性を探し、価格を更新します
$baseAttributes = $entry->getGbaseAttribute("price");
if (is_object($baseAttributes[0])) {
  $newPrice = "16.99 USD";
  $baseAttributes[0]->text = $newPrice;
}

// <g:pages> 属性を探し、ページ数を更新します
$baseAttributes = $entry->getGbaseAttribute("pages");
if (is_object($baseAttributes[0])) {
  $newPages = "278";
  $baseAttributes[0]->text = $newPages;

  // 属性の型を "number" から "int" に変更します
  if ($baseAttributes[0]->type == "number") {
    $newType = "int";
    $baseAttributes[0]->type = $newType;
  }
}

// <g:label> 属性を削除します
$baseAttributes = $entry->getGbaseAttribute("label");
foreach ($baseAttributes as $note) {
  $entry->removeGbaseAttribute($note);
}

// 新たな属性を追加します
$entry->addGbaseAttribute("note", "PHP 5", "text");
$entry->addGbaseAttribute("note", "Web Programming", "text");

// エントリオブジェクトの save() を実行して変更内容を保存します
$dryRun = true;
$entry->save($dryRun);

// あるいは、サービスオブジェクトの updateGbaseItem() をコールして変更を保存します
// $dryRun = true;
// $service->updateGbaseItem($entry, $dryRun);

            

変更した後は、Zend_Gdata_Gbase_ItemEntry オブジェクトの save($dryRun) メソッドを実行するか Zend_Gdata_Gbase オブジェクトの updateGbaseItem($entry, $dryRun) メソッドをコールしてその内容を保存する必要があります。

22.10.3.3. アイテムの削除

アイテムを削除するには、deleteGbaseItem() メソッドをコールします。

$dryRun = false;
$service->deleteGbaseItem($entry, $dryRun);

            

あるいは、Zend_Gdata_Gbase_ItemEntry オブジェクトの delete() を実行することもできます。

$dryRun = false;
$entry->delete($dryRun);