| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- Reviewed: no -->
- <sect1 id="zend.gdata.gbase">
- <title>Using Google Base</title>
- <para>
- The Google Base data <acronym>API</acronym> is designed to enable developers to do two
- things:
- <itemizedlist>
- <listitem>
- <para>
- Query Google Base data to create applications and mashups.
- </para>
- </listitem>
- <listitem>
- <para>
- Input and manage Google Base items programmatically.
- </para>
- </listitem>
- </itemizedlist>
- </para>
- <para>
- There are two item feeds: snippets feed and customer items feeds. The snippets feed contains
- all Google Base data and is available to anyone to query against without a need for
- authentication. The customer items feed is a customer-specific subset of data and only a
- customer/owner can access this feed to insert, update, or delete their own data. Queries are
- constructed the same way against both types of feeds.
- </para>
- <para>
- See <ulink url="http://code.google.com/apis/base/">http://code.google.com/apis/base</ulink>
- for more information about the Google Base <acronym>API</acronym>.
- </para>
- <sect2 id="zend.gdata.gbase.connect">
- <title>Connect To The Base Service</title>
- <para>
- The Google Base <acronym>API</acronym>, like all GData <acronym>API</acronym>s, is based
- off of the Atom Publishing Protocol (APP), an <acronym>XML</acronym> based format for
- managing web-based resources. Traffic between a client and the Google Base servers
- occurs over <acronym>HTTP</acronym> and allows for both authenticated and
- unauthenticated connections.
- </para>
- <para>
- Before any transactions can occur, this connection needs to be made. Creating a
- connection to the base servers involves two steps: creating an <acronym>HTTP</acronym>
- client and binding a <classname>Zend_Gdata_Gbase</classname> service instance to that
- client.
- </para>
- <sect3 id="zend.gdata.gbase.connect.authentication">
- <title>Authentication</title>
- <para>
- The Google Base <acronym>API</acronym> allows access to both public and private base
- feeds. Public feeds do not require authentication, but are read-only and offer
- reduced functionality. Private feeds offers the most complete functionality but
- requires an authenticated connection to the base servers. There are three
- authentication schemes that are supported by Google Base:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <firstterm>ClientAuth</firstterm> provides direct username/password
- authentication to the base servers. Since this scheme requires that users
- provide your application with their password, this authentication is only
- recommended when other authentication schemes are insufficient.
- </para>
- </listitem>
- <listitem>
- <para>
- <firstterm>AuthSub</firstterm> allows authentication to the base servers via
- a Google proxy server. This provides the same level of convenience as
- ClientAuth but without the security risk, making this an ideal choice for
- web-based applications.
- </para>
- </listitem>
- </itemizedlist>
- <para>
- The <classname>Zend_Gdata</classname> library provides support for all three
- authentication schemes. The rest of this chapter will assume that you are familiar
- the authentication schemes available and how to create an appropriate authenticated
- connection. For more information, please see the <link
- linkend="zend.gdata.introduction.authentication">authentication section</link>
- or the <ulink url="http://code.google.com/apis/gdata/auth.html">Authentication
- Overview in the Google Data <acronym>API</acronym> Developer's Guide</ulink>.
- </para>
- </sect3>
- <sect3 id="zend.gdata.gbase.connect.service">
- <title>Create A Service Instance</title>
- <para>
- In order to interact with Google Base, this library provides the
- <classname>Zend_Gdata_Gbase</classname> service class. This class provides a common
- interface to the Google Data and Atom Publishing Protocol models and assists in
- marshaling requests to and from the base servers.
- </para>
- <para>
- Once deciding on an authentication scheme, the next step is to create an instance of
- <classname>Zend_Gdata_Gbase</classname>. This class takes in an instance of
- <classname>Zend_Http_Client</classname> as a single argument. This provides an
- interface for AuthSub and ClientAuth authentication, as both of these creation of a
- special authenticated <acronym>HTTP</acronym> client. If no arguments are provided,
- an unauthenticated instance of <classname>Zend_Http_Client</classname>
- will be automatically created.
- </para>
- <para>
- The example below shows how to create a Base service class using ClientAuth
- authentication:
- </para>
- <programlisting language="php"><![CDATA[
- // Parameters for ClientAuth authentication
- $service = Zend_Gdata_Gbase::AUTH_SERVICE_NAME;
- $user = "sample.user@gmail.com";
- $pass = "pa$$w0rd";
- // Create an authenticated HTTP client
- $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
- // Create an instance of the Base service
- $service = new Zend_Gdata_Gbase($client);
- ]]></programlisting>
- <para>
- A Base service using AuthSub can be created in a similar, though slightly more
- lengthy fashion:
- </para>
- <programlisting language="php"><![CDATA[
- /*
- * Retrieve the current URL so that the AuthSub server knows where to
- * redirect the user after authentication is complete.
- */
- function getCurrentUrl()
- {
- global $_SERVER;
- // Filter php_self to avoid a security vulnerability.
- $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;
- }
- /**
- * Obtain an AuthSub authenticated HTTP client, redirecting the user
- * to the AuthSub server to login if necessary.
- */
- function getAuthSubHttpClient()
- {
- global $_SESSION, $_GET;
- // If there is no AuthSub session or one-time token waiting for us,
- // redirect the user to the AuthSub server to get one.
- if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])) {
- // Parameters to give to AuthSub server
- $next = getCurrentUrl();
- $scope = "http://www.google.com/base/feeds/items/";
- $secure = false;
- $session = true;
- // Redirect the user to the AuthSub server to sign in
- $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
- $scope,
- $secure,
- $session);
- header("HTTP/1.0 307 Temporary redirect");
- header("Location: " . $authSubUrl);
- exit();
- }
- // Convert an AuthSub one-time token into a session token if needed
- if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
- $_SESSION['sessionToken'] =
- Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
- }
- // At this point we are authenticated via AuthSub and can obtain an
- // authenticated HTTP client instance
- // Create an authenticated HTTP client
- $client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
- return $client;
- }
- // -> Script execution begins here <-
- // Make sure http://code.google.com/apis/gdata/reference.html#Queriesthat
- // the user has a valid session, so we can record the
- // AuthSub session token once it is available.
- session_start();
- // Create an instance of the Base service, redirecting the user
- // to the AuthSub server if necessary.
- $service = new Zend_Gdata_Gbase(getAuthSubHttpClient());
- ]]></programlisting>
- <para>
- Finally, an unauthenticated server can be created for use with snippets feeds:
- </para>
- <programlisting language="php"><![CDATA[
- // Create an instance of the Base service using an unauthenticated HTTP client
- $service = new Zend_Gdata_Gbase();
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.gbase.retrieve">
- <title>Retrieve Items</title>
- <para>
- You can query customer items feed or snippets feed to retrieve items. It involves two
- steps, sending a query and iterating through the returned feed.
- </para>
- <sect3 id="zend.gdata.gbase.retrieve.query">
- <title>Send a Structured Query</title>
- <para>
- You can send a structured query to retrieve items from your own customer items feed
- or from the public snippets feed.
- </para>
- <para>
- When retrieving items using the Base <acronym>API</acronym>, specially constructed
- query <acronym>URL</acronym>s are used to describe what events should be returned.
- The <classname>Zend_Gdata_Gbase_ItemQuery</classname> and
- <classname>Zend_Gdata_Gbase_SnippetQuery</classname> classes simplify this task by
- automatically constructing a query <acronym>URL</acronym> based on provided
- parameters.
- </para>
- <sect4 id="zend.gdata.gbase.retrieve.query.customeritems">
- <title>Query Customer Items Feed</title>
- <para>
- To execute a query against the customer items feed, invoke
- <methodname>newItemQuery()</methodname> and
- <methodname>getGbaseItemFeed()</methodname> methods:
- </para>
- <programlisting language="php"><![CDATA[
- $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);
- ]]></programlisting>
- <para>
- A full list of these parameters is available at the <ulink
- url="http://code.google.com/apis/base/items-feed.html#QueParameters">Query
- parameters section</ulink> of the Customer Items Feed documentation.
- </para>
- </sect4>
- <sect4 id="zend.gdata.gbase.retrieve.query.snippets">
- <title>Query Snippets Feed</title>
- <para>
- To execute a query against the public snippets feed, invoke
- <methodname>newSnippetQuery()</methodname> and
- <methodname>getGbaseSnippetFeed()</methodname> methods:
- </para>
- <programlisting language="php"><![CDATA[
- $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);
- ]]></programlisting>
- <para>
- A full list of these parameters is available at the <ulink
- url="http://code.google.com/apis/base/snippets-feed.html#Parameters">Query
- parameters section</ulink> of the Snippets Feed documentation.
- </para>
- </sect4>
- </sect3>
- <sect3 id="zend.gdata.gbase.retrieve.iterate">
- <title>Iterate through the Items</title>
- <para>
- Google Base items can contain item-specific attributes such as
- <emphasis><g:main_ingredient></emphasis> and <emphasis><g:weight></emphasis>.
- </para>
- <para>
- To iterate through all attributes of a given item, invoke
- <methodname>getGbaseAttributes()</methodname> and iterate through the results:
- </para>
- <programlisting language="php"><![CDATA[
- foreach ($feed->entries as $entry) {
- // Get all attributes and print out the name and text value of each
- // attribute
- $baseAttributes = $entry->getGbaseAttributes();
- foreach ($baseAttributes as $attr) {
- echo "Attribute " . $attr->name . " : " . $attr->text . "<br>";
- }
- }
- ]]></programlisting>
- <para>
- Or, you can look for specific attribute name and iterate through the results that
- match:
- </para>
- <programlisting language="php"><![CDATA[
- foreach ($feed->entries as $entry) {
- // Print all main ingredients <g:main_ingredient>
- $baseAttributes = $entry->getGbaseAttribute("main_ingredient");
- foreach ($baseAttributes as $attr) {
- echo "Main ingredient: " . $attr->text . "<br>";
- }
- }
- ]]></programlisting>
- </sect3>
- </sect2>
- <sect2 id="zend.gdata.gbase.crud">
- <title>Insert, Update, and Delete Customer Items</title>
- <para>
- A customer/owner can access his own Customer Items feed to insert, update, or delete
- their items. These operations do not apply to the public snippets feed.
- </para>
- <para>
- You can test a feed operation before it is actually executed by setting the dry-run flag
- (<varname>$dryRun</varname>) to <constant>TRUE</constant>. Once you are sure that you
- want to submit the data, set it to <constant>FALSE</constant> to execute the operation.
- </para>
- <sect3 id="zend.gdata.gbase.crud.insert">
- <title>Insert an Item</title>
- <para>
- Items can be added by using the <methodname>insertGbaseItem()</methodname> method
- for the Base service:
- </para>
- <programlisting language="php"><![CDATA[
- $service = new Zend_Gdata_Gbase($client);
- $newEntry = $service->newItemEntry();
- // Add title
- $title = "PHP Developer Handbook";
- $newEntry->title = $service->newTitle(trim($title));
- // Add some content
- $content = "Essential handbook for PHP developers.";
- $newEntry->content = $service->newContent($content);
- $newEntry->content->type = 'text';
- // Define product type
- $itemType = "Products";
- $newEntry->itemType = $itemType;
- // Add item specific attributes
- $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);
- ]]></programlisting>
- </sect3>
- <sect3 id="zend.gdata.gbase.crud.modify">
- <title>Modify an Item</title>
- <para>
- You can update each attribute element of an item as you iterate through them:
- </para>
- <programlisting language="php"><![CDATA[
- // Update the title
- $newTitle = "PHP Developer Handbook Second Edition";
- $entry->title = $service->newTitle($newTitle);
- // Find <g:price> attribute and update the price
- $baseAttributes = $entry->getGbaseAttribute("price");
- if (is_object($baseAttributes[0])) {
- $newPrice = "16.99 USD";
- $baseAttributes[0]->text = $newPrice;
- }
- // Find <g:pages> attribute and update the number of pages
- $baseAttributes = $entry->getGbaseAttribute("pages");
- if (is_object($baseAttributes[0])) {
- $newPages = "278";
- $baseAttributes[0]->text = $newPages;
- // Update the attribute type from "number" to "int"
- if ($baseAttributes[0]->type == "number") {
- $newType = "int";
- $baseAttributes[0]->type = $newType;
- }
- }
- // Remove <g:label> attributes
- $baseAttributes = $entry->getGbaseAttribute("label");
- foreach ($baseAttributes as $note) {
- $entry->removeGbaseAttribute($note);
- }
- // Add new attributes
- $entry->addGbaseAttribute("note", "PHP 5", "text");
- $entry->addGbaseAttribute("note", "Web Programming", "text");
- // Save the changes by invoking save() on the entry object itself
- $dryRun = true;
- $entry->save($dryRun);
- // Or, save the changes by calling updateGbaseItem() on the service object
- // $dryRun = true;
- // $service->updateGbaseItem($entry, $dryRun);
- ]]></programlisting>
- <para>
- After making the changes, either invoke <methodname>save($dryRun)</methodname>
- method on the <classname>Zend_Gdata_Gbase_ItemEntry</classname> object or call
- <methodname>updateGbaseItem($entry, $dryRun)</methodname> method on the
- <classname>Zend_Gdata_Gbase</classname> object to save the changes.
- </para>
- </sect3>
- <sect3 id="zend.gdata.gbase.crud.delete">
- <title>Delete an Item</title>
- <para>
- You can remove an item by calling <methodname>deleteGbaseItem()</methodname> method:
- </para>
- <programlisting language="php"><![CDATA[
- $dryRun = false;
- $service->deleteGbaseItem($entry, $dryRun);
- ]]></programlisting>
- <para>
- Alternatively, you can invoke <methodname>delete()</methodname> on the
- <classname>Zend_Gdata_Gbase_ItemEntry</classname> object:
- </para>
- <programlisting language="php"><![CDATA[
- $dryRun = false;
- $entry->delete($dryRun);
- ]]></programlisting>
- </sect3>
- </sect2>
- </sect1>
|