1 <?xml version="1.0" encoding="UTF-8"?>
3 <sect1 id="zend.gdata.gbase">
4 <title>Using Google Base</title>
7 The Google Base data <acronym>API</acronym> is designed to enable developers to do two
13 Query Google Base data to create applications and mashups.
19 Input and manage Google Base items programmatically.
26 There are two item feeds: snippets feed and customer items feeds. The snippets feed contains
27 all Google Base data and is available to anyone to query against without a need for
28 authentication. The customer items feed is a customer-specific subset of data and only a
29 customer/owner can access this feed to insert, update, or delete their own data. Queries are
30 constructed the same way against both types of feeds.
34 See <ulink url="http://code.google.com/apis/base/">http://code.google.com/apis/base</ulink>
35 for more information about the Google Base <acronym>API</acronym>.
38 <sect2 id="zend.gdata.gbase.connect">
39 <title>Connect To The Base Service</title>
42 The Google Base <acronym>API</acronym>, like all GData <acronym>API</acronym>s, is based
43 off of the Atom Publishing Protocol (APP), an <acronym>XML</acronym> based format for
44 managing web-based resources. Traffic between a client and the Google Base servers
45 occurs over <acronym>HTTP</acronym> and allows for both authenticated and
46 unauthenticated connections.
50 Before any transactions can occur, this connection needs to be made. Creating a
51 connection to the base servers involves two steps: creating an <acronym>HTTP</acronym>
52 client and binding a <classname>Zend_Gdata_Gbase</classname> service instance to that
56 <sect3 id="zend.gdata.gbase.connect.authentication">
57 <title>Authentication</title>
60 The Google Base <acronym>API</acronym> allows access to both public and private base
61 feeds. Public feeds do not require authentication, but are read-only and offer
62 reduced functionality. Private feeds offers the most complete functionality but
63 requires an authenticated connection to the base servers. There are three
64 authentication schemes that are supported by Google Base:
70 <firstterm>ClientAuth</firstterm> provides direct username/password
71 authentication to the base servers. Since this scheme requires that users
72 provide your application with their password, this authentication is only
73 recommended when other authentication schemes are insufficient.
79 <firstterm>AuthSub</firstterm> allows authentication to the base servers via
80 a Google proxy server. This provides the same level of convenience as
81 ClientAuth but without the security risk, making this an ideal choice for
82 web-based applications.
88 The <classname>Zend_Gdata</classname> library provides support for all three
89 authentication schemes. The rest of this chapter will assume that you are familiar
90 the authentication schemes available and how to create an appropriate authenticated
91 connection. For more information, please see section <xref
92 linkend="zend.gdata.introduction.authentication" /> or the <ulink
93 url="http://code.google.com/apis/gdata/auth.html">Authentication Overview in the
94 Google Data <acronym>API</acronym> Developer's Guide</ulink>.
98 <sect3 id="zend.gdata.gbase.connect.service">
99 <title>Create A Service Instance</title>
102 In order to interact with Google Base, this library provides the
103 <classname>Zend_Gdata_Gbase</classname> service class. This class provides a common
104 interface to the Google Data and Atom Publishing Protocol models and assists in
105 marshaling requests to and from the base servers.
109 Once deciding on an authentication scheme, the next step is to create an instance of
110 <classname>Zend_Gdata_Gbase</classname>. This class takes in an instance of
111 <classname>Zend_Http_Client</classname> as a single argument. This provides an
112 interface for AuthSub and ClientAuth authentication, as both of these creation of a
113 special authenticated <acronym>HTTP</acronym> client. If no arguments are provided,
114 an unauthenticated instance of <classname>Zend_Http_Client</classname>
115 will be automatically created.
119 The example below shows how to create a Base service class using ClientAuth
123 <programlisting language="php"><![CDATA[
124 // Parameters for ClientAuth authentication
125 $service = Zend_Gdata_Gbase::AUTH_SERVICE_NAME;
126 $user = "sample.user@gmail.com";
129 // Create an authenticated HTTP client
130 $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
132 // Create an instance of the Base service
133 $service = new Zend_Gdata_Gbase($client);
137 A Base service using AuthSub can be created in a similar, though slightly more
141 <programlisting language="php"><![CDATA[
143 * Retrieve the current URL so that the AuthSub server knows where to
144 * redirect the user after authentication is complete.
146 function getCurrentUrl()
150 // Filter php_self to avoid a security vulnerability.
152 htmlentities(substr($_SERVER['REQUEST_URI'],
154 strcspn($_SERVER['REQUEST_URI'], "\n\r")),
157 if (isset($_SERVER['HTTPS']) &&
158 strtolower($_SERVER['HTTPS']) == 'on') {
159 $protocol = 'https://';
161 $protocol = 'http://';
163 $host = $_SERVER['HTTP_HOST'];
164 if ($_SERVER['HTTP_PORT'] != '' &&
165 (($protocol == 'http://' && $_SERVER['HTTP_PORT'] != '80') ||
166 ($protocol == 'https://' && $_SERVER['HTTP_PORT'] != '443'))) {
167 $port = ':' . $_SERVER['HTTP_PORT'];
171 return $protocol . $host . $port . $php_request_uri;
175 * Obtain an AuthSub authenticated HTTP client, redirecting the user
176 * to the AuthSub server to login if necessary.
178 function getAuthSubHttpClient()
180 global $_SESSION, $_GET;
182 // If there is no AuthSub session or one-time token waiting for us,
183 // redirect the user to the AuthSub server to get one.
184 if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])) {
185 // Parameters to give to AuthSub server
186 $next = getCurrentUrl();
187 $scope = "http://www.google.com/base/feeds/items/";
191 // Redirect the user to the AuthSub server to sign in
193 $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
197 header("HTTP/1.0 307 Temporary redirect");
199 header("Location: " . $authSubUrl);
204 // Convert an AuthSub one-time token into a session token if needed
205 if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
206 $_SESSION['sessionToken'] =
207 Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
210 // At this point we are authenticated via AuthSub and can obtain an
211 // authenticated HTTP client instance
213 // Create an authenticated HTTP client
214 $client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
218 // -> Script execution begins here <-
220 // Make sure http://code.google.com/apis/gdata/reference.html#Queriesthat
221 // the user has a valid session, so we can record the
222 // AuthSub session token once it is available.
225 // Create an instance of the Base service, redirecting the user
226 // to the AuthSub server if necessary.
227 $service = new Zend_Gdata_Gbase(getAuthSubHttpClient());
229 <para>Finally, an unauthenticated server can be created for use with snippets feeds:</para>
230 <programlisting language="php"><![CDATA[
231 // Create an instance of the Base service using an unauthenticated HTTP client
232 $service = new Zend_Gdata_Gbase();
237 <sect2 id="zend.gdata.gbase.retrieve">
238 <title>Retrieve Items</title>
241 You can query customer items feed or snippets feed to retrieve items. It involves two
242 steps, sending a query and iterating through the returned feed.
245 <sect3 id="zend.gdata.gbase.retrieve.query">
246 <title>Send a Structured Query</title>
249 You can send a structured query to retrieve items from your own customer items feed
250 or from the public snippets feed.
254 When retrieving items using the Base <acronym>API</acronym>, specially constructed
255 query <acronym>URL</acronym>s are used to describe what events should be returned.
256 The <classname>Zend_Gdata_Gbase_ItemQuery</classname> and
257 <classname>Zend_Gdata_Gbase_SnippetQuery</classname> classes simplify this task by
258 automatically constructing a query <acronym>URL</acronym> based on provided
262 <sect4 id="zend.gdata.gbase.retrieve.query.customeritems">
263 <title>Query Customer Items Feed</title>
266 To execute a query against the customer items feed, invoke
267 <methodname>newItemQuery()</methodname> and
268 <methodname>getGbaseItemFeed()</methodname> methods:
271 <programlisting language="php"><![CDATA[
272 $service = new Zend_Gdata_Gbase($client);
273 $query = $service->newItemQuery();
274 $query->setBq('[title:Programming]');
275 $query->setOrderBy('modification_time');
276 $query->setSortOrder('descending');
277 $query->setMaxResults('5');
278 $feed = $service->getGbaseItemFeed($query);
282 A full list of these parameters is available at the <ulink
283 url="http://code.google.com/apis/base/items-feed.html#QueParameters">Query
284 parameters section</ulink> of the Customer Items Feed documentation.
288 <sect4 id="zend.gdata.gbase.retrieve.query.snippets">
289 <title>Query Snippets Feed</title>
292 To execute a query against the public snippets feed, invoke
293 <methodname>newSnippetQuery()</methodname> and
294 <methodname>getGbaseSnippetFeed()</methodname> methods:
297 <programlisting language="php"><![CDATA[
298 $service = new Zend_Gdata_Gbase();
299 $query = $service->newSnippetQuery();
300 $query->setBq('[title:Programming]');
301 $query->setOrderBy('modification_time');
302 $query->setSortOrder('descending');
303 $query->setMaxResults('5');
304 $feed = $service->getGbaseSnippetFeed($query);
308 A full list of these parameters is available at the <ulink
309 url="http://code.google.com/apis/base/snippets-feed.html#Parameters">Query
310 parameters section</ulink> of the Snippets Feed documentation.
315 <sect3 id="zend.gdata.gbase.retrieve.iterate">
316 <title>Iterate through the Items</title>
319 Google Base items can contain item-specific attributes such as
320 <code><g:main_ingredient></code> and <code><g:weight></code>.
324 To iterate through all attributes of a given item, invoke
325 <methodname>getGbaseAttributes()</methodname> and iterate through the results:
328 <programlisting language="php"><![CDATA[
329 foreach ($feed->entries as $entry) {
330 // Get all attributes and print out the name and text value of each
332 $baseAttributes = $entry->getGbaseAttributes();
333 foreach ($baseAttributes as $attr) {
334 echo "Attribute " . $attr->name . " : " . $attr->text . "<br>";
340 Or, you can look for specific attribute name and iterate through the results that
344 <programlisting language="php"><![CDATA[
345 foreach ($feed->entries as $entry) {
346 // Print all main ingredients <g:main_ingredient>
347 $baseAttributes = $entry->getGbaseAttribute("main_ingredient");
348 foreach ($baseAttributes as $attr) {
349 echo "Main ingredient: " . $attr->text . "<br>";
356 <sect2 id="zend.gdata.gbase.crud">
357 <title>Insert, Update, and Delete Customer Items</title>
360 A customer/owner can access his own Customer Items feed to insert, update, or delete
361 their items. These operations do not apply to the public snippets feed.
365 You can test a feed operation before it is actually executed by setting the dry-run flag
366 (<varname>$dryRun</varname>) to <constant>TRUE</constant>. Once you are sure that you
367 want to submit the data, set it to <constant>FALSE</constant> to execute the operation.
370 <sect3 id="zend.gdata.gbase.crud.insert">
371 <title>Insert an Item</title>
374 Items can be added by using the <methodname>insertGbaseItem()</methodname> method
375 for the Base service:
378 <programlisting language="php"><![CDATA[
379 $service = new Zend_Gdata_Gbase($client);
380 $newEntry = $service->newItemEntry();
383 $title = "PHP Developer Handbook";
384 $newEntry->title = $service->newTitle(trim($title));
387 $content = "Essential handbook for PHP developers.";
388 $newEntry->content = $service->newContent($content);
389 $newEntry->content->type = 'text';
391 // Define product type
392 $itemType = "Products";
393 $newEntry->itemType = $itemType;
395 // Add item specific attributes
396 $newEntry->addGbaseAttribute("product_type", "book", "text");
397 $newEntry->addGbaseAttribute("price", "12.99 USD", "floatUnit");
398 $newEntry->addGbaseAttribute("quantity", "10", "int");
399 $newEntry->addGbaseAttribute("weight", "2.2 lbs", "numberUnit");
400 $newEntry->addGbaseAttribute("condition", "New", "text");
401 $newEntry->addGbaseAttribute("author", "John Doe", "text");
402 $newEntry->addGbaseAttribute("edition", "First Edition", "text");
403 $newEntry->addGbaseAttribute("pages", "253", "number");
404 $newEntry->addGbaseAttribute("publisher", "My Press", "text");
405 $newEntry->addGbaseAttribute("year", "2007", "number");
406 $newEntry->addGbaseAttribute("payment_accepted", "Google Checkout", "text");
409 $createdEntry = $service->insertGbaseItem($newEntry, $dryRun);
413 <sect3 id="zend.gdata.gbase.crud.modify">
414 <title>Modify an Item</title>
417 You can update each attribute element of an item as you iterate through them:
420 <programlisting language="php"><![CDATA[
422 $newTitle = "PHP Developer Handbook Second Edition";
423 $entry->title = $service->newTitle($newTitle);
425 // Find <g:price> attribute and update the price
426 $baseAttributes = $entry->getGbaseAttribute("price");
427 if (is_object($baseAttributes[0])) {
428 $newPrice = "16.99 USD";
429 $baseAttributes[0]->text = $newPrice;
432 // Find <g:pages> attribute and update the number of pages
433 $baseAttributes = $entry->getGbaseAttribute("pages");
434 if (is_object($baseAttributes[0])) {
436 $baseAttributes[0]->text = $newPages;
438 // Update the attribute type from "number" to "int"
439 if ($baseAttributes[0]->type == "number") {
441 $baseAttributes[0]->type = $newType;
445 // Remove <g:label> attributes
446 $baseAttributes = $entry->getGbaseAttribute("label");
447 foreach ($baseAttributes as $note) {
448 $entry->removeGbaseAttribute($note);
451 // Add new attributes
452 $entry->addGbaseAttribute("note", "PHP 5", "text");
453 $entry->addGbaseAttribute("note", "Web Programming", "text");
455 // Save the changes by invoking save() on the entry object itself
457 $entry->save($dryRun);
459 // Or, save the changes by calling updateGbaseItem() on the service object
461 // $service->updateGbaseItem($entry, $dryRun);
465 After making the changes, either invoke <methodname>save($dryRun)</methodname>
466 method on the <classname>Zend_Gdata_Gbase_ItemEntry</classname> object or call
467 <methodname>updateGbaseItem($entry, $dryRun)</methodname> method on the
468 <classname>Zend_Gdata_Gbase</classname> object to save the changes.
472 <sect3 id="zend.gdata.gbase.crud.delete">
473 <title>Delete an Item</title>
476 You can remove an item by calling <methodname>deleteGbaseItem()</methodname> method:
479 <programlisting language="php"><![CDATA[
481 $service->deleteGbaseItem($entry, $dryRun);
485 Alternatively, you can invoke <methodname>delete()</methodname> on the
486 <classname>Zend_Gdata_Gbase_ItemEntry</classname> object:
489 <programlisting language="php"><![CDATA[
491 $entry->delete($dryRun);