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());
231 Finally, an unauthenticated server can be created for use with snippets feeds:
234 <programlisting language="php"><![CDATA[
235 // Create an instance of the Base service using an unauthenticated HTTP client
236 $service = new Zend_Gdata_Gbase();
241 <sect2 id="zend.gdata.gbase.retrieve">
242 <title>Retrieve Items</title>
245 You can query customer items feed or snippets feed to retrieve items. It involves two
246 steps, sending a query and iterating through the returned feed.
249 <sect3 id="zend.gdata.gbase.retrieve.query">
250 <title>Send a Structured Query</title>
253 You can send a structured query to retrieve items from your own customer items feed
254 or from the public snippets feed.
258 When retrieving items using the Base <acronym>API</acronym>, specially constructed
259 query <acronym>URL</acronym>s are used to describe what events should be returned.
260 The <classname>Zend_Gdata_Gbase_ItemQuery</classname> and
261 <classname>Zend_Gdata_Gbase_SnippetQuery</classname> classes simplify this task by
262 automatically constructing a query <acronym>URL</acronym> based on provided
266 <sect4 id="zend.gdata.gbase.retrieve.query.customeritems">
267 <title>Query Customer Items Feed</title>
270 To execute a query against the customer items feed, invoke
271 <methodname>newItemQuery()</methodname> and
272 <methodname>getGbaseItemFeed()</methodname> methods:
275 <programlisting language="php"><![CDATA[
276 $service = new Zend_Gdata_Gbase($client);
277 $query = $service->newItemQuery();
278 $query->setBq('[title:Programming]');
279 $query->setOrderBy('modification_time');
280 $query->setSortOrder('descending');
281 $query->setMaxResults('5');
282 $feed = $service->getGbaseItemFeed($query);
286 A full list of these parameters is available at the <ulink
287 url="http://code.google.com/apis/base/items-feed.html#QueParameters">Query
288 parameters section</ulink> of the Customer Items Feed documentation.
292 <sect4 id="zend.gdata.gbase.retrieve.query.snippets">
293 <title>Query Snippets Feed</title>
296 To execute a query against the public snippets feed, invoke
297 <methodname>newSnippetQuery()</methodname> and
298 <methodname>getGbaseSnippetFeed()</methodname> methods:
301 <programlisting language="php"><![CDATA[
302 $service = new Zend_Gdata_Gbase();
303 $query = $service->newSnippetQuery();
304 $query->setBq('[title:Programming]');
305 $query->setOrderBy('modification_time');
306 $query->setSortOrder('descending');
307 $query->setMaxResults('5');
308 $feed = $service->getGbaseSnippetFeed($query);
312 A full list of these parameters is available at the <ulink
313 url="http://code.google.com/apis/base/snippets-feed.html#Parameters">Query
314 parameters section</ulink> of the Snippets Feed documentation.
319 <sect3 id="zend.gdata.gbase.retrieve.iterate">
320 <title>Iterate through the Items</title>
323 Google Base items can contain item-specific attributes such as
324 <emphasis><g:main_ingredient></emphasis> and <emphasis><g:weight></emphasis>.
328 To iterate through all attributes of a given item, invoke
329 <methodname>getGbaseAttributes()</methodname> and iterate through the results:
332 <programlisting language="php"><![CDATA[
333 foreach ($feed->entries as $entry) {
334 // Get all attributes and print out the name and text value of each
336 $baseAttributes = $entry->getGbaseAttributes();
337 foreach ($baseAttributes as $attr) {
338 echo "Attribute " . $attr->name . " : " . $attr->text . "<br>";
344 Or, you can look for specific attribute name and iterate through the results that
348 <programlisting language="php"><![CDATA[
349 foreach ($feed->entries as $entry) {
350 // Print all main ingredients <g:main_ingredient>
351 $baseAttributes = $entry->getGbaseAttribute("main_ingredient");
352 foreach ($baseAttributes as $attr) {
353 echo "Main ingredient: " . $attr->text . "<br>";
360 <sect2 id="zend.gdata.gbase.crud">
361 <title>Insert, Update, and Delete Customer Items</title>
364 A customer/owner can access his own Customer Items feed to insert, update, or delete
365 their items. These operations do not apply to the public snippets feed.
369 You can test a feed operation before it is actually executed by setting the dry-run flag
370 (<varname>$dryRun</varname>) to <constant>TRUE</constant>. Once you are sure that you
371 want to submit the data, set it to <constant>FALSE</constant> to execute the operation.
374 <sect3 id="zend.gdata.gbase.crud.insert">
375 <title>Insert an Item</title>
378 Items can be added by using the <methodname>insertGbaseItem()</methodname> method
379 for the Base service:
382 <programlisting language="php"><![CDATA[
383 $service = new Zend_Gdata_Gbase($client);
384 $newEntry = $service->newItemEntry();
387 $title = "PHP Developer Handbook";
388 $newEntry->title = $service->newTitle(trim($title));
391 $content = "Essential handbook for PHP developers.";
392 $newEntry->content = $service->newContent($content);
393 $newEntry->content->type = 'text';
395 // Define product type
396 $itemType = "Products";
397 $newEntry->itemType = $itemType;
399 // Add item specific attributes
400 $newEntry->addGbaseAttribute("product_type", "book", "text");
401 $newEntry->addGbaseAttribute("price", "12.99 USD", "floatUnit");
402 $newEntry->addGbaseAttribute("quantity", "10", "int");
403 $newEntry->addGbaseAttribute("weight", "2.2 lbs", "numberUnit");
404 $newEntry->addGbaseAttribute("condition", "New", "text");
405 $newEntry->addGbaseAttribute("author", "John Doe", "text");
406 $newEntry->addGbaseAttribute("edition", "First Edition", "text");
407 $newEntry->addGbaseAttribute("pages", "253", "number");
408 $newEntry->addGbaseAttribute("publisher", "My Press", "text");
409 $newEntry->addGbaseAttribute("year", "2007", "number");
410 $newEntry->addGbaseAttribute("payment_accepted", "Google Checkout", "text");
413 $createdEntry = $service->insertGbaseItem($newEntry, $dryRun);
417 <sect3 id="zend.gdata.gbase.crud.modify">
418 <title>Modify an Item</title>
421 You can update each attribute element of an item as you iterate through them:
424 <programlisting language="php"><![CDATA[
426 $newTitle = "PHP Developer Handbook Second Edition";
427 $entry->title = $service->newTitle($newTitle);
429 // Find <g:price> attribute and update the price
430 $baseAttributes = $entry->getGbaseAttribute("price");
431 if (is_object($baseAttributes[0])) {
432 $newPrice = "16.99 USD";
433 $baseAttributes[0]->text = $newPrice;
436 // Find <g:pages> attribute and update the number of pages
437 $baseAttributes = $entry->getGbaseAttribute("pages");
438 if (is_object($baseAttributes[0])) {
440 $baseAttributes[0]->text = $newPages;
442 // Update the attribute type from "number" to "int"
443 if ($baseAttributes[0]->type == "number") {
445 $baseAttributes[0]->type = $newType;
449 // Remove <g:label> attributes
450 $baseAttributes = $entry->getGbaseAttribute("label");
451 foreach ($baseAttributes as $note) {
452 $entry->removeGbaseAttribute($note);
455 // Add new attributes
456 $entry->addGbaseAttribute("note", "PHP 5", "text");
457 $entry->addGbaseAttribute("note", "Web Programming", "text");
459 // Save the changes by invoking save() on the entry object itself
461 $entry->save($dryRun);
463 // Or, save the changes by calling updateGbaseItem() on the service object
465 // $service->updateGbaseItem($entry, $dryRun);
469 After making the changes, either invoke <methodname>save($dryRun)</methodname>
470 method on the <classname>Zend_Gdata_Gbase_ItemEntry</classname> object or call
471 <methodname>updateGbaseItem($entry, $dryRun)</methodname> method on the
472 <classname>Zend_Gdata_Gbase</classname> object to save the changes.
476 <sect3 id="zend.gdata.gbase.crud.delete">
477 <title>Delete an Item</title>
480 You can remove an item by calling <methodname>deleteGbaseItem()</methodname> method:
483 <programlisting language="php"><![CDATA[
485 $service->deleteGbaseItem($entry, $dryRun);
489 Alternatively, you can invoke <methodname>delete()</methodname> on the
490 <classname>Zend_Gdata_Gbase_ItemEntry</classname> object:
493 <programlisting language="php"><![CDATA[
495 $entry->delete($dryRun);