Health.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Gdata
  17. * @subpackage Demos
  18. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  19. * @license http://framework.zend.com/license/new-bsd New BSD License
  20. */
  21. //////////////////////////////////////////////////////////////////////////////
  22. // Configuration: You must change these settings before running this sample //
  23. //////////////////////////////////////////////////////////////////////////////
  24. // Change this to point to the location of your private signing key. See:
  25. // http://code.google.com/apis/health/getting_started.html#DomainRegistration
  26. define('HEALTH_PRIVATE_KEY', '/path/to/your/rsa_private_key.pem');
  27. //////////////////////////////////////////////////////////////////////////////
  28. // End Configuration //
  29. //////////////////////////////////////////////////////////////////////////////
  30. // Load the Zend Gdata classes.
  31. require_once 'Zend/Loader.php';
  32. Zend_Loader::loadClass('Zend_Gdata_AuthSub');
  33. Zend_Loader::loadClass('Zend_Gdata_Health');
  34. Zend_Loader::loadClass('Zend_Gdata_Health_Query');
  35. session_start();
  36. // Google H9 Sandbox AuthSub/OAuth scope
  37. define('SCOPE', 'https://www.google.com/h9/feeds/');
  38. try {
  39. // Setup the HTTP client and fetch an AuthSub token for H9
  40. $client = authenticate(@$_GET['token']);
  41. $useH9 = true;
  42. $healthService = new Zend_Gdata_Health($client, 'google-HealthPHPSample-v1.0', $useH9);
  43. } catch(Zend_Gdata_App_Exception $e) {
  44. echo 'Error: ' . $e->getMessage();
  45. }
  46. ?>
  47. <html>
  48. <head>
  49. <style>
  50. body { margin:0; }
  51. div { width:75%;margin-left:10px;padding:5px;font-family: "Courier New"; }
  52. div#tokenstats { border-bottom:5px solid;background-color:#99ccff;margin:0 0 10px 0;padding:5px;width:100%; }
  53. .code { margin:5px 0 5px 10px;background-color:#eee; }
  54. div.data{ height:600px;border:1px solid;overflow:auto; }
  55. </style>
  56. </head>
  57. <body>
  58. <div id="tokenstats">
  59. <b>Token info</b>: <?php echo getTokenInfo($client); ?><br>
  60. <b>Session Token</b>: <?php echo $client->getAuthSubToken(); ?><br>
  61. </div>
  62. <?php
  63. // =============================================================================
  64. // Return the user's entire profile in a single atom <entry>
  65. // =============================================================================
  66. try {
  67. $snippet = '
  68. // =========================================================================
  69. // Return the user\'s entire profile in a single atom <entry>
  70. // =========================================================================
  71. $query = new Zend_Gdata_Health_Query();
  72. $query->setDigest("true");
  73. $profileFeed = $healthService->getHealthProfileFeed($query);';
  74. $snippet2 = '
  75. $entries = $profileFeed->getEntries();
  76. $ccr = $entries[0]->getCcr();
  77. $xmlStr = $ccr->saveXML($ccr);
  78. echo "<p>" . xmlpp($xmlStr) . "</p>";';
  79. echo '<div class="code"><pre>' . htmlentities($snippet . $snippet2) . '</pre></div>';
  80. eval($snippet);
  81. } catch(Zend_Gdata_App_Exception $e) {
  82. echo 'Error: ' . $e->getMessage();
  83. }
  84. echo '<div class="data"><pre>';
  85. echo 'num entries: ' . count($profileFeed->getEntries());
  86. eval($snippet2);
  87. echo '</pre></div>';
  88. // =============================================================================
  89. // Return a user's medication from the entire CCR
  90. // =============================================================================
  91. try {
  92. $snippet = '
  93. // =========================================================================
  94. // Return a user\'s medication for the entire CCR
  95. // =========================================================================
  96. $profileFeed = $healthService->getHealthProfileFeed();';
  97. $snippet2 = '
  98. foreach ($profileFeed->entry as $entry) {
  99. $medications = $entry->getCcr()->getMedications();
  100. foreach ($medications as $med) {
  101. $xmlStr = $med->ownerDocument->saveXML($med);
  102. echo "<p>" . xmlpp($xmlStr) . "</p>";
  103. }
  104. }';
  105. } catch(Zend_Gdata_App_Exception $e) {
  106. echo 'Error: ' . $e->getMessage();
  107. }
  108. echo '<div class="code"><pre>' . htmlentities($snippet . $snippet2) . '</pre></div>';
  109. eval($snippet);
  110. echo '<div class="data"><pre>';
  111. eval($snippet2);
  112. echo '</pre></div>';
  113. // =============================================================================
  114. // Category query: return a user's medication
  115. // =============================================================================
  116. try {
  117. $snippet = '
  118. // =========================================================================
  119. // Category query: return a user\'s medication
  120. // =========================================================================
  121. $query = new Zend_Gdata_Health_Query(SCOPE . "profile/default");
  122. $query->setCategory("medication");
  123. $profileFeed = $healthService->getHealthProfileFeed($query);';
  124. $snippet2 = '
  125. foreach ($profileFeed->entry as $entry) {
  126. $medications = $entry->getCcr()->getMedications();
  127. foreach ($medications as $med) {
  128. $xmlStr = $med->ownerDocument->saveXML($med);
  129. echo "<p>" . xmlpp($xmlStr) . "</p>";
  130. }
  131. }';
  132. } catch(Zend_Gdata_App_Exception $e) {
  133. echo 'Error: ' . $e->getMessage();
  134. }
  135. echo '<div class="code"><pre>' . htmlentities($snippet . $snippet2) . '</pre></div>';
  136. eval($snippet);
  137. echo '<div class="data"><pre>';
  138. echo 'query: ' . $query->getQueryUrl() . '<br>';
  139. echo 'num entries: ' . count($profileFeed->getEntries());
  140. eval($snippet2);
  141. echo '</pre></div>';
  142. // =============================================================================
  143. // Query for a specific item within a category: allgergy A-Fil
  144. // =============================================================================
  145. try {
  146. $snippet = '
  147. // =========================================================================
  148. // Query for a specific item within a category: allgergy A-Fil
  149. // =========================================================================
  150. $query = new Zend_Gdata_Health_Query(SCOPE . "profile/default");
  151. $query->setCategory("allergy", "A-Fil");
  152. $query->setGrouped("true");
  153. $profileFeed = $healthService->getHealthProfileFeed($query);';
  154. $snippet2 = '
  155. foreach ($profileFeed->getEntries() as $entry) {
  156. $allergies = $entry->getCcr()->getAllergies();
  157. foreach ($allergies as $allergy) {
  158. $xmlStr = $allergy->ownerDocument->saveXML($allergy);
  159. echo "<p>" . xmlpp($xmlStr) . "</p>";
  160. }
  161. }';
  162. } catch(Zend_Gdata_App_Exception $e) {
  163. echo 'Error: ' . $e->getMessage();
  164. }
  165. echo '<div class="code"><pre>' . htmlentities($snippet . $snippet2) . '</pre></div>';
  166. eval($snippet);
  167. echo '<div class="data"><pre>';
  168. echo 'query: ' . $query->getQueryUrl() . '<br>';
  169. echo 'num entries: ' . count($profileFeed->getEntries());
  170. eval($snippet2);
  171. echo '</pre></div>';
  172. // =============================================================================
  173. // Query (and return) the user\'s medications OR conditions
  174. // =============================================================================
  175. try {
  176. $snippet = '
  177. // =========================================================================
  178. // Query (and return) the user\'s medications OR conditions
  179. // =========================================================================
  180. $queryStr = SCOPE . "profile/default/-/medication%7Ccondition?digest=false";
  181. $profileFeed = $healthService->getHealthProfileFeed($queryStr);';
  182. $snippet2 = '
  183. $entries = $profileFeed->getEntries();
  184. foreach ($entries as $entry) {
  185. $ccr = $entry->getCcr();
  186. $xmlStr = $ccr->saveXML($ccr);
  187. echo "<p>" . xmlpp($xmlStr) . "</p>";
  188. }';
  189. echo '<div class="code"><pre>' . htmlentities($snippet . $snippet2) . '</pre></div>';
  190. eval($snippet);
  191. } catch(Zend_Gdata_App_Exception $e) {
  192. echo 'Error: ' . $e->getMessage();
  193. }
  194. echo '<div class="data"><pre>';
  195. echo 'num entries: ' . count($profileFeed->getEntries());
  196. eval($snippet2);
  197. echo '</pre></div>';
  198. // =============================================================================
  199. // Send a notice to the user's profile that includes a CCR payload
  200. // =============================================================================
  201. try {
  202. $snippet = '
  203. // =========================================================================
  204. // Send a notice to the user\'s profile that includes a CCR payload
  205. // =========================================================================
  206. $subject = "Title of your notice goes here";
  207. $body = "Notice body can contain <b>html</b> entities";
  208. $ccr = \'<ContinuityOfCareRecord xmlns="urn:astm-org:CCR">
  209. <Body>
  210. <Problems>
  211. <Problem>
  212. <DateTime>
  213. <Type><Text>Start date</Text></Type>
  214. <ExactDateTime>2007-04-04T07:00:00Z</ExactDateTime>
  215. </DateTime>
  216. <Description>
  217. <Text>Aortic valve disorders</Text>
  218. <Code>
  219. <Value>410.10</Value>
  220. <CodingSystem>ICD9</CodingSystem>
  221. <Version>2004</Version>
  222. </Code>
  223. </Description>
  224. <Status><Text>Active</Text></Status>
  225. </Problem>
  226. </Problems>
  227. </Body>
  228. </ContinuityOfCareRecord>\';
  229. $responseEntry = $healthService->sendHealthNotice($subject, $body, "html", $ccr);';
  230. } catch(Zend_Gdata_App_Exception $e) {
  231. echo 'Error: ' . $e->getMessage();
  232. }
  233. echo '<div class="code"><pre>' . htmlentities($snippet) . '</pre></div>';
  234. eval($snippet);
  235. echo '<div class="data"><pre>';
  236. echo xmlpp($responseEntry->getXML());
  237. echo '</pre></div>';
  238. // =============================================================================
  239. // Revoke the AuthSub session token
  240. // =============================================================================
  241. //$revoked = Zend_Gdata_AuthSub::AuthSubRevokeToken($client->getAuthSubToken(), $client) ? 'yes' : 'no';
  242. //echo '<b>Token revoked</b>: ' . @$revoked;
  243. //unset($_SESSION['sessionToken']);
  244. ?>
  245. </body>
  246. </html>
  247. <?php
  248. function getCurrentUrl() {
  249. $phpRequestUri =
  250. htmlentities(substr($_SERVER['REQUEST_URI'], 0, strcspn($_SERVER['REQUEST_URI'], "\n\r")), ENT_QUOTES);
  251. if (isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) == 'on') {
  252. $protocol = 'https://';
  253. } else {
  254. $protocol = 'http://';
  255. }
  256. $host = $_SERVER['HTTP_HOST'];
  257. if ($_SERVER['SERVER_PORT'] != '' &&
  258. (($protocol == 'http://' && $_SERVER['SERVER_PORT'] != '80') ||
  259. ($protocol == 'https://' && $_SERVER['SERVER_PORT'] != '443'))) {
  260. $port = ':' . $_SERVER['SERVER_PORT'];
  261. } else {
  262. $port = '';
  263. }
  264. return $protocol . $host . $port . $phpRequestUri;
  265. }
  266. function authenticate($singleUseToken=null) {
  267. $sessionToken = isset($_SESSION['sessionToken']) ? $_SESSION['sessionToken'] : null;
  268. // If there is no AuthSub session or one-time token waiting for us,
  269. // redirect the user to Google Health's AuthSub handler to get one.
  270. if (!$sessionToken && !$singleUseToken) {
  271. $next = getCurrentUrl();
  272. $secure = 1;
  273. $session = 1;
  274. $authSubHandler = 'https://www.google.com/h9/authsub';
  275. $permission = 1; // 1 - allows reading of the profile && posting notices
  276. $authSubURL =
  277. Zend_Gdata_AuthSub::getAuthSubTokenUri($next, SCOPE, $secure, $session,
  278. $authSubHandler);
  279. $authSubURL .= '&permission=' . $permission;
  280. echo '<a href="' . $authSubURL . '">Link your Google Health Account</a>';
  281. exit();
  282. }
  283. $client = new Zend_Gdata_HttpClient();
  284. $client->setAuthSubPrivateKeyFile(HEALTH_PRIVATE_KEY, null, true);
  285. // Convert an AuthSub one-time token into a session token if needed
  286. if ($singleUseToken && !$sessionToken) {
  287. $sessionToken =
  288. Zend_Gdata_AuthSub::getAuthSubSessionToken($singleUseToken, $client);
  289. $_SESSION['sessionToken'] = $sessionToken;
  290. }
  291. $client->setAuthSubToken($sessionToken);
  292. return $client;
  293. }
  294. function getTokenInfo($client) {
  295. $sessionToken = $client->getAuthSubToken();
  296. return Zend_Gdata_AuthSub::getAuthSubTokenInfo($sessionToken, $client);
  297. }
  298. function revokeToken($client) {
  299. $sessionToken = $client->getAuthSubToken();
  300. return Zend_Gdata_AuthSub::AuthSubRevokeToken($sessionToken, $client);
  301. }
  302. /** Prettifies an XML string into a human-readable and indented work of art
  303. * @param string $xml The XML as a string
  304. * @param boolean $html_output True if the output should be escaped (for use in HTML)
  305. */
  306. function xmlpp($xml, $html_output=true) {
  307. $xml_obj = new SimpleXMLElement($xml);
  308. $level = 4;
  309. $indent = 0; // current indentation level
  310. $pretty = array();
  311. // get an array containing each XML element
  312. $xml = explode("\n", preg_replace('/>\s*</', ">\n<", $xml_obj->asXML()));
  313. // shift off opening XML tag if present
  314. if (count($xml) && preg_match('/^<\?\s*xml/', $xml[0])) {
  315. $pretty[] = array_shift($xml);
  316. }
  317. foreach ($xml as $el) {
  318. if (preg_match('/^<([\w])+[^>\/]*>$/U', $el)) {
  319. // opening tag, increase indent
  320. $pretty[] = str_repeat(' ', $indent) . $el;
  321. $indent += $level;
  322. } else {
  323. if (preg_match('/^<\/.+>$/', $el)) {
  324. $indent -= $level; // closing tag, decrease indent
  325. }
  326. if ($indent < 0) {
  327. $indent += $level;
  328. }
  329. $pretty[] = str_repeat(' ', $indent) . $el;
  330. }
  331. }
  332. $xml = implode("\n", $pretty);
  333. return ($html_output) ? htmlentities($xml) : $xml;
  334. }
  335. ?>