Zend_Gdata_Gbase.xml 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  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
  7. things:
  8. <itemizedlist>
  9. <listitem>
  10. <para>
  11. Query Google Base data to create applications and mashups.
  12. </para>
  13. </listitem>
  14. <listitem>
  15. <para>
  16. Input and manage Google Base items programmatically.
  17. </para>
  18. </listitem>
  19. </itemizedlist>
  20. </para>
  21. <para>
  22. There are two item feeds: snippets feed and customer items feeds. The snippets feed contains
  23. all Google Base data and is available to anyone to query against without a need for
  24. authentication. The customer items feed is a customer-specific subset of data and only a
  25. customer/owner can access this feed to insert, update, or delete their own data. Queries are
  26. constructed the same way against both types of feeds.
  27. </para>
  28. <para>
  29. See <ulink url="http://code.google.com/apis/base/">http://code.google.com/apis/base</ulink>
  30. for more information about the Google Base <acronym>API</acronym>.
  31. </para>
  32. <sect2 id="zend.gdata.gbase.connect">
  33. <title>Connect To The Base Service</title>
  34. <para>
  35. The Google Base <acronym>API</acronym>, like all GData <acronym>API</acronym>s, is based
  36. off of the Atom Publishing Protocol (APP), an <acronym>XML</acronym> based format for
  37. managing web-based resources. Traffic between a client and the Google Base servers
  38. occurs over <acronym>HTTP</acronym> and allows for both authenticated and
  39. unauthenticated connections.
  40. </para>
  41. <para>
  42. Before any transactions can occur, this connection needs to be made. Creating a
  43. connection to the base servers involves two steps: creating an <acronym>HTTP</acronym>
  44. client and binding a <classname>Zend_Gdata_Gbase</classname> service instance to that
  45. client.
  46. </para>
  47. <sect3 id="zend.gdata.gbase.connect.authentication">
  48. <title>Authentication</title>
  49. <para>
  50. The Google Base <acronym>API</acronym> allows access to both public and private base
  51. feeds. Public feeds do not require authentication, but are read-only and offer
  52. reduced functionality. Private feeds offers the most complete functionality but
  53. requires an authenticated connection to the base servers. There are three
  54. authentication schemes that are supported by Google Base:
  55. </para>
  56. <itemizedlist>
  57. <listitem>
  58. <para>
  59. <firstterm>ClientAuth</firstterm> provides direct username/password
  60. authentication to the base servers. Since this scheme requires that users
  61. provide your application with their password, this authentication is only
  62. recommended when other authentication schemes are insufficient.
  63. </para>
  64. </listitem>
  65. <listitem>
  66. <para>
  67. <firstterm>AuthSub</firstterm> allows authentication to the base servers via
  68. a Google proxy server. This provides the same level of convenience as
  69. ClientAuth but without the security risk, making this an ideal choice for
  70. web-based applications.
  71. </para>
  72. </listitem>
  73. </itemizedlist>
  74. <para>
  75. The <classname>Zend_Gdata</classname> library provides support for all three
  76. authentication schemes. The rest of this chapter will assume that you are familiar
  77. the authentication schemes available and how to create an appropriate authenticated
  78. connection. For more information, please see the <link
  79. linkend="zend.gdata.introduction.authentication">authentication section</link>
  80. or the <ulink url="http://code.google.com/apis/gdata/auth.html">Authentication
  81. Overview in the Google Data <acronym>API</acronym> Developer's Guide</ulink>.
  82. </para>
  83. </sect3>
  84. <sect3 id="zend.gdata.gbase.connect.service">
  85. <title>Create A Service Instance</title>
  86. <para>
  87. In order to interact with Google Base, this library provides the
  88. <classname>Zend_Gdata_Gbase</classname> service class. This class provides a common
  89. interface to the Google Data and Atom Publishing Protocol models and assists in
  90. marshaling requests to and from the base servers.
  91. </para>
  92. <para>
  93. Once deciding on an authentication scheme, the next step is to create an instance of
  94. <classname>Zend_Gdata_Gbase</classname>. This class takes in an instance of
  95. <classname>Zend_Http_Client</classname> as a single argument. This provides an
  96. interface for AuthSub and ClientAuth authentication, as both of these creation of a
  97. special authenticated <acronym>HTTP</acronym> client. If no arguments are provided,
  98. an unauthenticated instance of <classname>Zend_Http_Client</classname>
  99. will be automatically created.
  100. </para>
  101. <para>
  102. The example below shows how to create a Base service class using ClientAuth
  103. authentication:
  104. </para>
  105. <programlisting language="php"><![CDATA[
  106. // Parameters for ClientAuth authentication
  107. $service = Zend_Gdata_Gbase::AUTH_SERVICE_NAME;
  108. $user = "sample.user@gmail.com";
  109. $pass = "pa$$w0rd";
  110. // Create an authenticated HTTP client
  111. $client = Zend_Gdata_ClientLogin::getHttpClient($user, $pass, $service);
  112. // Create an instance of the Base service
  113. $service = new Zend_Gdata_Gbase($client);
  114. ]]></programlisting>
  115. <para>
  116. A Base service using AuthSub can be created in a similar, though slightly more
  117. lengthy fashion:
  118. </para>
  119. <programlisting language="php"><![CDATA[
  120. /*
  121. * Retrieve the current URL so that the AuthSub server knows where to
  122. * redirect the user after authentication is complete.
  123. */
  124. function getCurrentUrl()
  125. {
  126. global $_SERVER;
  127. // Filter php_self to avoid a security vulnerability.
  128. $php_request_uri =
  129. htmlentities(substr($_SERVER['REQUEST_URI'],
  130. 0,
  131. strcspn($_SERVER['REQUEST_URI'], "\n\r")),
  132. ENT_QUOTES);
  133. if (isset($_SERVER['HTTPS']) &&
  134. strtolower($_SERVER['HTTPS']) == 'on') {
  135. $protocol = 'https://';
  136. } else {
  137. $protocol = 'http://';
  138. }
  139. $host = $_SERVER['HTTP_HOST'];
  140. if ($_SERVER['HTTP_PORT'] != '' &&
  141. (($protocol == 'http://' && $_SERVER['HTTP_PORT'] != '80') ||
  142. ($protocol == 'https://' && $_SERVER['HTTP_PORT'] != '443'))) {
  143. $port = ':' . $_SERVER['HTTP_PORT'];
  144. } else {
  145. $port = '';
  146. }
  147. return $protocol . $host . $port . $php_request_uri;
  148. }
  149. /**
  150. * Obtain an AuthSub authenticated HTTP client, redirecting the user
  151. * to the AuthSub server to login if necessary.
  152. */
  153. function getAuthSubHttpClient()
  154. {
  155. global $_SESSION, $_GET;
  156. // If there is no AuthSub session or one-time token waiting for us,
  157. // redirect the user to the AuthSub server to get one.
  158. if (!isset($_SESSION['sessionToken']) && !isset($_GET['token'])) {
  159. // Parameters to give to AuthSub server
  160. $next = getCurrentUrl();
  161. $scope = "http://www.google.com/base/feeds/items/";
  162. $secure = false;
  163. $session = true;
  164. // Redirect the user to the AuthSub server to sign in
  165. $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
  166. $scope,
  167. $secure,
  168. $session);
  169. header("HTTP/1.0 307 Temporary redirect");
  170. header("Location: " . $authSubUrl);
  171. exit();
  172. }
  173. // Convert an AuthSub one-time token into a session token if needed
  174. if (!isset($_SESSION['sessionToken']) && isset($_GET['token'])) {
  175. $_SESSION['sessionToken'] =
  176. Zend_Gdata_AuthSub::getAuthSubSessionToken($_GET['token']);
  177. }
  178. // At this point we are authenticated via AuthSub and can obtain an
  179. // authenticated HTTP client instance
  180. // Create an authenticated HTTP client
  181. $client = Zend_Gdata_AuthSub::getHttpClient($_SESSION['sessionToken']);
  182. return $client;
  183. }
  184. // -> Script execution begins here <-
  185. // Make sure http://code.google.com/apis/gdata/reference.html#Queriesthat
  186. // the user has a valid session, so we can record the
  187. // AuthSub session token once it is available.
  188. session_start();
  189. // Create an instance of the Base service, redirecting the user
  190. // to the AuthSub server if necessary.
  191. $service = new Zend_Gdata_Gbase(getAuthSubHttpClient());
  192. ]]></programlisting>
  193. <para>
  194. Finally, an unauthenticated server can be created for use with snippets feeds:
  195. </para>
  196. <programlisting language="php"><![CDATA[
  197. // Create an instance of the Base service using an unauthenticated HTTP client
  198. $service = new Zend_Gdata_Gbase();
  199. ]]></programlisting>
  200. </sect3>
  201. </sect2>
  202. <sect2 id="zend.gdata.gbase.retrieve">
  203. <title>Retrieve Items</title>
  204. <para>
  205. You can query customer items feed or snippets feed to retrieve items. It involves two
  206. steps, sending a query and iterating through the returned feed.
  207. </para>
  208. <sect3 id="zend.gdata.gbase.retrieve.query">
  209. <title>Send a Structured Query</title>
  210. <para>
  211. You can send a structured query to retrieve items from your own customer items feed
  212. or from the public snippets feed.
  213. </para>
  214. <para>
  215. When retrieving items using the Base <acronym>API</acronym>, specially constructed
  216. query <acronym>URL</acronym>s are used to describe what events should be returned.
  217. The <classname>Zend_Gdata_Gbase_ItemQuery</classname> and
  218. <classname>Zend_Gdata_Gbase_SnippetQuery</classname> classes simplify this task by
  219. automatically constructing a query <acronym>URL</acronym> based on provided
  220. parameters.
  221. </para>
  222. <sect4 id="zend.gdata.gbase.retrieve.query.customeritems">
  223. <title>Query Customer Items Feed</title>
  224. <para>
  225. To execute a query against the customer items feed, invoke
  226. <methodname>newItemQuery()</methodname> and
  227. <methodname>getGbaseItemFeed()</methodname> methods:
  228. </para>
  229. <programlisting language="php"><![CDATA[
  230. $service = new Zend_Gdata_Gbase($client);
  231. $query = $service->newItemQuery();
  232. $query->setBq('[title:Programming]');
  233. $query->setOrderBy('modification_time');
  234. $query->setSortOrder('descending');
  235. $query->setMaxResults('5');
  236. $feed = $service->getGbaseItemFeed($query);
  237. ]]></programlisting>
  238. <para>
  239. A full list of these parameters is available at the <ulink
  240. url="http://code.google.com/apis/base/items-feed.html#QueParameters">Query
  241. parameters section</ulink> of the Customer Items Feed documentation.
  242. </para>
  243. </sect4>
  244. <sect4 id="zend.gdata.gbase.retrieve.query.snippets">
  245. <title>Query Snippets Feed</title>
  246. <para>
  247. To execute a query against the public snippets feed, invoke
  248. <methodname>newSnippetQuery()</methodname> and
  249. <methodname>getGbaseSnippetFeed()</methodname> methods:
  250. </para>
  251. <programlisting language="php"><![CDATA[
  252. $service = new Zend_Gdata_Gbase();
  253. $query = $service->newSnippetQuery();
  254. $query->setBq('[title:Programming]');
  255. $query->setOrderBy('modification_time');
  256. $query->setSortOrder('descending');
  257. $query->setMaxResults('5');
  258. $feed = $service->getGbaseSnippetFeed($query);
  259. ]]></programlisting>
  260. <para>
  261. A full list of these parameters is available at the <ulink
  262. url="http://code.google.com/apis/base/snippets-feed.html#Parameters">Query
  263. parameters section</ulink> of the Snippets Feed documentation.
  264. </para>
  265. </sect4>
  266. </sect3>
  267. <sect3 id="zend.gdata.gbase.retrieve.iterate">
  268. <title>Iterate through the Items</title>
  269. <para>
  270. Google Base items can contain item-specific attributes such as
  271. <emphasis>&lt;g:main_ingredient&gt;</emphasis> and <emphasis>&lt;g:weight&gt;</emphasis>.
  272. </para>
  273. <para>
  274. To iterate through all attributes of a given item, invoke
  275. <methodname>getGbaseAttributes()</methodname> and iterate through the results:
  276. </para>
  277. <programlisting language="php"><![CDATA[
  278. foreach ($feed->entries as $entry) {
  279. // Get all attributes and print out the name and text value of each
  280. // attribute
  281. $baseAttributes = $entry->getGbaseAttributes();
  282. foreach ($baseAttributes as $attr) {
  283. echo "Attribute " . $attr->name . " : " . $attr->text . "<br>";
  284. }
  285. }
  286. ]]></programlisting>
  287. <para>
  288. Or, you can look for specific attribute name and iterate through the results that
  289. match:
  290. </para>
  291. <programlisting language="php"><![CDATA[
  292. foreach ($feed->entries as $entry) {
  293. // Print all main ingredients <g:main_ingredient>
  294. $baseAttributes = $entry->getGbaseAttribute("main_ingredient");
  295. foreach ($baseAttributes as $attr) {
  296. echo "Main ingredient: " . $attr->text . "<br>";
  297. }
  298. }
  299. ]]></programlisting>
  300. </sect3>
  301. </sect2>
  302. <sect2 id="zend.gdata.gbase.crud">
  303. <title>Insert, Update, and Delete Customer Items</title>
  304. <para>
  305. A customer/owner can access his own Customer Items feed to insert, update, or delete
  306. their items. These operations do not apply to the public snippets feed.
  307. </para>
  308. <para>
  309. You can test a feed operation before it is actually executed by setting the dry-run flag
  310. (<varname>$dryRun</varname>) to <constant>TRUE</constant>. Once you are sure that you
  311. want to submit the data, set it to <constant>FALSE</constant> to execute the operation.
  312. </para>
  313. <sect3 id="zend.gdata.gbase.crud.insert">
  314. <title>Insert an Item</title>
  315. <para>
  316. Items can be added by using the <methodname>insertGbaseItem()</methodname> method
  317. for the Base service:
  318. </para>
  319. <programlisting language="php"><![CDATA[
  320. $service = new Zend_Gdata_Gbase($client);
  321. $newEntry = $service->newItemEntry();
  322. // Add title
  323. $title = "PHP Developer Handbook";
  324. $newEntry->title = $service->newTitle(trim($title));
  325. // Add some content
  326. $content = "Essential handbook for PHP developers.";
  327. $newEntry->content = $service->newContent($content);
  328. $newEntry->content->type = 'text';
  329. // Define product type
  330. $itemType = "Products";
  331. $newEntry->itemType = $itemType;
  332. // Add item specific attributes
  333. $newEntry->addGbaseAttribute("product_type", "book", "text");
  334. $newEntry->addGbaseAttribute("price", "12.99 USD", "floatUnit");
  335. $newEntry->addGbaseAttribute("quantity", "10", "int");
  336. $newEntry->addGbaseAttribute("weight", "2.2 lbs", "numberUnit");
  337. $newEntry->addGbaseAttribute("condition", "New", "text");
  338. $newEntry->addGbaseAttribute("author", "John Doe", "text");
  339. $newEntry->addGbaseAttribute("edition", "First Edition", "text");
  340. $newEntry->addGbaseAttribute("pages", "253", "number");
  341. $newEntry->addGbaseAttribute("publisher", "My Press", "text");
  342. $newEntry->addGbaseAttribute("year", "2007", "number");
  343. $newEntry->addGbaseAttribute("payment_accepted", "Google Checkout", "text");
  344. $dryRun = true;
  345. $createdEntry = $service->insertGbaseItem($newEntry, $dryRun);
  346. ]]></programlisting>
  347. </sect3>
  348. <sect3 id="zend.gdata.gbase.crud.modify">
  349. <title>Modify an Item</title>
  350. <para>
  351. You can update each attribute element of an item as you iterate through them:
  352. </para>
  353. <programlisting language="php"><![CDATA[
  354. // Update the title
  355. $newTitle = "PHP Developer Handbook Second Edition";
  356. $entry->title = $service->newTitle($newTitle);
  357. // Find <g:price> attribute and update the price
  358. $baseAttributes = $entry->getGbaseAttribute("price");
  359. if (is_object($baseAttributes[0])) {
  360. $newPrice = "16.99 USD";
  361. $baseAttributes[0]->text = $newPrice;
  362. }
  363. // Find <g:pages> attribute and update the number of pages
  364. $baseAttributes = $entry->getGbaseAttribute("pages");
  365. if (is_object($baseAttributes[0])) {
  366. $newPages = "278";
  367. $baseAttributes[0]->text = $newPages;
  368. // Update the attribute type from "number" to "int"
  369. if ($baseAttributes[0]->type == "number") {
  370. $newType = "int";
  371. $baseAttributes[0]->type = $newType;
  372. }
  373. }
  374. // Remove <g:label> attributes
  375. $baseAttributes = $entry->getGbaseAttribute("label");
  376. foreach ($baseAttributes as $note) {
  377. $entry->removeGbaseAttribute($note);
  378. }
  379. // Add new attributes
  380. $entry->addGbaseAttribute("note", "PHP 5", "text");
  381. $entry->addGbaseAttribute("note", "Web Programming", "text");
  382. // Save the changes by invoking save() on the entry object itself
  383. $dryRun = true;
  384. $entry->save($dryRun);
  385. // Or, save the changes by calling updateGbaseItem() on the service object
  386. // $dryRun = true;
  387. // $service->updateGbaseItem($entry, $dryRun);
  388. ]]></programlisting>
  389. <para>
  390. After making the changes, either invoke <methodname>save($dryRun)</methodname>
  391. method on the <classname>Zend_Gdata_Gbase_ItemEntry</classname> object or call
  392. <methodname>updateGbaseItem($entry, $dryRun)</methodname> method on the
  393. <classname>Zend_Gdata_Gbase</classname> object to save the changes.
  394. </para>
  395. </sect3>
  396. <sect3 id="zend.gdata.gbase.crud.delete">
  397. <title>Delete an Item</title>
  398. <para>
  399. You can remove an item by calling <methodname>deleteGbaseItem()</methodname> method:
  400. </para>
  401. <programlisting language="php"><![CDATA[
  402. $dryRun = false;
  403. $service->deleteGbaseItem($entry, $dryRun);
  404. ]]></programlisting>
  405. <para>
  406. Alternatively, you can invoke <methodname>delete()</methodname> on the
  407. <classname>Zend_Gdata_Gbase_ItemEntry</classname> object:
  408. </para>
  409. <programlisting language="php"><![CDATA[
  410. $dryRun = false;
  411. $entry->delete($dryRun);
  412. ]]></programlisting>
  413. </sect3>
  414. </sect2>
  415. </sect1>