PageRenderTime 55ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/fitbitphp.php

https://github.com/clyons/fitbitphp
PHP | 2346 lines | 1532 code | 247 blank | 567 comment | 241 complexity | 2b025815e76b06b666885d4274e6ed57 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. /**
  3. * FitbitPHP v.0.70. Basic Fitbit API wrapper for PHP using OAuth
  4. *
  5. * Note: Library is in beta and provided as-is. We hope to add features as API grows, however
  6. * feel free to fork, extend and send pull requests to us.
  7. *
  8. * - https://github.com/heyitspavel/fitbitphp
  9. *
  10. *
  11. * Date: 2011/12/09
  12. * Requires OAuth 1.0.0, SimpleXML
  13. * @version 0.70 ($Id$)
  14. */
  15. class FitBitPHP
  16. {
  17. /**
  18. * API Constants
  19. *
  20. */
  21. private $authHost = 'www.fitbit.com';
  22. private $apiHost = 'api.fitbit.com';
  23. private $baseApiUrl;
  24. private $authUrl;
  25. private $requestTokenUrl;
  26. private $accessTokenUrl;
  27. /**
  28. * Class Variables
  29. *
  30. */
  31. protected $oauth;
  32. protected $oauth_Token, $oauth_Secret;
  33. protected $userId = '-';
  34. protected $metric = 0;
  35. protected $userAgent = 'FitbitPHP 0.70';
  36. protected $debug;
  37. protected $clientDebug;
  38. /**
  39. * @param string $consumer_key Application consumer key for Fitbit API
  40. * @param string $consumer_secret Application secret
  41. * @param int $debug Debug mode (0/1) enables OAuth internal debug
  42. * @param string $userAgent User-agent to use in API calls
  43. */
  44. public function __construct($consumer_key, $consumer_secret, $debug = 1, $userAgent = null)
  45. {
  46. $this->initUrls();
  47. $this->consumer_key = $consumer_key;
  48. $this->consumer_secret = $consumer_secret;
  49. $this->oauth = new OAuth($consumer_key, $consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_AUTHORIZATION);
  50. $this->debug = $debug;
  51. if (isset($userAgent))
  52. $this->userAgent = $userAgent;
  53. if ($debug)
  54. $this->oauth->enableDebug();
  55. }
  56. /**
  57. * @param string $consumer_key Application consumer key for Fitbit API
  58. * @param string $consumer_secret Application secret
  59. */
  60. public function reinit($consumer_key, $consumer_secret)
  61. {
  62. $this->consumer_key = $consumer_key;
  63. $this->consumer_secret = $consumer_secret;
  64. $this->oauth = new OAuth($consumer_key, $consumer_secret, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_AUTHORIZATION);
  65. if ($debug)
  66. $this->oauth->enableDebug();
  67. }
  68. /**
  69. * @param string $apiHost API host, i.e. api.fitbit.com (do you know any others?)
  70. * @param string $authHost Auth host, i.e. www.fitbit.com
  71. */
  72. public function setEndpointBase($apiHost, $authHost, $https = true, $httpsApi = false)
  73. {
  74. $this->apiHost = $apiHost;
  75. $this->authHost = $authHost;
  76. $this->initUrls($https, $httpsApi);
  77. }
  78. private function initUrls($https = true, $httpsApi = false)
  79. {
  80. if ($httpsApi)
  81. $this->baseApiUrl = 'https://' . $this->apiHost . '/1/';
  82. else
  83. $this->baseApiUrl = 'http://' . $this->apiHost . '/1/';
  84. if ($https) {
  85. $this->authUrl = 'https://' . $this->authHost . '/oauth/authorize';
  86. $this->requestTokenUrl = 'https://' . $this->apiHost . '/oauth/request_token';
  87. $this->accessTokenUrl = 'https://' . $this->apiHost . '/oauth/access_token';
  88. } else {
  89. $this->authUrl = 'http://' . $this->authHost . '/oauth/authorize';
  90. $this->requestTokenUrl = 'http://' . $this->apiHost . '/oauth/request_token';
  91. $this->accessTokenUrl = 'http://' . $this->apiHost . '/oauth/access_token';
  92. }
  93. }
  94. /**
  95. * @return OAuth debugInfo object for previous call. Debug should be enabled in __construct
  96. */
  97. public function oauthDebug()
  98. {
  99. return $this->oauth->debugInfo;
  100. }
  101. /**
  102. * @return OAuth debugInfo object for previous client_customCall. Debug should be enabled in __construct
  103. */
  104. public function client_oauthDebug()
  105. {
  106. return $this->clientDebug;
  107. }
  108. /**
  109. * Returns Fitbit session status for frontend (i.e. 'Sign in with Fitbit' implementations)
  110. *
  111. * @return int (0 - no session, 1 - just after successful authorization, 2 - session exist)
  112. */
  113. public static function sessionStatus()
  114. {
  115. $session = session_id();
  116. if (empty($session)) {
  117. session_start();
  118. }
  119. if (empty($_SESSION['fitbit_Session']))
  120. $_SESSION['fitbit_Session'] = 0;
  121. return (int)$_SESSION['fitbit_Session'];
  122. }
  123. /**
  124. * Initialize session. Inits OAuth session, handles redirects to Fitbit login/authorization if needed
  125. *
  126. * @param $callbackUrl Callback for 'Sign in with Fitbit'
  127. * @param $cookie Use persistent cookie for authorization, or session cookie only
  128. * @return int (1 - just after successful authorization, 2 - if session already exist)
  129. */
  130. public function initSession($callbackUrl, $cookie = true)
  131. {
  132. $session = session_id();
  133. if (empty($session)) {
  134. session_start();
  135. }
  136. if (empty($_SESSION['fitbit_Session']))
  137. $_SESSION['fitbit_Session'] = 0;
  138. if (!isset($_GET['oauth_token']) && $_SESSION['fitbit_Session'] == 1)
  139. $_SESSION['fitbit_Session'] = 0;
  140. if ($_SESSION['fitbit_Session'] == 0) {
  141. $request_token_info = $this->oauth->getRequestToken($this->requestTokenUrl, $callbackUrl);
  142. $_SESSION['fitbit_Secret'] = $request_token_info['oauth_token_secret'];
  143. $_SESSION['fitbit_Session'] = 1;
  144. header('Location: ' . $this->authUrl . '?oauth_token=' . $request_token_info['oauth_token']);
  145. exit;
  146. } else if ($_SESSION['fitbit_Session'] == 1) {
  147. $this->oauth->setToken($_GET['oauth_token'], $_SESSION['fitbit_Secret']);
  148. $access_token_info = $this->oauth->getAccessToken($this->accessTokenUrl);
  149. $_SESSION['fitbit_Session'] = 2;
  150. $_SESSION['fitbit_Token'] = $access_token_info['oauth_token'];
  151. $_SESSION['fitbit_Secret'] = $access_token_info['oauth_token_secret'];
  152. $this->setOAuthDetails($_SESSION['fitbit_Token'], $_SESSION['fitbit_Secret']);
  153. return 1;
  154. } else if ($_SESSION['fitbit_Session'] == 2) {
  155. $this->setOAuthDetails($_SESSION['fitbit_Token'], $_SESSION['fitbit_Secret']);
  156. return 2;
  157. }
  158. }
  159. /**
  160. * Reset session
  161. *
  162. * @return void
  163. */
  164. public function resetSession()
  165. {
  166. $_SESSION['fitbit_Session'] = 0;
  167. }
  168. /**
  169. * Sets OAuth token/secret. Use if library used in internal calls without session handling
  170. *
  171. * @param $token
  172. * @param $secret
  173. * @return void
  174. */
  175. public function setOAuthDetails($token, $secret)
  176. {
  177. $this->oauth_Token = $token;
  178. $this->oauth_Secret = $secret;
  179. $this->oauth->setToken($this->oauth_Token, $this->oauth_Secret);
  180. }
  181. /**
  182. * Get OAuth token
  183. *
  184. * @return string
  185. */
  186. public function getOAuthToken()
  187. {
  188. return $this->oauth_Token;
  189. }
  190. /**
  191. * Get OAuth secret
  192. *
  193. * @return string
  194. */
  195. public function getOAuthSecret()
  196. {
  197. return $this->oauth_Secret;
  198. }
  199. /**
  200. * Set Fitbit userId for future API calls
  201. *
  202. * @param $userId 'XXXXX'
  203. * @return void
  204. */
  205. public function setUser($userId)
  206. {
  207. $this->userId = $userId;
  208. }
  209. /**
  210. * Set Unit System for all future calls (see http://wiki.fitbit.com/display/API/API-Unit-System)
  211. * 0 (Metric), 1 (en_US), 2 (en_GB)
  212. *
  213. * @param int $metric
  214. * @return void
  215. */
  216. public function setMetric($metric)
  217. {
  218. $this->metric = $metric;
  219. }
  220. /**
  221. * API wrappers
  222. *
  223. */
  224. /**
  225. * Get user profile
  226. *
  227. * @throws FitBitException
  228. * @param string $userId UserId of public profile, if none using set with setUser or '-' by default
  229. * @return SimpleXMLElement
  230. */
  231. public function getProfile()
  232. {
  233. $headers = $this->getHeaders();
  234. try {
  235. $this->oauth->fetch($this->baseApiUrl . "user/" . $this->userId . "/profile.xml", null, OAUTH_HTTP_METHOD_GET, $headers);
  236. } catch (Exception $E) {
  237. }
  238. $response = $this->oauth->getLastResponse();
  239. $responseInfo = $this->oauth->getLastResponseInfo();
  240. if (!strcmp($responseInfo['http_code'], '200')) {
  241. $xml = simplexml_load_string($response);
  242. if ($xml)
  243. return $xml;
  244. else
  245. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  246. } else {
  247. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  248. }
  249. }
  250. /**
  251. * Update user profile
  252. *
  253. * @throws FitBitException
  254. * @param string $gender 'FEMALE', 'MALE' or 'NA'
  255. * @param DateTime $birthday Date of birth
  256. * @param string $height Height in cm/inches (as set with setMetric)
  257. * @param string $nickname Nickname
  258. * @param string $fullName Full name
  259. * @param string $timezone Timezone in the format 'America/Los_Angeles'
  260. * @return SimpleXMLElement
  261. */
  262. public function updateProfile($gender = null, $birthday = null, $height = null, $nickname = null, $fullName = null, $timezone = null)
  263. {
  264. $headers = $this->getHeaders();
  265. $parameters = array();
  266. if (isset($gender))
  267. $parameters['gender'] = $gender;
  268. if (isset($birthday))
  269. $parameters['birthday'] = $birthday->format('Y-m-d');
  270. if (isset($height))
  271. $parameters['height'] = $height;
  272. if (isset($nickname))
  273. $parameters['nickname'] = $nickname;
  274. if (isset($fullName))
  275. $parameters['fullName'] = $fullName;
  276. if (isset($timezone))
  277. $parameters['timezone'] = $timezone;
  278. try {
  279. $this->oauth->fetch($this->baseApiUrl . "user/-/profile.xml",
  280. $parameters, OAUTH_HTTP_METHOD_POST, $headers);
  281. } catch (Exception $E) {
  282. }
  283. $response = $this->oauth->getLastResponse();
  284. $responseInfo = $this->oauth->getLastResponseInfo();
  285. if (!strcmp($responseInfo['http_code'], '201')) {
  286. $xml = simplexml_load_string($response);
  287. if ($xml)
  288. return $xml;
  289. else
  290. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  291. } else {
  292. $xml = simplexml_load_string($response);
  293. if (!$xml)
  294. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  295. else
  296. throw new FitBitException($responseInfo['http_code'], $xml->errors->apiError->message, 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  297. }
  298. }
  299. /**
  300. * Get user activities for specific date
  301. *
  302. * @throws FitBitException
  303. * @param DateTime $date
  304. * @param String $dateStr
  305. * @return SimpleXMLElement
  306. */
  307. public function getActivities($date, $dateStr = null)
  308. {
  309. $headers = $this->getHeaders();
  310. if (!isset($dateStr)) {
  311. $dateStr = $date->format('Y-m-d');
  312. }
  313. try {
  314. $this->oauth->fetch($this->baseApiUrl . "user/" . $this->userId . "/activities/date/" . $dateStr . ".xml",
  315. null, OAUTH_HTTP_METHOD_GET, $headers);
  316. } catch (Exception $E) {
  317. }
  318. $response = $this->oauth->getLastResponse();
  319. $responseInfo = $this->oauth->getLastResponseInfo();
  320. if (!strcmp($responseInfo['http_code'], '200')) {
  321. $xml = simplexml_load_string($response);
  322. if ($xml)
  323. return $xml;
  324. else
  325. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  326. } else {
  327. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  328. }
  329. }
  330. /**
  331. * Get user recent activities
  332. *
  333. * @throws FitBitException
  334. * @return SimpleXMLElement
  335. */
  336. public function getRecentActivities()
  337. {
  338. $headers = $this->getHeaders();
  339. try {
  340. $this->oauth->fetch($this->baseApiUrl . "user/-/activities/recent.xml", null,
  341. OAUTH_HTTP_METHOD_GET, $headers);
  342. } catch (Exception $E) {
  343. }
  344. $response = $this->oauth->getLastResponse();
  345. $responseInfo = $this->oauth->getLastResponseInfo();
  346. if (!strcmp($responseInfo['http_code'], '200')) {
  347. $xml = simplexml_load_string($response);
  348. if ($xml)
  349. return $xml;
  350. else
  351. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  352. } else {
  353. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  354. }
  355. }
  356. /**
  357. * Get user frequent activities
  358. *
  359. * @throws FitBitException
  360. * @return SimpleXMLElement
  361. */
  362. public function getFrequentActivities()
  363. {
  364. $headers = $this->getHeaders();
  365. try {
  366. $this->oauth->fetch($this->baseApiUrl . "user/-/activities/frequent.xml", null,
  367. OAUTH_HTTP_METHOD_GET, $headers);
  368. } catch (Exception $E) {
  369. }
  370. $response = $this->oauth->getLastResponse();
  371. $responseInfo = $this->oauth->getLastResponseInfo();
  372. if (!strcmp($responseInfo['http_code'], '200')) {
  373. $xml = simplexml_load_string($response);
  374. if ($xml)
  375. return $xml;
  376. else
  377. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  378. } else {
  379. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  380. }
  381. }
  382. /**
  383. * Get user favorite activities
  384. *
  385. * @throws FitBitException
  386. * @return SimpleXMLElement
  387. */
  388. public function getFavoriteActivities()
  389. {
  390. $headers = $this->getHeaders();
  391. try {
  392. $this->oauth->fetch($this->baseApiUrl . "user/-/activities/favorite.xml", null,
  393. OAUTH_HTTP_METHOD_GET, $headers);
  394. } catch (Exception $E) {
  395. }
  396. $response = $this->oauth->getLastResponse();
  397. $responseInfo = $this->oauth->getLastResponseInfo();
  398. if (!strcmp($responseInfo['http_code'], '200')) {
  399. $xml = simplexml_load_string($response);
  400. if ($xml)
  401. return $xml;
  402. else
  403. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  404. } else {
  405. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  406. }
  407. }
  408. /**
  409. * Log user activity
  410. *
  411. * @throws FitBitException
  412. * @param DateTime $date Activity date and time (set proper timezone, which could be fetched via getProfile)
  413. * @param string $activityId Activity Id (or Intensity Level Id) from activities database,
  414. * see http://wiki.fitbit.com/display/API/API-Log-Activity
  415. * @param string $duration Duration millis
  416. * @param string $calories Manual calories to override Fitbit estimate
  417. * @param string $distance Distance in km/miles (as set with setMetric)
  418. * @param string $distanceUnit Distance unit string (see http://wiki.fitbit.com/display/API/API-Distance-Unit)
  419. * @return SimpleXMLElement
  420. */
  421. public function logActivity($date, $activityId, $duration, $calories = null, $distance = null, $distanceUnit = null, $activityName = null)
  422. {
  423. $distanceUnits = array('Centimeter', 'Foot', 'Inch', 'Kilometer', 'Meter', 'Mile', 'Millimeter', 'Steps', 'Yards');
  424. $headers = $this->getHeaders();
  425. $parameters = array();
  426. $parameters['date'] = $date->format('Y-m-d');
  427. $parameters['startTime'] = $date->format('H:i');
  428. if (isset($activityName)) {
  429. $parameters['activityName'] = $activityName;
  430. $parameters['manualCalories'] = $calories;
  431. } else {
  432. $parameters['activityId'] = $activityId;
  433. if (isset($calories))
  434. $parameters['manualCalories'] = $calories;
  435. }
  436. $parameters['durationMillis'] = $duration;
  437. if (isset($distance))
  438. $parameters['distance'] = $distance;
  439. if (isset($distanceUnit) && in_array($distanceUnit, $distanceUnits))
  440. $parameters['distanceUnit'] = $distanceUnit;
  441. try {
  442. $this->oauth->fetch($this->baseApiUrl . "user/-/activities.xml", $parameters,
  443. OAUTH_HTTP_METHOD_POST, $headers);
  444. } catch (Exception $E) {
  445. }
  446. $response = $this->oauth->getLastResponse();
  447. $responseInfo = $this->oauth->getLastResponseInfo();
  448. if (!strcmp($responseInfo['http_code'], '201')) {
  449. $xml = simplexml_load_string($response);
  450. if ($xml)
  451. return $xml;
  452. else
  453. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  454. } else {
  455. $xml = simplexml_load_string($response);
  456. if (!$xml)
  457. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  458. else
  459. throw new FitBitException($responseInfo['http_code'], $xml->errors->apiError->message, 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  460. }
  461. }
  462. /**
  463. * Delete user activity
  464. *
  465. * @throws FitBitException
  466. * @param string $id Activity log id
  467. * @return bool
  468. */
  469. public function deleteActivity($id)
  470. {
  471. $headers = $this->getHeaders();
  472. try {
  473. $this->oauth->fetch($this->baseApiUrl . "user/-/activities/" . $id . ".xml", null,
  474. OAUTH_HTTP_METHOD_DELETE, $headers);
  475. } catch (Exception $E) {
  476. }
  477. $responseInfo = $this->oauth->getLastResponseInfo();
  478. if (!strcmp($responseInfo['http_code'], '204')) {
  479. return true;
  480. } else {
  481. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  482. }
  483. }
  484. /**
  485. * Add user favorite activity
  486. *
  487. * @throws FitBitException
  488. * @param string $id Activity log id
  489. * @return bool
  490. */
  491. public function addFavoriteActivity($id)
  492. {
  493. $headers = $this->getHeaders();
  494. try {
  495. $this->oauth->fetch($this->baseApiUrl . "user/-/activities/log/favorite/" . $id . ".xml",
  496. null, OAUTH_HTTP_METHOD_POST, $headers);
  497. } catch (Exception $E) {
  498. }
  499. $responseInfo = $this->oauth->getLastResponseInfo();
  500. if (!strcmp($responseInfo['http_code'], '201')) {
  501. return true;
  502. } else {
  503. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  504. }
  505. }
  506. /**
  507. * Delete user favorite activity
  508. *
  509. * @throws FitBitException
  510. * @param string $id Activity log id
  511. * @return bool
  512. */
  513. public function deleteFavoriteActivity($id)
  514. {
  515. $headers = $this->getHeaders();
  516. try {
  517. $this->oauth->fetch($this->baseApiUrl . "user/-/activities/log/favorite/" . $id . ".xml",
  518. null, OAUTH_HTTP_METHOD_DELETE, $headers);
  519. } catch (Exception $E) {
  520. }
  521. $responseInfo = $this->oauth->getLastResponseInfo();
  522. if (!strcmp($responseInfo['http_code'], '204')) {
  523. return true;
  524. } else {
  525. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  526. }
  527. }
  528. /**
  529. * Get full description of specific activity
  530. *
  531. * @throws FitBitException
  532. * @param string $id Activity log Id
  533. * @return SimpleXMLElement
  534. */
  535. public function getActivity($id)
  536. {
  537. $headers = $this->getHeaders();
  538. try {
  539. $this->oauth->fetch($this->baseApiUrl . "activities/" . $id . ".xml", null,
  540. OAUTH_HTTP_METHOD_GET, $headers);
  541. } catch (Exception $E) {
  542. }
  543. $response = $this->oauth->getLastResponse();
  544. $responseInfo = $this->oauth->getLastResponseInfo();
  545. if (!strcmp($responseInfo['http_code'], '200')) {
  546. $xml = simplexml_load_string($response);
  547. if ($xml)
  548. return $xml;
  549. else
  550. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  551. } else {
  552. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  553. }
  554. }
  555. /**
  556. * Get a tree of all valid Fitbit public activities as well as private custom activities the user createds
  557. *
  558. * @throws FitBitException
  559. * @return SimpleXMLElement
  560. */
  561. public function browseActivities()
  562. {
  563. $headers = $this->getHeaders();
  564. try {
  565. $this->oauth->fetch($this->baseApiUrl . "activities.xml", null,
  566. OAUTH_HTTP_METHOD_GET, $headers);
  567. } catch (Exception $E) {
  568. }
  569. $response = $this->oauth->getLastResponse();
  570. $responseInfo = $this->oauth->getLastResponseInfo();
  571. if (!strcmp($responseInfo['http_code'], '200')) {
  572. $xml = simplexml_load_string($response);
  573. if ($xml)
  574. return $xml;
  575. else
  576. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  577. } else {
  578. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  579. }
  580. }
  581. /**
  582. * Get user foods for specific date
  583. *
  584. * @throws FitBitException
  585. * @param DateTime $date
  586. * @param String $dateStr
  587. * @return SimpleXMLElement
  588. */
  589. public function getFoods($date, $dateStr = null)
  590. {
  591. $headers = $this->getHeaders();
  592. if (!isset($dateStr)) {
  593. $dateStr = $date->format('Y-m-d');
  594. }
  595. try {
  596. $this->oauth->fetch($this->baseApiUrl . "user/" . $this->userId . "/foods/log/date/" . $dateStr . ".xml",
  597. null, OAUTH_HTTP_METHOD_GET, $headers);
  598. } catch (Exception $E) {
  599. }
  600. $response = $this->oauth->getLastResponse();
  601. $responseInfo = $this->oauth->getLastResponseInfo();
  602. if (!strcmp($responseInfo['http_code'], '200')) {
  603. $xml = simplexml_load_string($response);
  604. if ($xml)
  605. return $xml;
  606. else
  607. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  608. } else {
  609. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  610. }
  611. }
  612. /**
  613. * Get user recent foods
  614. *
  615. * @throws FitBitException
  616. * @return SimpleXMLElement
  617. */
  618. public function getRecentFoods()
  619. {
  620. $headers = $this->getHeaders();
  621. try {
  622. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/recent.xml", null,
  623. OAUTH_HTTP_METHOD_GET, $headers);
  624. } catch (Exception $E) {
  625. }
  626. $response = $this->oauth->getLastResponse();
  627. $responseInfo = $this->oauth->getLastResponseInfo();
  628. if (!strcmp($responseInfo['http_code'], '200')) {
  629. $xml = simplexml_load_string($response);
  630. if ($xml)
  631. return $xml;
  632. else
  633. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  634. } else {
  635. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  636. }
  637. }
  638. /**
  639. * Get user frequent foods
  640. *
  641. * @throws FitBitException
  642. * @return SimpleXMLElement
  643. */
  644. public function getFrequentFoods()
  645. {
  646. $headers = $this->getHeaders();
  647. try {
  648. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/frequent.xml", null,
  649. OAUTH_HTTP_METHOD_GET, $headers);
  650. } catch (Exception $E) {
  651. }
  652. $response = $this->oauth->getLastResponse();
  653. $responseInfo = $this->oauth->getLastResponseInfo();
  654. if (!strcmp($responseInfo['http_code'], '200')) {
  655. $xml = simplexml_load_string($response);
  656. if ($xml)
  657. return $xml;
  658. else
  659. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  660. } else {
  661. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  662. }
  663. }
  664. /**
  665. * Get user favorite foods
  666. *
  667. * @throws FitBitException
  668. * @return SimpleXMLElement
  669. */
  670. public function getFavoriteFoods()
  671. {
  672. $headers = $this->getHeaders();
  673. try {
  674. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/favorite.xml", null,
  675. OAUTH_HTTP_METHOD_GET, $headers);
  676. } catch (Exception $E) {
  677. }
  678. $response = $this->oauth->getLastResponse();
  679. $responseInfo = $this->oauth->getLastResponseInfo();
  680. if (!strcmp($responseInfo['http_code'], '200')) {
  681. $xml = simplexml_load_string($response);
  682. if ($xml)
  683. return $xml;
  684. else
  685. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  686. } else {
  687. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  688. }
  689. }
  690. /**
  691. * Log user food
  692. *
  693. * @throws FitBitException
  694. * @param DateTime $date Food log date
  695. * @param string $foodId Food Id from foods database (see searchFoods)
  696. * @param string $mealTypeId Meal Type Id from foods database (see searchFoods)
  697. * @param string $unitId Unit Id, should be allowed for this food (see getFoodUnits and searchFoods)
  698. * @param string $amount Amount in specified units
  699. * @return SimpleXMLElement
  700. */
  701. public function logFood($date, $foodId, $mealTypeId, $unitId, $amount, $foodName = null, $calories = null, $brandName = null, $nutrition = null)
  702. {
  703. $headers = $this->getHeaders();
  704. $parameters = array();
  705. $parameters['date'] = $date->format('Y-m-d');
  706. if (isset($foodName)) {
  707. $parameters['foodName'] = $foodName;
  708. $parameters['calories'] = $calories;
  709. if (isset($brandName))
  710. $parameters['brandName'] = $brandName;
  711. if (isset($nutrition)) {
  712. foreach ($nutrition as $i => $value) {
  713. $parameters[$i] = $nutrition[$i];
  714. }
  715. }
  716. } else {
  717. $parameters['foodId'] = $foodId;
  718. }
  719. $parameters['mealTypeId'] = $mealTypeId;
  720. $parameters['unitId'] = $unitId;
  721. $parameters['amount'] = $amount;
  722. try {
  723. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log.xml", $parameters,
  724. OAUTH_HTTP_METHOD_POST, $headers);
  725. } catch (Exception $E) {
  726. }
  727. $response = $this->oauth->getLastResponse();
  728. $responseInfo = $this->oauth->getLastResponseInfo();
  729. if (!strcmp($responseInfo['http_code'], '201')) {
  730. $xml = simplexml_load_string($response);
  731. if ($xml)
  732. return $xml;
  733. else
  734. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  735. } else {
  736. $xml = simplexml_load_string($response);
  737. if (!$xml)
  738. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  739. else
  740. throw new FitBitException($responseInfo['http_code'], $xml->errors->apiError->message, 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  741. }
  742. }
  743. /**
  744. * Delete user food
  745. *
  746. * @throws FitBitException
  747. * @param string $id Food log id
  748. * @return bool
  749. */
  750. public function deleteFood($id)
  751. {
  752. $headers = $this->getHeaders();
  753. try {
  754. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/" . $id . ".xml", null,
  755. OAUTH_HTTP_METHOD_DELETE, $headers);
  756. } catch (Exception $E) {
  757. }
  758. $responseInfo = $this->oauth->getLastResponseInfo();
  759. if (!strcmp($responseInfo['http_code'], '204')) {
  760. return true;
  761. } else {
  762. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  763. }
  764. }
  765. /**
  766. * Add user favorite food
  767. *
  768. * @throws FitBitException
  769. * @param string $id Food log id
  770. * @return bool
  771. */
  772. public function addFavoriteFood($id)
  773. {
  774. $headers = $this->getHeaders();
  775. try {
  776. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/favorite/" . $id . ".xml", null,
  777. OAUTH_HTTP_METHOD_POST, $headers);
  778. } catch (Exception $E) {
  779. }
  780. $responseInfo = $this->oauth->getLastResponseInfo();
  781. if (!strcmp($responseInfo['http_code'], '201')) {
  782. return true;
  783. } else {
  784. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  785. }
  786. }
  787. /**
  788. * Delete user favorite food
  789. *
  790. * @throws FitBitException
  791. * @param string $id Food log id
  792. * @return bool
  793. */
  794. public function deleteFavoriteFood($id)
  795. {
  796. $headers = $this->getHeaders();
  797. try {
  798. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/favorite/" . $id . ".xml",
  799. null, OAUTH_HTTP_METHOD_DELETE, $headers);
  800. } catch (Exception $E) {
  801. }
  802. $responseInfo = $this->oauth->getLastResponseInfo();
  803. if (!strcmp($responseInfo['http_code'], '204')) {
  804. return true;
  805. } else {
  806. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  807. }
  808. }
  809. /**
  810. * Get user meal sets
  811. *
  812. * @throws FitBitException
  813. * @return SimpleXMLElement
  814. */
  815. public function getMeals()
  816. {
  817. $headers = $this->getHeaders();
  818. try {
  819. $this->oauth->fetch($this->baseApiUrl . "user/-/meals.xml",
  820. null, OAUTH_HTTP_METHOD_GET, $headers);
  821. } catch (Exception $E) {
  822. }
  823. $response = $this->oauth->getLastResponse();
  824. $responseInfo = $this->oauth->getLastResponseInfo();
  825. if (!strcmp($responseInfo['http_code'], '200')) {
  826. $xml = simplexml_load_string($response);
  827. if ($xml)
  828. return $xml;
  829. else
  830. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  831. } else {
  832. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  833. }
  834. }
  835. /**
  836. * Get food units library
  837. *
  838. * @throws FitBitException
  839. * @return SimpleXMLElement
  840. */
  841. public function getFoodUnits()
  842. {
  843. $headers = $this->getHeaders();
  844. try {
  845. $this->oauth->fetch($this->baseApiUrl . "foods/units.xml", null, OAUTH_HTTP_METHOD_GET, $headers);
  846. } catch (Exception $E) {
  847. }
  848. $response = $this->oauth->getLastResponse();
  849. $responseInfo = $this->oauth->getLastResponseInfo();
  850. if (!strcmp($responseInfo['http_code'], '200')) {
  851. $xml = simplexml_load_string($response);
  852. if ($xml)
  853. return $xml;
  854. else
  855. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  856. } else {
  857. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  858. }
  859. }
  860. /**
  861. * Search for foods in foods database
  862. *
  863. * @throws FitBitException
  864. * @param string $query Search query
  865. * @return SimpleXMLElement
  866. */
  867. public function searchFoods($query)
  868. {
  869. $headers = $this->getHeaders();
  870. try {
  871. $this->oauth->fetch($this->baseApiUrl . "foods/search.xml?query=" . rawurlencode($query), null, OAUTH_HTTP_METHOD_GET, $headers);
  872. } catch (Exception $E) {
  873. }
  874. $response = $this->oauth->getLastResponse();
  875. $responseInfo = $this->oauth->getLastResponseInfo();
  876. if (!strcmp($responseInfo['http_code'], '200')) {
  877. $xml = simplexml_load_string($response);
  878. if ($xml)
  879. return $xml;
  880. else
  881. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  882. } else {
  883. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  884. }
  885. }
  886. /**
  887. * Get description of specific food from food db (or private for the user)
  888. *
  889. * @throws FitBitException
  890. * @param string $id Food Id
  891. * @return SimpleXMLElement
  892. */
  893. public function getFood($id)
  894. {
  895. $headers = $this->getHeaders();
  896. try {
  897. $this->oauth->fetch($this->baseApiUrl . "foods/" . $id . ".xml", null,
  898. OAUTH_HTTP_METHOD_GET, $headers);
  899. } catch (Exception $E) {
  900. }
  901. $response = $this->oauth->getLastResponse();
  902. $responseInfo = $this->oauth->getLastResponseInfo();
  903. if (!strcmp($responseInfo['http_code'], '200')) {
  904. $xml = simplexml_load_string($response);
  905. if ($xml)
  906. return $xml;
  907. else
  908. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  909. } else {
  910. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  911. }
  912. }
  913. /**
  914. * Create private foods for a user
  915. *
  916. * @throws FitBitException
  917. * @param string $name Food name
  918. * @param string $defaultFoodMeasurementUnitId Unit id of the default measurement unit
  919. * @param string $defaultServingSize Default serving size in measurement units
  920. * @param string $calories Calories in default serving
  921. * @param string $description
  922. * @param string $formType ("LIQUID" or "DRY)
  923. * @param string $nutrition Array of nutritional values, see http://wiki.fitbit.com/display/API/API-Create-Food
  924. * @return SimpleXMLElement
  925. */
  926. public function createFood($name, $defaultFoodMeasurementUnitId, $defaultServingSize, $calories, $description = null, $formType = null, $nutrition = null)
  927. {
  928. $headers = $this->getHeaders();
  929. $parameters = array();
  930. $parameters['name'] = $name;
  931. $parameters['defaultFoodMeasurementUnitId'] = $defaultFoodMeasurementUnitId;
  932. $parameters['defaultServingSize'] = $defaultServingSize;
  933. $parameters['calories'] = $calories;
  934. if (isset($description))
  935. $parameters['description'] = $description;
  936. if (isset($formType))
  937. $parameters['formType'] = $formType;
  938. if (isset($nutrition)) {
  939. foreach ($nutrition as $i => $value) {
  940. $parameters[$i] = $nutrition[$i];
  941. }
  942. }
  943. try {
  944. $this->oauth->fetch($this->baseApiUrl . "foods.xml", $parameters, OAUTH_HTTP_METHOD_POST, $headers);
  945. } catch (Exception $E) {
  946. }
  947. $response = $this->oauth->getLastResponse();
  948. $responseInfo = $this->oauth->getLastResponseInfo();
  949. if (!strcmp($responseInfo['http_code'], '201')) {
  950. $xml = simplexml_load_string($response);
  951. if ($xml)
  952. return $xml;
  953. else
  954. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  955. } else {
  956. $xml = simplexml_load_string($response);
  957. if (!$xml)
  958. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  959. else
  960. throw new FitBitException($responseInfo['http_code'], $xml->errors->apiError->message, 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  961. }
  962. }
  963. /**
  964. * Get user water log entries for specific date
  965. *
  966. * @throws FitBitException
  967. * @param DateTime $date
  968. * @param String $dateStr
  969. * @return SimpleXMLElement
  970. */
  971. public function getWater($date, $dateStr)
  972. {
  973. $headers = $this->getHeaders();
  974. if (!isset($dateStr)) {
  975. $dateStr = $date->format('Y-m-d');
  976. }
  977. try {
  978. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/water/date/" . $dateStr . ".xml", null, OAUTH_HTTP_METHOD_GET, $headers);
  979. } catch (Exception $E) {
  980. }
  981. $response = $this->oauth->getLastResponse();
  982. $responseInfo = $this->oauth->getLastResponseInfo();
  983. if (!strcmp($responseInfo['http_code'], '200')) {
  984. $xml = simplexml_load_string($response);
  985. if ($xml)
  986. return $xml;
  987. else
  988. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  989. } else {
  990. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  991. }
  992. }
  993. /**
  994. * Log user water
  995. *
  996. * @throws FitBitException
  997. * @param DateTime $date Log entry date (set proper timezone, which could be fetched via getProfile)
  998. * @param string $amount Amount in ml/fl oz (as set with setMetric) or waterUnit
  999. * @param string $waterUnit Water Unit ("ml", "fl oz" or "cup")
  1000. * @return SimpleXMLElement
  1001. */
  1002. public function logWater($date, $amount, $waterUnit = null)
  1003. {
  1004. $waterUnits = array('ml', 'fl oz', 'cup');
  1005. $headers = $this->getHeaders();
  1006. $parameters = array();
  1007. $parameters['date'] = $date->format('Y-m-d');
  1008. $parameters['amount'] = $amount;
  1009. if (isset($waterUnit) && in_array($waterUnit, $waterUnits))
  1010. $parameters['unit'] = $waterUnit;
  1011. try {
  1012. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/water.xml", $parameters,
  1013. OAUTH_HTTP_METHOD_POST, $headers);
  1014. } catch (Exception $E) {
  1015. }
  1016. $response = $this->oauth->getLastResponse();
  1017. $responseInfo = $this->oauth->getLastResponseInfo();
  1018. if (!strcmp($responseInfo['http_code'], '201')) {
  1019. $xml = simplexml_load_string($response);
  1020. if ($xml)
  1021. return $xml;
  1022. else
  1023. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1024. } else {
  1025. $xml = simplexml_load_string($response);
  1026. if (!$xml)
  1027. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1028. else
  1029. throw new FitBitException($responseInfo['http_code'], $xml->errors->apiError->message, 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1030. }
  1031. }
  1032. /**
  1033. * Delete user water record
  1034. *
  1035. * @throws FitBitException
  1036. * @param string $id Water log id
  1037. * @return bool
  1038. */
  1039. public function deleteWater($id)
  1040. {
  1041. $headers = $this->getHeaders();
  1042. try {
  1043. $this->oauth->fetch($this->baseApiUrl . "user/-/foods/log/water/" . $id . ".xml", null,
  1044. OAUTH_HTTP_METHOD_DELETE, $headers);
  1045. } catch (Exception $E) {
  1046. }
  1047. $responseInfo = $this->oauth->getLastResponseInfo();
  1048. if (!strcmp($responseInfo['http_code'], '204')) {
  1049. return true;
  1050. } else {
  1051. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1052. }
  1053. }
  1054. /**
  1055. * Get user sleep log entries for specific date
  1056. *
  1057. * @throws FitBitException
  1058. * @param DateTime $date
  1059. * @param String $dateStr
  1060. * @return SimpleXMLElement
  1061. */
  1062. public function getSleep($date, $dateStr = null)
  1063. {
  1064. $headers = $this->getHeaders();
  1065. if (!isset($dateStr)) {
  1066. $dateStr = $date->format('Y-m-d');
  1067. }
  1068. try {
  1069. $this->oauth->fetch($this->baseApiUrl . "user/" . $this->userId . "/sleep/date/" . $dateStr . ".xml",
  1070. null, OAUTH_HTTP_METHOD_GET, $headers);
  1071. } catch (Exception $E) {
  1072. }
  1073. $response = $this->oauth->getLastResponse();
  1074. $responseInfo = $this->oauth->getLastResponseInfo();
  1075. if (!strcmp($responseInfo['http_code'], '200')) {
  1076. $xml = simplexml_load_string($response);
  1077. if ($xml)
  1078. return $xml;
  1079. else
  1080. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1081. } else {
  1082. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1083. }
  1084. }
  1085. /**
  1086. * Log user sleep
  1087. *
  1088. * @throws FitBitException
  1089. * @param DateTime $date Sleep date and time (set proper timezone, which could be fetched via getProfile)
  1090. * @param string $duration Duration millis
  1091. * @return SimpleXMLElement
  1092. */
  1093. public function logSleep($date, $duration)
  1094. {
  1095. $headers = $this->getHeaders();
  1096. $parameters = array();
  1097. $parameters['date'] = $date->format('Y-m-d');
  1098. $parameters['startTime'] = $date->format('H:i');
  1099. $parameters['duration'] = $duration;
  1100. try {
  1101. $this->oauth->fetch($this->baseApiUrl . "user/-/sleep.xml", $parameters,
  1102. OAUTH_HTTP_METHOD_POST, $headers);
  1103. } catch (Exception $E) {
  1104. }
  1105. $response = $this->oauth->getLastResponse();
  1106. $responseInfo = $this->oauth->getLastResponseInfo();
  1107. if (!strcmp($responseInfo['http_code'], '201')) {
  1108. $xml = simplexml_load_string($response);
  1109. if ($xml)
  1110. return $xml;
  1111. else
  1112. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1113. } else {
  1114. $xml = simplexml_load_string($response);
  1115. if (!$xml)
  1116. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1117. else
  1118. throw new FitBitException($responseInfo['http_code'], $xml->errors->apiError->message, 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1119. }
  1120. }
  1121. /**
  1122. * Delete user sleep record
  1123. *
  1124. * @throws FitBitException
  1125. * @param string $id Activity log id
  1126. * @return bool
  1127. */
  1128. public function deleteSleep($id)
  1129. {
  1130. $headers = $this->getHeaders();
  1131. try {
  1132. $this->oauth->fetch($this->baseApiUrl . "user/-/sleep/" . $id . ".xml", null,
  1133. OAUTH_HTTP_METHOD_DELETE, $headers);
  1134. } catch (Exception $E) {
  1135. }
  1136. $responseInfo = $this->oauth->getLastResponseInfo();
  1137. if (!strcmp($responseInfo['http_code'], '204')) {
  1138. return true;
  1139. } else {
  1140. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1141. }
  1142. }
  1143. /**
  1144. * Get user body measurements
  1145. *
  1146. * @throws FitBitException
  1147. * @param DateTime $date
  1148. * @param String $dateStr
  1149. * @return SimpleXMLElement
  1150. */
  1151. public function getBody($date, $dateStr = null)
  1152. {
  1153. $headers = $this->getHeaders();
  1154. if (!isset($dateStr)) {
  1155. $dateStr = $date->format('Y-m-d');
  1156. }
  1157. try {
  1158. $this->oauth->fetch($this->baseApiUrl . "user/" . $this->userId . "/body/date/" . $dateStr . ".xml",
  1159. null, OAUTH_HTTP_METHOD_GET, $headers);
  1160. } catch (Exception $E) {
  1161. }
  1162. $response = $this->oauth->getLastResponse();
  1163. $responseInfo = $this->oauth->getLastResponseInfo();
  1164. if (!strcmp($responseInfo['http_code'], '200')) {
  1165. $xml = simplexml_load_string($response);
  1166. if ($xml)
  1167. return $xml;
  1168. else
  1169. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1170. } else {
  1171. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1172. }
  1173. }
  1174. /**
  1175. * Log user body measurements
  1176. *
  1177. * @throws FitBitException
  1178. * @param string $weight Float number. For en_GB units, provide floating number of stones (i.e. 11 st. 4 lbs = 11.2857143)
  1179. * @param string $fat Float number
  1180. * @param string $bicep Float number
  1181. * @param string $calf Float number
  1182. * @param string $chest Float number
  1183. * @param string $forearm Float number
  1184. * @param string $hips Float number
  1185. * @param string $neck Float number
  1186. * @param string $thigh Float number
  1187. * @param string $waist Float number
  1188. * @param DateTime $date Date Log entry date (set proper timezone, which could be fetched via getProfile)
  1189. * @return SimpleXMLElement
  1190. */
  1191. public function logBody($date, $weight = null, $fat = null, $bicep = null, $calf = null, $chest = null, $forearm = null, $hips = null, $neck = null, $thigh = null, $waist = null)
  1192. {
  1193. $headers = $this->getHeaders();
  1194. $parameters = array();
  1195. $parameters['date'] = $date->format('Y-m-d');
  1196. if (isset($weight))
  1197. $parameters['weight'] = $weight;
  1198. if (isset($fat))
  1199. $parameters['fat'] = $fat;
  1200. if (isset($bicep))
  1201. $parameters['bicep'] = $bicep;
  1202. if (isset($calf))
  1203. $parameters['calf'] = $calf;
  1204. if (isset($chest))
  1205. $parameters['chest'] = $chest;
  1206. if (isset($forearm))
  1207. $parameters['forearm'] = $forearm;
  1208. if (isset($hips))
  1209. $parameters['hips'] = $hips;
  1210. if (isset($neck))
  1211. $parameters['neck'] = $neck;
  1212. if (isset($thigh))
  1213. $parameters['thigh'] = $thigh;
  1214. if (isset($waist))
  1215. $parameters['waist'] = $waist;
  1216. try {
  1217. $this->oauth->fetch($this->baseApiUrl . "user/-/body.xml",
  1218. $parameters, OAUTH_HTTP_METHOD_POST, $headers);
  1219. } catch (Exception $E) {
  1220. }
  1221. $response = $this->oauth->getLastResponse();
  1222. $responseInfo = $this->oauth->getLastResponseInfo();
  1223. if (!strcmp($responseInfo['http_code'], '201')) {
  1224. $xml = simplexml_load_string($response);
  1225. if ($xml)
  1226. return $xml;
  1227. else
  1228. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1229. } else {
  1230. $xml = simplexml_load_string($response);
  1231. if (!$xml)
  1232. throw new FitBitException($responseInfo['http_code'], 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1233. else
  1234. throw new FitBitException($responseInfo['http_code'], $xml->errors->apiError->message, 'Fitbit request failed. Code: ' . $responseInfo['http_code']);
  1235. }
  1236. }
  1237. /**
  1238. * Log user weight
  1239. *
  1240. * @throws FitBitException
  1241. * @param string $weight Float number. For en_GB units, provide floating number of stones (i.e. 11 st. 4 lbs = 11.2857143)
  1242. * @param DateTime $date If present, log entry date, now by default (set proper timezone, which could be fetched via getProfile)
  1243. * @return bool
  1244. */
  1245. public function logWeight($weight, $date = null)
  1246. {
  1247. $headers = $this->getHeaders();
  1248. $parameters = array();
  1249. $parameters['weight'] = $weight;
  1250. if (isset($date))
  1251. $parameters['date'] = $date->format('Y-m-d');
  1252. try {
  1253. $this->oauth->fetch($this->baseApiUrl . "user/-/body/weight.xml",
  1254. $parameters, OAUTH_

Large files files are truncated, but you can click here to view the full file