Zend_Gdata_Health.xml 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!-- Reviewed: no -->
  3. <sect1 id="zend.gdata.health">
  4. <title>Using Google Health</title>
  5. <para>
  6. The Google Health Data <acronym>API</acronym> is designed to enable developers to do two
  7. things:
  8. <itemizedlist>
  9. <listitem>
  10. <para>
  11. Read a user's Google Health profile or query for medical records that match
  12. particular criteria and then use the results to provide personalized
  13. functionality based on the data.
  14. </para>
  15. </listitem>
  16. <listitem>
  17. <para>
  18. Add new medical records to a user's profile by including CCR data when sending a
  19. notice to a user's profile. Note: The CCR data is stored as an
  20. <acronym>XML</acronym> blob within the &lt;atom&gt; entry. The library does not
  21. provide direct accessors to the object model but it does have helpers for
  22. extracting specific fields.
  23. </para>
  24. </listitem>
  25. </itemizedlist>
  26. </para>
  27. <para>
  28. There are three main feeds, each of which requires authentication. Unlike other Google Data
  29. <acronym>API</acronym>s, each Google Health feed has a limited set of
  30. <acronym>HTTP</acronym> operations you can perform on it, depending on which authentication
  31. method you are using (ClientLogin or AuthSub/OAuth). For a list of permitted operations, see
  32. <ulink
  33. url="http://code.google.com/apis/health/reference.html#Authentication">http://code.google.com/apis/health/reference.html#Authentication</ulink>.
  34. <itemizedlist>
  35. <listitem>
  36. <para>
  37. <firstterm>Profile Feed</firstterm>
  38. use the profile feed to query a user's health profile for specific information.
  39. </para>
  40. </listitem>
  41. <listitem>
  42. <para>
  43. <firstterm>Register Feed</firstterm>
  44. use the register feed to reconcile new CCR data into a profile.
  45. </para>
  46. </listitem>
  47. <listitem>
  48. <para>
  49. <firstterm>Profile List Feed</firstterm> the profile list feed should be used to
  50. determine which of the user's Health profiles to interact with. This feed is only
  51. available when using ClientLogin.
  52. </para>
  53. </listitem>
  54. </itemizedlist>
  55. </para>
  56. <para>
  57. See <ulink
  58. url="http://code.google.com/apis/health/">http://code.google.com/apis/health</ulink>
  59. for more information about the Google Health <acronym>API</acronym>.
  60. </para>
  61. <sect2 id="zend.gdata.health.connect">
  62. <title>Connect To The Health Service</title>
  63. <para>
  64. The Google Health <acronym>API</acronym>, like all Google Data <acronym>API</acronym>s,
  65. is based off of the Atom Publishing Protocol (APP), an <acronym>XML</acronym> based
  66. format for managing web-based resources. Traffic between a client and the Google Health
  67. servers occurs over <acronym>HTTP</acronym> and allows for authenticated connections.
  68. </para>
  69. <para>
  70. Before any transactions can occur, a connection needs to be made. Creating a connection
  71. to the Health servers involves two steps: creating an <acronym>HTTP</acronym> client and
  72. binding a <classname>Zend_Gdata_Health</classname> service instance to that client.
  73. </para>
  74. <sect3 id="zend.gdata.health.connect.authentication">
  75. <title>Authentication</title>
  76. <para>
  77. The Google Health <acronym>API</acronym> allows programmatic access to a user's
  78. Health profile. There are three authentication schemes that are supported by Google
  79. Health:
  80. </para>
  81. <itemizedlist>
  82. <listitem>
  83. <para>
  84. <firstterm>ClientLogin</firstterm> provides direct username/password
  85. authentication to the Health servers. Since this method requires that users
  86. provide your application with their password, this authentication scheme is
  87. only recommended for installed/desktop applications.
  88. </para>
  89. </listitem>
  90. <listitem>
  91. <para>
  92. <firstterm>AuthSub</firstterm> allows a user to authorize the sharing of
  93. their private data. This provides the same level of convenience as
  94. ClientLogin but without the security risk, making it an ideal choice for
  95. web-based applications. For Google Health, AuthSub must be used in
  96. registered and secure mode--meaning that all requests to the
  97. <acronym>API</acronym> must be digitally signed.
  98. </para>
  99. </listitem>
  100. <listitem>
  101. <para>
  102. <firstterm>OAuth</firstterm> is an alternative to AuthSub. Although this
  103. authentication scheme is not discussed in this document, more information
  104. can be found in the <ulink
  105. url="http://code.google.com/apis/health/developers_guide_protocol.html#OAuth">Health
  106. Data <acronym>API</acronym> Developer's Guide</ulink>.
  107. </para>
  108. </listitem>
  109. </itemizedlist>
  110. <para>
  111. See <ulink
  112. url="http://code.google.com/apis/gdata/auth.html">Authentication Overview in the
  113. Google Data <acronym>API</acronym> documentation</ulink> for more
  114. information on each authentication method.
  115. </para>
  116. </sect3>
  117. <sect3 id="zend.gdata.health.connect.service">
  118. <title>Create A Health Service Instance</title>
  119. <para>
  120. In order to interact with Google Health, the client library provides the
  121. <classname>Zend_Gdata_Health</classname> service class. This class provides a common
  122. interface to the Google Data and Atom Publishing Protocol models and assists in
  123. marshaling requests to and from the Health <acronym>API</acronym>.
  124. </para>
  125. <para>
  126. Once you've decided on an authentication scheme, the next step is to create an
  127. instance of <classname>Zend_Gdata_Health</classname>. This class should be passed an
  128. instance of <classname>Zend_Gdata_HttpClient</classname>. This provides an interface
  129. for AuthSub/OAuth and ClientLogin to create a special authenticated
  130. <acronym>HTTP</acronym> client.
  131. </para>
  132. <para>
  133. To test against the H9 Developer's (/h9) instead of Google Health (/health), the
  134. <classname>Zend_Gdata_Health</classname> constructor takes an optional third
  135. argument for you to specify the H9 service name 'weaver'.
  136. </para>
  137. <para>
  138. The example below shows how to create a Health service class using ClientLogin
  139. authentication:
  140. </para>
  141. <programlisting language="php"><![CDATA[
  142. // Parameters for ClientLogin authentication
  143. $healthServiceName = Zend_Gdata_Health::HEALTH_SERVICE_NAME;
  144. //$h9ServiceName = Zend_Gdata_Health::H9_SANDBOX_SERVICE_NAME;
  145. $user = "user@gmail.com";
  146. $pass = "pa$$w0rd";
  147. // Create an authenticated HTTP client
  148. $client = Zend_Gdata_ClientLogin::getHttpClient($user,
  149. $pass,
  150. $healthServiceName);
  151. // Create an instance of the Health service
  152. $service = new Zend_Gdata_Health($client);
  153. ]]></programlisting>
  154. <para>
  155. A Health service using AuthSub can be created in a similar, though slightly more
  156. lengthy fashion. AuthSub is the recommend interface to communicate with Google
  157. Health because each token is directly linked to a specific profile in the user's
  158. account. Unlike other Google Data <acronym>API</acronym>s, it is required that all
  159. requests from your application be digitally signed.
  160. </para>
  161. <programlisting language="php"><![CDATA[
  162. /*
  163. * Retrieve the current URL so that the AuthSub server knows where to
  164. * redirect the user after authentication is complete.
  165. */
  166. function getCurrentUrl() {
  167. $phpRequestUri = htmlentities(substr($_SERVER['REQUEST_URI'],
  168. 0,
  169. strcspn($_SERVER['REQUEST_URI'],
  170. "\n\r")),
  171. ENT_QUOTES);
  172. if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
  173. $protocol = 'https://';
  174. } else {
  175. $protocol = 'http://';
  176. }
  177. $host = $_SERVER['HTTP_HOST'];
  178. if ($_SERVER['SERVER_PORT'] != '' &&
  179. (($protocol == 'http://' && $_SERVER['SERVER_PORT'] != '80') ||
  180. ($protocol == 'https://' && $_SERVER['SERVER_PORT'] != '443'))) {
  181. $port = ':' . $_SERVER['SERVER_PORT'];
  182. } else {
  183. $port = '';
  184. }
  185. return $protocol . $host . $port . $phpRequestUri;
  186. }
  187. /*
  188. * Redirect a user to AuthSub if they do not have a valid session token.
  189. * If they're coming back from AuthSub with a single-use token, instantiate
  190. * a new HTTP client and exchange the token for a long-lived session token
  191. * instead.
  192. */
  193. function setupClient($singleUseToken = null) {
  194. $client = null;
  195. // Fetch a new AuthSub token?
  196. if (!$singleUseToken) {
  197. $next = getCurrentUrl();
  198. $scope = 'https://www.google.com/health/feeds';
  199. $authSubHandler = 'https://www.google.com/health/authsub';
  200. $secure = 1;
  201. $session = 1;
  202. $authSubURL = Zend_Gdata_AuthSub::getAuthSubTokenUri($next,
  203. $scope,
  204. $secure,
  205. $session,
  206. $authSubHandler);
  207. // 1 - allows posting notices && allows reading profile data
  208. $permission = 1;
  209. $authSubURL .= '&permission=' . $permission;
  210. echo '<a href="' . $authSubURL . '">Your Google Health Account</a>';
  211. } else {
  212. $client = new Zend_Gdata_HttpClient();
  213. // This sets your private key to be used to sign subsequent requests
  214. $client->setAuthSubPrivateKeyFile('/path/to/your/rsa_private_key.pem',
  215. null,
  216. true);
  217. $sessionToken =
  218. Zend_Gdata_AuthSub::getAuthSubSessionToken(trim($singleUseToken),
  219. $client);
  220. // Set the long-lived session token for subsequent requests
  221. $client->setAuthSubToken($sessionToken);
  222. }
  223. return $client;
  224. }
  225. // -> Script execution begins here <-
  226. session_start();
  227. $client = setupClient(@$_GET['token']);
  228. // Create an instance of the Health service
  229. $userH9Sandbox = false;
  230. $healthService = new Zend_Gdata_Health($client,
  231. 'googleInc-MyTestAppName-v1.0',
  232. $userH9Sandbox);
  233. ]]></programlisting>
  234. <para>
  235. NOTE: the remainder of this document will assume you are using AuthSub for
  236. authentication.
  237. </para>
  238. </sect3>
  239. </sect2>
  240. <sect2 id="zend.gdata.health.profilefeed">
  241. <title>Profile Feed</title>
  242. <para>
  243. To query the user's profile feed, make sure your initial AuthSub token was requested
  244. with the <property>permission</property> parameter set to <emphasis>1</emphasis>. The
  245. process of extracting data from the profile requires two steps, sending a query and
  246. iterating through the resulting feed.
  247. </para>
  248. <sect3 id="zend.gdata.health.profilefeed.query">
  249. <title>Send a Structured Query</title>
  250. <para>
  251. You can send structured queries to retrieve specific records from a user's profile.
  252. </para>
  253. <para>
  254. When retrieving the profile using the Health <acronym>API</acronym>, specifically
  255. constructed query <acronym>URL</acronym>s are used to describe what (CCR) data
  256. should be returned. The <classname>Zend_Gdata_Health_Query</classname> class helps
  257. simplify this task by automatically constructing a query <acronym>URL</acronym>
  258. based on the parameters you set.
  259. </para>
  260. <sect4 id="zend.gdata.health.profilefeed.query.construct">
  261. <title>Query The Feed</title>
  262. <para>
  263. To execute a query against the profile feed, invoke a new instance of an
  264. <classname>Zend_Gdata_Health_Query</classname> and call the service's
  265. <methodname>getHealthProfileFeed()</methodname> method:
  266. </para>
  267. <programlisting language="php"><![CDATA[
  268. $healthService = new Zend_Gdata_Health($client);
  269. // example query for the top 10 medications with 2 items each
  270. $query = new Zend_Gdata_Health_Query();
  271. $query->setDigest("true");
  272. $query->setGrouped("true");
  273. $query->setMaxResultsGroup(10);
  274. $query->setMaxResultsInGroup(2);
  275. $query->setCategory("medication");
  276. $profileFeed = $healthService->getHealthProfileFeed($query);
  277. ]]></programlisting>
  278. <para>
  279. Using <methodname>setDigest("true")</methodname> returns all of user's CCR data
  280. in a single Atom <emphasis>&lt;entry&gt;</emphasis>.
  281. </para>
  282. <para>
  283. The <methodname>setCategory()</methodname> helper can be passed an additional
  284. parameter to return more specific CCR information. For example, to return just
  285. the medication Lipitor, use
  286. <methodname>setCategory("medication", "Lipitor")</methodname>. The same
  287. methodology can be applied to other categories such as conditions, allergies,
  288. lab results, etc.
  289. </para>
  290. <para>
  291. A full list of supported query parameters is available in the <ulink
  292. url="http://code.google.com/apis/health/reference.html#Parameters">query
  293. parameters section</ulink> of the Health <acronym>API</acronym> Reference
  294. Guide.
  295. </para>
  296. </sect4>
  297. </sect3>
  298. <sect3 id="zend.gdata.health.profilefeed.iterate">
  299. <title>Iterate Through The Profile Entries</title>
  300. <para>
  301. Each Google Health entry contains CCR data, however, using the
  302. <property>digest</property> query parameter and setting is to
  303. <constant>TRUE</constant> will consolidate all of the CCR elements
  304. (that match your query) into a single Atom <emphasis>&lt;entry&gt;</emphasis>.
  305. </para>
  306. <para>
  307. To retrieve the full CCR information from an entry, make a call to the
  308. <classname>Zend_Gdata_Health_ProfileEntry</classname> class's
  309. <methodname>getCcr()</methodname> method. That returns a
  310. <classname>Zend_Gdata_Health_Extension_CCR</classname>:
  311. </para>
  312. <programlisting language="php"><![CDATA[
  313. $entries = $profileFeed->getEntries();
  314. foreach ($entries as $entry) {
  315. $medications = $entry->getCcr()->getMedications();
  316. //$conditions = $entry->getCcr()->getConditions();
  317. //$immunizations = $entry->getCcr()->getImmunizations();
  318. // print the CCR xml (this will just be the entry's medications)
  319. foreach ($medications as $med) {
  320. $xmlStr = $med->ownerDocument->saveXML($med);
  321. echo "<pre>" . $xmlStr . "</pre>";
  322. }
  323. }
  324. ]]></programlisting>
  325. <para>
  326. Here, the <methodname>getCcr()</methodname> method is used in conjunction with a
  327. magic helper to drill down and extract just the medication data from the entry's
  328. CCR. The formentioned magic helper takes the form
  329. <methodname>getCATEGORYNAME()</methodname>, where <constant>CATEGORYNAME</constant>
  330. is a supported Google Health category. See the <ulink
  331. url="http://code.google.com/apis/health/reference.html#CatQueries">Google Health
  332. reference Guide</ulink> for the possible categories.
  333. </para>
  334. <para>
  335. To be more efficient, you can also use category queries to only return the necessary
  336. CCR from the Google Health servers. Then, iterate through those results:
  337. </para>
  338. <programlisting language="php"><![CDATA[
  339. $query = new Zend_Gdata_Health_Query();
  340. $query->setDigest("true");
  341. $query->setCategory("condition");
  342. $profileFeed = $healthService->getHealthProfileFeed($query);
  343. // Since the query contained digest=true, only one Atom entry is returned
  344. $entry = $profileFeed->entry[0];
  345. $conditions = $entry->getCcr()->getConditions();
  346. // print the CCR xml (this will just be the profile's conditions)
  347. foreach ($conditions as $cond) {
  348. $xmlStr = $cond->ownerDocument->saveXML($cond);
  349. echo "<pre>" . $xmlStr . "</pre>";
  350. }
  351. ]]></programlisting>
  352. </sect3>
  353. </sect2>
  354. <sect2 id="zend.gdata.health.profilelist">
  355. <title>Profile List Feed</title>
  356. <para>NOTE: This feed is only available when using ClientLogin</para>
  357. <para>
  358. Since ClientLogin requires a profile ID with each of its feeds, applications will likely
  359. want to query this feed first in order to select the appropriate profile. The profile
  360. list feed returns Atom entries corresponding each profile in the user's Google Health
  361. account. The profile ID is returned in the Atom <emphasis>&lt;content&gt;</emphasis> and
  362. the profile name in the <emphasis>&lt;title&gt;</emphasis> element.
  363. </para>
  364. <sect3 id="zend.gdata.health.profilelist.query">
  365. <title>Query The Feed</title>
  366. <para>
  367. To execute a query against the profile list feed, call the service's
  368. <methodname>getHealthProfileListFeed()</methodname> method:
  369. </para>
  370. <programlisting language="php"><![CDATA[
  371. $client = Zend_Gdata_ClientLogin::getHttpClient('user@gmail.com',
  372. 'pa$$word',
  373. 'health');
  374. $healthService = new Zend_Gdata_Health($client);
  375. $feed = $healthService->getHealthProfileListFeed();
  376. // print each profile's name and id
  377. $entries = $feed->getEntries();
  378. foreach ($entries as $entry) {
  379. echo '<p>Profile name: ' . $entry->getProfileName() . '<br>';
  380. echo 'profile ID: ' . $entry->getProfileID() . '</p>';
  381. }
  382. ]]></programlisting>
  383. <para>
  384. Once you've determined which profile to use, call
  385. <methodname>setProfileID()</methodname> with the profileID as an argument. This will
  386. restrict subsequent <acronym>API</acronym> requests to be against that particular
  387. profile:
  388. </para>
  389. <programlisting language="php"><![CDATA[
  390. // use the first profile
  391. $profileID = $feed->entry[0]->getProfileID();
  392. $healthService->setProfileID($profileID);
  393. $profileFeed = $healthService->getHealthProfileFeed();
  394. $profileID = $healthService->getProfileID();
  395. echo '<p><b>Queried profileID</b>: ' . $profileID . '</p>';
  396. ]]></programlisting>
  397. </sect3>
  398. </sect2>
  399. <sect2 id="zend.gdata.health.notice">
  400. <title>Sending Notices to the Register Feed</title>
  401. <para>
  402. Individual posts to the register feed are known as notices. Notice are sent from
  403. third-party applications to inform the user of a new event. With AuthSub/OAuth, notices
  404. are the single means by which your application can add new CCR information into a user's
  405. profile. Notices can contain plain text (including certain <acronym>XHTML</acronym>
  406. elements), a CCR document, or both. As an example, notices might be sent to remind users
  407. to pick up a prescription, or they might contain lab results in the CCR format.
  408. </para>
  409. <sect3 id="zend.gdata.health.notice.send">
  410. <title>Sending a notice</title>
  411. <para>
  412. Notices can be sent by using the <methodname>sendHealthNotice()</methodname> method
  413. for the Health service:
  414. </para>
  415. <programlisting language="php"><![CDATA[
  416. $healthService = new Zend_Gdata_Health($client);
  417. $subject = "Title of your notice goes here";
  418. $body = "Notice body can contain <b>html</b> entities";
  419. $ccr = '<ContinuityOfCareRecord xmlns="urn:astm-org:CCR">
  420. <Body>
  421. <Problems>
  422. <Problem>
  423. <DateTime>
  424. <Type><Text>Start date</Text></Type>
  425. <ExactDateTime>2007-04-04T07:00:00Z</ExactDateTime>
  426. </DateTime>
  427. <Description>
  428. <Text>Aortic valve disorders</Text>
  429. <Code>
  430. <Value>410.10</Value>
  431. <CodingSystem>ICD9</CodingSystem>
  432. <Version>2004</Version>
  433. </Code>
  434. </Description>
  435. <Status><Text>Active</Text></Status>
  436. </Problem>
  437. </Problems>
  438. </Body>
  439. </ContinuityOfCareRecord>';
  440. $responseEntry = $healthService->sendHealthNotice($subject,
  441. $body,
  442. "html",
  443. $ccr);
  444. ]]></programlisting>
  445. </sect3>
  446. </sect2>
  447. </sect1>