Zend_Gdata_Gbase.xml 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.gdata.gbase">
  4. <title>Using Google Base</title>
  5. <para>
  6. The Google Base data <acronym>API</acronym> is designed to enable developers to do two things:
  7. <itemizedlist>
  8. <listitem>
  9. <para>
  10. Query Google Base data to create applications and mashups.
  11. </para>
  12. </listitem>
  13. <listitem>
  14. <para>
  15. Input and manage Google Base items programmatically.
  16. </para>
  17. </listitem>
  18. </itemizedlist>
  19. </para>
  20. <para>
  21. 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.
  22. </para>
  23. <para>
  24. See <ulink url="http://code.google.com/apis/base/">http://code.google.com/apis/base</ulink>
  25. for more information about the Google Base <acronym>API</acronym>.
  26. </para>
  27. <sect2 id="zend.gdata.gbase.connect">
  28. <title>Connect To The Base Service</title>
  29. <para>
  30. 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.
  31. </para>
  32. <para>
  33. 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
  34. <classname>Zend_Gdata_Gbase</classname> service instance to that client.
  35. </para>
  36. <sect3 id="zend.gdata.gbase.connect.authentication">
  37. <title>Authentication</title>
  38. <para>
  39. 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:
  40. </para>
  41. <itemizedlist>
  42. <listitem>
  43. <para>
  44. <firstterm>ClientAuth</firstterm>
  45. 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.
  46. </para>
  47. </listitem>
  48. <listitem>
  49. <para>
  50. <firstterm>AuthSub</firstterm>
  51. 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.
  52. </para>
  53. </listitem>
  54. </itemizedlist>
  55. <para>
  56. The <classname>Zend_Gdata</classname>
  57. 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 section <xref linkend="zend.gdata.introduction.authentication" />.
  58. or the
  59. <ulink url="http://code.google.com/apis/gdata/auth.html">Authentication Overview in the Google Data <acronym>API</acronym> Developer's Guide</ulink>.
  60. </para>
  61. </sect3>
  62. <sect3 id="zend.gdata.gbase.connect.service">
  63. <title>Create A Service Instance</title>
  64. <para>
  65. In order to interact with Google Base, this library provides the
  66. <classname>Zend_Gdata_Gbase</classname>
  67. 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.
  68. </para>
  69. <para>
  70. Once deciding on an authentication scheme, the next step is to create an instance of
  71. <classname>Zend_Gdata_Gbase</classname>
  72. . This class takes in an instance of
  73. <classname>Zend_Http_Client</classname>
  74. 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
  75. <classname>Zend_Http_Client</classname>
  76. will be automatically created.
  77. </para>
  78. <para>
  79. The example below shows how to create a Base service class using ClientAuth authentication:
  80. </para>
  81. <programlisting language="php"><![CDATA[
  82. // Parameters for ClientAuth authentication
  83. $service = Zend_Gdata_Gbase::AUTH_SERVICE_NAME;
  84. $user = "sample.user@gmail.com";
  85. $pass = "pa$$w0rd";
  86. // Create an authenticated HTTP client
  87. $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
  88. // Create an instance of the Base service
  89. $service = new Zend_Gdata_Gbase($client);
  90. ]]></programlisting>
  91. <para>A Base service using AuthSub can be created in a similar, though slightly more lengthy fashion:</para>
  92. <programlisting language="php"><![CDATA[
  93. /*
  94. * Retrieve the current URL so that the AuthSub server knows where to
  95. * redirect the user after authentication is complete.
  96. */
  97. function getCurrentUrl()
  98. {
  99. global $_SERVER;
  100. // Filter php_self to avoid a security vulnerability.
  101. $php_request_uri =
  102. htmlentities(substr($_SERVER['REQUEST_URI'],
  103. 0,
  104. strcspn($_SERVER['REQUEST_URI'], "\n\r")),
  105. ENT_QUOTES);
  106. if (isset($_SERVER['HTTPS']) &&
  107. strtolower($_SERVER['HTTPS']) == 'on') {
  108. $protocol = 'https://';
  109. } else {
  110. $protocol = 'http://';
  111. }
  112. $host = $_SERVER['HTTP_HOST'];
  113. if ($_SERVER['HTTP_PORT'] != '' &&
  114. (($protocol == 'http://' && $_SERVER['HTTP_PORT'] != '80') ||
  115. ($protocol == 'https://' && $_SERVER['HTTP_PORT'] != '443'))) {
  116. $port = ':' . $_SERVER['HTTP_PORT'];
  117. } else {
  118. $port = '';
  119. }
  120. return $protocol . $host . $port . $php_request_uri;
  121. }
  122. /**
  123. * Obtain an AuthSub authenticated HTTP client, redirecting the user
  124. * to the AuthSub server to login if necessary.
  125. */
  126. function getAuthSubHttpClient()
  127. {
  128. global $_SESSION, $_GET;
  129. // If there is no AuthSub session or one-time token waiting for us,
  130. // redirect the user to the AuthSub server to get one.
  131. if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])) {
  132. // Parameters to give to AuthSub server
  133. $next = getCurrentUrl();
  134. $scope = "http://www.google.com/base/feeds/items/";
  135. $secure = false;
  136. $session = true;
  137. // Redirect the user to the AuthSub server to sign in
  138. $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
  139. $scope,
  140. $secure,
  141. $session);
  142. header("HTTP/1.0 307 Temporary redirect");
  143. header("Location: " . $authSubUrl);
  144. exit();
  145. }
  146. // Convert an AuthSub one-time token into a session token if needed
  147. if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
  148. $_SESSION['sessionToken'] =
  149. Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
  150. }
  151. // At this point we are authenticated via AuthSub and can obtain an
  152. // authenticated HTTP client instance
  153. // Create an authenticated HTTP client
  154. $client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
  155. return $client;
  156. }
  157. // -> Script execution begins here <-
  158. // Make sure http://code.google.com/apis/gdata/reference.html#Queriesthat
  159. // the user has a valid session, so we can record the
  160. // AuthSub session token once it is available.
  161. session_start();
  162. // Create an instance of the Base service, redirecting the user
  163. // to the AuthSub server if necessary.
  164. $service = new Zend_Gdata_Gbase(getAuthSubHttpClient());
  165. ]]></programlisting>
  166. <para>Finally, an unauthenticated server can be created for use with snippets feeds:</para>
  167. <programlisting language="php"><![CDATA[
  168. // Create an instance of the Base service using an unauthenticated HTTP client
  169. $service = new Zend_Gdata_Gbase();
  170. ]]></programlisting>
  171. </sect3>
  172. </sect2>
  173. <sect2 id="zend.gdata.gbase.retrieve">
  174. <title>Retrieve Items</title>
  175. <para>
  176. 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.
  177. </para>
  178. <sect3 id="zend.gdata.gbase.retrieve.query">
  179. <title>Send a Structured Query</title>
  180. <para>
  181. You can send a structured query to retrieve items from your own customer items feed or from the public snippets feed.
  182. </para>
  183. <para>
  184. When retrieving items using the Base <acronym>API</acronym>, specially constructed query <acronym>URL</acronym>s are used
  185. to describe what events should be returned. The
  186. <classname>Zend_Gdata_Gbase_ItemQuery</classname> and
  187. <classname>Zend_Gdata_Gbase_SnippetQuery</classname> classes simplify this task by
  188. automatically constructing a query <acronym>URL</acronym> based on provided parameters.
  189. </para>
  190. <sect4 id="zend.gdata.gbase.retrieve.query.customeritems">
  191. <title>Query Customer Items Feed</title>
  192. <para>
  193. To execute a query against the customer items feed, invoke <methodname>newItemQuery()</methodname> and <methodname>getGbaseItemFeed()</methodname> methods:
  194. </para>
  195. <programlisting language="php"><![CDATA[
  196. $service = new Zend_Gdata_Gbase($client);
  197. $query = $service->newItemQuery();
  198. $query->setBq('[title:Programming]');
  199. $query->setOrderBy('modification_time');
  200. $query->setSortOrder('descending');
  201. $query->setMaxResults('5');
  202. $feed = $service->getGbaseItemFeed($query);
  203. ]]></programlisting>
  204. <para>
  205. 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.
  206. </para>
  207. </sect4>
  208. <sect4 id="zend.gdata.gbase.retrieve.query.snippets">
  209. <title>Query Snippets Feed</title>
  210. <para>
  211. To execute a query against the public snippets feed, invoke <methodname>newSnippetQuery()</methodname> and <methodname>getGbaseSnippetFeed()</methodname> methods:
  212. </para>
  213. <programlisting language="php"><![CDATA[
  214. $service = new Zend_Gdata_Gbase();
  215. $query = $service->newSnippetQuery();
  216. $query->setBq('[title:Programming]');
  217. $query->setOrderBy('modification_time');
  218. $query->setSortOrder('descending');
  219. $query->setMaxResults('5');
  220. $feed = $service->getGbaseSnippetFeed($query);
  221. ]]></programlisting>
  222. <para>
  223. 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.
  224. </para>
  225. </sect4>
  226. </sect3>
  227. <sect3 id="zend.gdata.gbase.retrieve.iterate">
  228. <title>Iterate through the Items</title>
  229. <para>
  230. Google Base items can contain item-specific attributes such as <code>&lt;g:main_ingredient&gt;</code> and <code>&lt;g:weight&gt;</code>.
  231. </para>
  232. <para>
  233. To iterate through all attributes of a given item, invoke <methodname>getGbaseAttributes()</methodname> and iterate through the results:
  234. </para>
  235. <programlisting language="php"><![CDATA[
  236. foreach ($feed->entries as $entry) {
  237. // Get all attributes and print out the name and text value of each
  238. // attribute
  239. $baseAttributes = $entry->getGbaseAttributes();
  240. foreach ($baseAttributes as $attr) {
  241. echo "Attribute " . $attr->name . " : " . $attr->text . "<br>";
  242. }
  243. }
  244. ]]></programlisting>
  245. <para>
  246. Or, you can look for specific attribute name and iterate through the results that match:
  247. </para>
  248. <programlisting language="php"><![CDATA[
  249. foreach ($feed->entries as $entry) {
  250. // Print all main ingredients <g:main_ingredient>
  251. $baseAttributes = $entry->getGbaseAttribute("main_ingredient");
  252. foreach ($baseAttributes as $attr) {
  253. echo "Main ingredient: " . $attr->text . "<br>";
  254. }
  255. }
  256. ]]></programlisting>
  257. </sect3>
  258. </sect2>
  259. <sect2 id="zend.gdata.gbase.crud">
  260. <title>Insert, Update, and Delete Customer Items</title>
  261. <para>
  262. 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.
  263. </para>
  264. <para>
  265. 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.
  266. </para>
  267. <sect3 id="zend.gdata.gbase.crud.insert">
  268. <title>Insert an Item</title>
  269. <para>
  270. Items can be added by using the <methodname>insertGbaseItem()</methodname> method for the Base service:
  271. </para>
  272. <programlisting language="php"><![CDATA[
  273. $service = new Zend_Gdata_Gbase($client);
  274. $newEntry = $service->newItemEntry();
  275. // Add title
  276. $title = "PHP Developer Handbook";
  277. $newEntry->title = $service->newTitle(trim($title));
  278. // Add some content
  279. $content = "Essential handbook for PHP developers.";
  280. $newEntry->content = $service->newContent($content);
  281. $newEntry->content->type = 'text';
  282. // Define product type
  283. $itemType = "Products";
  284. $newEntry->itemType = $itemType;
  285. // Add item specific attributes
  286. $newEntry->addGbaseAttribute("product_type", "book", "text");
  287. $newEntry->addGbaseAttribute("price", "12.99 USD", "floatUnit");
  288. $newEntry->addGbaseAttribute("quantity", "10", "int");
  289. $newEntry->addGbaseAttribute("weight", "2.2 lbs", "numberUnit");
  290. $newEntry->addGbaseAttribute("condition", "New", "text");
  291. $newEntry->addGbaseAttribute("author", "John Doe", "text");
  292. $newEntry->addGbaseAttribute("edition", "First Edition", "text");
  293. $newEntry->addGbaseAttribute("pages", "253", "number");
  294. $newEntry->addGbaseAttribute("publisher", "My Press", "text");
  295. $newEntry->addGbaseAttribute("year", "2007", "number");
  296. $newEntry->addGbaseAttribute("payment_accepted", "Google Checkout", "text");
  297. $dryRun = true;
  298. $createdEntry = $service->insertGbaseItem($newEntry, $dryRun);
  299. ]]></programlisting>
  300. </sect3>
  301. <sect3 id="zend.gdata.gbase.crud.modify">
  302. <title>Modify an Item</title>
  303. <para>
  304. You can update each attribute element of an item as you iterate through them:
  305. </para>
  306. <programlisting language="php"><![CDATA[
  307. // Update the title
  308. $newTitle = "PHP Developer Handbook Second Edition";
  309. $entry->title = $service->newTitle($newTitle);
  310. // Find <g:price> attribute and update the price
  311. $baseAttributes = $entry->getGbaseAttribute("price");
  312. if (is_object($baseAttributes[0])) {
  313. $newPrice = "16.99 USD";
  314. $baseAttributes[0]->text = $newPrice;
  315. }
  316. // Find <g:pages> attribute and update the number of pages
  317. $baseAttributes = $entry->getGbaseAttribute("pages");
  318. if (is_object($baseAttributes[0])) {
  319. $newPages = "278";
  320. $baseAttributes[0]->text = $newPages;
  321. // Update the attribute type from "number" to "int"
  322. if ($baseAttributes[0]->type == "number") {
  323. $newType = "int";
  324. $baseAttributes[0]->type = $newType;
  325. }
  326. }
  327. // Remove <g:label> attributes
  328. $baseAttributes = $entry->getGbaseAttribute("label");
  329. foreach ($baseAttributes as $note) {
  330. $entry->removeGbaseAttribute($note);
  331. }
  332. // Add new attributes
  333. $entry->addGbaseAttribute("note", "PHP 5", "text");
  334. $entry->addGbaseAttribute("note", "Web Programming", "text");
  335. // Save the changes by invoking save() on the entry object itself
  336. $dryRun = true;
  337. $entry->save($dryRun);
  338. // Or, save the changes by calling updateGbaseItem() on the service object
  339. // $dryRun = true;
  340. // $service->updateGbaseItem($entry, $dryRun);
  341. ]]></programlisting>
  342. <para>
  343. 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.
  344. </para>
  345. </sect3>
  346. <sect3 id="zend.gdata.gbase.crud.delete">
  347. <title>Delete an Item</title>
  348. <para>
  349. You can remove an item by calling <methodname>deleteGbaseItem()</methodname> method:
  350. </para>
  351. <programlisting language="php"><![CDATA[
  352. $dryRun = false;
  353. $service->deleteGbaseItem($entry, $dryRun);
  354. ]]></programlisting>
  355. <para>
  356. Alternatively, you can invoke <methodname>delete()</methodname> on the <classname>Zend_Gdata_Gbase_ItemEntry</classname> object:
  357. </para>
  358. <programlisting language="php"><![CDATA[
  359. $dryRun = false;
  360. $entry->delete($dryRun);
  361. ]]></programlisting>
  362. </sect3>
  363. </sect2>
  364. </sect1>