Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,48 @@ print_r($foods);
echo '</pre>';
```

## Time Series Data ##

Time series data can be colected as described [http://wiki.fitbit.com/display/API/API-Get-Time-Series](http://wiki.fitbit.com/display/API/API-Get-Time-Series)

The base class, TimeSeriesGateway, uses the magic __call method to map methods calls to resource endpoints. The method name is converted to the last segment of the URI, the rest of the path is handled by the class.

```php
$sleep_time_series_gateway = $factory->getTimeSeriesGateway();
$minutes_asleep = $sleep_time_series_gateway->getMinutesAsleep();
```

A method call without parameters will default to a time series of today/1d. A period, baseDate and endDate can be passed to specify the time series. *Note: period will override endDate.

```php
//past seven days
$minutes_asleep = $sleep_time_series_gateway->getMinutesAsleep('today','7d');

//seven days before the new year (*Note you can also pass Datetime objects for baseDate and endDate)
$minutes_asleep = $sleep_time_series_gateway->getMinutesAsleep('2014-01-01','7d');

//first week of new year
$minutes_asleep = $sleep_time_series_gateway->getMinutesAsleep('2014-01-01', null, '2014-01-07');
```

The Activities Time Series Resource allows you to limit the data collected to that logged only by the tracker. To do so pass true|false (default false) as the first argument in activites timeseries calls

```php
$activities_time_series_gateway = $factory->getActivitiesSeriesGateway();
//get the minutes of very active activity from the tracker only for the previous 7 days
$tracker_minutes_very_active = $activities_time_series_gateway->getMinutesVeryActive(true, 'today', '7d');
```
*Note: the activities/caloriesBMR resource does not appear to have a corresponding activities/tracker/caloriesBMR. The tracker parameter for getCaloriesBMR(true) will automatically be set to false.


## Notes ##

* By default, all requests assume you want data for the authorized user (viewer). There are, however, several endpoints you can use to access the data of other Fitbit users, given that you have permission to access their data. This is accomplished by setting the Fitbit User ID with the `setUserID` method available on `ApiGatewayFactory` and the Endpoint Gateways (e.g. `UserGateway`, `FoodGateway`).
* *Subscriptions*: this library has some basic methods to add/delete subscriptions, but it's your responsibility to track the list and maintain server endpoints to receive notifications from Fitbit, as well as register them at [http://dev.fitbit.com](http://dev.fitbit.com). See [Subscriptions API](https://wiki.fitbit.com/display/API/Fitbit+Subscriptions+API) for more information.

## Known Issues ##

At the time of writing, the following resources do not currently work, or are documented incorrectly by Fitbit's documentation.

* activities/floors
* activities/elevation
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"license" : "Apache-2.0",
"authors": [
{
"name": "Ryan Martinsen",
"name": ["Ryan Martinsen","Juni Samos"],
"email": "ryan@ryanware.com",
"homepage": "http://ryanmartinsen.com"
},
Expand All @@ -19,7 +19,7 @@
],
"require": {
"php": ">=5.3.0",
"lusitanian/oauth": "~0.2"
"lusitanian/oauth": "0.2.5"
},
"autoload": {
"psr-0": {
Expand Down
55 changes: 55 additions & 0 deletions lib/Fitbit/ActivityTimeSeriesGateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace Fitbit;

class ActivityTimeSeriesGateway extends TimeSeriesEndpointGateway {

/**
* base fragment for this resources uri
*
* @var sting
*/
protected static $format = 'activities/%s/date';

/**
* convert to trcker only fragment
*
* @param string $fragment
* @return string
*/
protected function trackerOnlyFragment($fragment)
{
return str_replace('activities', 'activities/tracker', $fragment);
}

/**
* extended get to all for tracker only resource calls
*
* @throws Exception
* @param string $fragment
* @param bool $tracker
* @param \DateTime|string $baseDate
* @param string $period
* @param \DateTime|string $endDate
* @return mixed SimpleXMLElement or the value encoded in json as an object
*/
public function get($fragment, $tracker = false, $baseDate = null, $period = null, $endDate = null)
{
$fragment = ($tracker) ? $this->trackerOnlyFragment($fragment) : $fragment;
return parent::get($fragment, $baseDate, $period, $endDate);
}

/**
* extended call, to ensure methods without tracker
* have tracker set to false
*
* {@inheritdoc}
*/
public function __call($method, $parameters)
{
if (in_array($method, array('getCaloriesBMR'))) $parameters[0] = false;
return parent::__call($method, $parameters);
}


}
28 changes: 28 additions & 0 deletions lib/Fitbit/ApiGatewayFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,27 +167,55 @@ public function getActivityGateway()
return $gateway;
}

public function getActivityTimeSeriesGateway()
{
$gateway = new ActivityTimeSeriesGateway;
$this->injectGatewayDependencies($gateway);
return $gateway;
}

public function getBodyGateway()
{
$gateway = new BodyGateway;
$this->injectGatewayDependencies($gateway);
return $gateway;
}

public function getBodyTimeSeriesGateway()
{
$gateway = new BodyTimeSeriesGateway;
$this->injectGatewayDependencies($gateway);
return $gateway;
}

public function getFoodGateway()
{
$gateway = new FoodGateway;
$this->injectGatewayDependencies($gateway);
return $gateway;
}

public function getFoodTimeSeriesGateway()
{
$gateway = new FoodTimeSeriesGateway;
$this->injectGatewayDependencies($gateway);
return $gateway;
}

public function getSleepGateway()
{
$gateway = new SleepGateway;
$this->injectGatewayDependencies($gateway);
return $gateway;
}

public function getSleepTimeSeriesGateway()
{
$gateway = new SleepTimeSeriesGateway;
$this->injectGatewayDependencies($gateway);
return $gateway;
}

public function getTimeGateway()
{
$gateway = new TimeGateway;
Expand Down
15 changes: 15 additions & 0 deletions lib/Fitbit/BodyTimeSeriesGateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Fitbit;

class BodyTimeSeriesGateway extends TimeSeriesEndpointGateway {


/**
* base fragment for this resources uri
*
* @var sting
*/
protected static $format = 'body/%s/date';

}
15 changes: 15 additions & 0 deletions lib/Fitbit/FoodTimeSeriesGateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Fitbit;

class FoodTimeSeriesGateway extends TimeSeriesEndpointGateway {


/**
* base fragment for this resources uri
*
* @var sting
*/
protected static $format = 'foods/log/%s/date';

}
15 changes: 15 additions & 0 deletions lib/Fitbit/SleepTimeSeriesGateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php

namespace Fitbit;

class SleepTimeSeriesGateway extends TimeSeriesEndpointGateway {


/**
* base fragment for this resources uri
*
* @var sting
*/
protected static $format = 'sleep/%s/date';

}
67 changes: 67 additions & 0 deletions lib/Fitbit/TimeSeriesEndpointGateway.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

namespace Fitbit;
use DateTime;

class TimeSeriesEndpointGateway extends EndpointGateway {


/**
* base fragment for the instantiated resource uri
*
* @var sting
*/
protected static $format;

/**
* create a uri fragment from a method name
*
* @param string $method
*/
public function fragment($method)
{
$method = substr($method, 3);
$fragment = strtolower($method[0]) . substr($method, 1);
return sprintf(static::$format, $fragment);
}

/**
* Get user time series
*
* @throws Exception
* @param string $fragment
* @param \DateTime|string $baseDate
* @param string $period
* @param \DateTime|string $endDate
* @return mixed SimpleXMLElement or the value encoded in json as an object
*/
public function get($fragment, $baseDate = null, $period = null, $endDate = null)
{
$date1 = $baseDate ?: 'today';
$date2 = ($period) ? $period : ($endDate) ?: '1d';

if ($date1 instanceof Datetime)
$date1 = $date1->format("Y-m-d");

if ($date2 instanceof Datetime)
$date2 = $date2->format("Y-m-d");

$endpoint = sprintf('user/%s/%s/%s/%s', $this->userID, $fragment, $date1, $date2);
return $this->makeApiRequest($endpoint);
}

/**
* Dynamically pass methods to get.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
$fragment = $this->fragment($method);
array_unshift($parameters, $fragment);
return call_user_func_array(array($this, 'get'), $parameters);
}

}