From 4e28406e3bdafe8655c20185c1d6e8a94248559e Mon Sep 17 00:00:00 2001 From: tuckdesign Date: Fri, 3 Aug 2018 15:04:49 +0200 Subject: [PATCH 1/4] Fixed typo in TogglRecord: $this::element_plural_name Changed API version to v8 Added debug property in TogglRecord and TogglConnection and public method getCurlDebugInfo in TogglRecord that will return verbose cURL response --- src/TogglConnection.php | 21 +++++++++++++++++++-- src/TogglRecord.php | 15 ++++++++++++--- src/toggl.php | 4 ++-- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/src/TogglConnection.php b/src/TogglConnection.php index 1cfe5a9..8545a67 100644 --- a/src/TogglConnection.php +++ b/src/TogglConnection.php @@ -9,13 +9,16 @@ class TogglConnection { /** * The Toggl API version, used in HTTP requests. */ - const API_VERSION = 'v6'; + const API_VERSION = 'v8'; private $userAgent = 'Toggl PHP SDK'; private $token; private $options = array(); + + public $debug = false; + public $curlVerbose = null; /** * Construct the API object. @@ -53,7 +56,7 @@ public function setOptions(array $options) { * A fully-quantified Toggl API URL. */ public function getURL($resource, array $query = array()) { - $url = 'https://www.toggl.com/api/' . self::API_VERSION . '/' . $resource . '.json'; + $url = 'https://www.toggl.com/api/' . self::API_VERSION . '/' . $resource; if (!empty($query)) { $url .= '?' . http_build_query($query, NULL, '&'); } @@ -98,6 +101,12 @@ public function request($resource, array $options = array()) { curl_setopt($ch, CURLOPT_USERAGENT, $this->userAgent); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $options['method']); curl_setopt($ch, CURLOPT_USERPWD, $this->getToken() . ':api_token'); + if ($this->debug) { + $this->curlVerbose = array('url' => $url, 'postfields' => isset($options['data'])?json_encode($options['data']):null); + curl_setopt($ch, CURLOPT_VERBOSE, true); + $verbose = fopen('php://temp', 'rw+'); + curl_setopt($ch, CURLOPT_STDERR, $verbose); + } // Build and format the headers. foreach (array_merge($this->getHeaders(), $options['headers']) as $header => $value) { @@ -118,6 +127,14 @@ public function request($resource, array $options = array()) { $response->success = $response->code == 200; curl_close($ch); + + if ($this->debug) { + rewind($verbose); + $this->curlVerbose['result'] = $result; + $this->curlVerbose['curl'] = stream_get_contents($verbose); + fclose($verbose); + } + return $response; } diff --git a/src/TogglRecord.php b/src/TogglRecord.php index 8bf25ed..0c02c31 100644 --- a/src/TogglRecord.php +++ b/src/TogglRecord.php @@ -6,9 +6,12 @@ abstract class TogglRecord { protected $data = array(); protected $connection; + + public $debug = false; public function __construct(TogglConnection $connection, array $data = array()) { $this->connection = $connection; + $this->connection->debug = $this->debug; $this->data = $data; } @@ -57,7 +60,7 @@ public static function load(TogglConnection $connection, $id, array $options = a if (!empty($response->data['data'])) { return new $class($connection, $response->data['data']); } - return FALSE; + return $response->success; } public static function loadMultiple(TogglConnection $connection, array $options = array()) { @@ -75,10 +78,10 @@ public static function loadMultiple(TogglConnection $connection, array $options public function save(array $options = array()) { $options['method'] = !empty($this->id) ? 'PUT' : 'POST'; $options['data'][$this::$element_name] = $this->data; - $resource = $this::element_plural_name . (!empty($this->id) ? '/' . $this->id : ''); + $resource = $this::$element_plural_name . (!empty($this->id) ? '/' . $this->id : ''); $response = $this->connection->request($resource, $options); $this->data = $response->data['data']; - return TRUE; + return $response->success; } public function delete(array $options = array()) { @@ -86,8 +89,14 @@ public function delete(array $options = array()) { $options['method'] = 'DELETE'; $resource = $this::$element_plural_name . '/' . $this->id; $response = $this->connection->request($resource, $options); + return $response->success; } $this->data = array(); return TRUE; } + + public function getCurlDebugInfo() { + return $this->connection->curlVerbose; + } + } diff --git a/src/toggl.php b/src/toggl.php index eb38525..b6fa67d 100644 --- a/src/toggl.php +++ b/src/toggl.php @@ -12,7 +12,7 @@ class Toggl { /** * The Toggl API version, used in HTTP requests. */ - const API_VERSION = 'v6'; + const API_VERSION = 'v8'; const DATE_FORMAT = 'Y-m-d\TH:i:sO'; @@ -47,7 +47,7 @@ public function getToken() { * A fully-quantified Toggl API URL. */ protected function getURL($resource, array $query = array()) { - $url = 'https://www.toggl.com/api/' . self::API_VERSION . '/' . $resource . '.json'; + $url = 'https://www.toggl.com/api/' . self::API_VERSION . '/' . $resource; if (!empty($query)) { $url .= '?' . http_build_query($query, NULL, '&'); } From dd81d62744e3bc3114cdf60b2aaa4fe9abb1e3a4 Mon Sep 17 00:00:00 2001 From: tuckdesign Date: Tue, 4 Sep 2018 14:20:51 +0200 Subject: [PATCH 2/4] Fixed date format for API v8 --- src/TogglUtility.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TogglUtility.php b/src/TogglUtility.php index d12ab25..6404796 100644 --- a/src/TogglUtility.php +++ b/src/TogglUtility.php @@ -10,7 +10,7 @@ class TogglUtility { /** * The date format used by Toggl.com. */ - const DATE_FORMAT = 'Y-m-d\TH:i:sO'; + const DATE_FORMAT = 'c'; /** * Filter an array of objects or nested arrays by a variable depth value. From 370e8e869b745d3b98b655e2b1f5faaeee304905 Mon Sep 17 00:00:00 2001 From: tuckdesign Date: Tue, 4 Sep 2018 14:23:59 +0200 Subject: [PATCH 3/4] Fixed loadMultiple method in Record --- src/TogglRecord.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/TogglRecord.php b/src/TogglRecord.php index 0c02c31..a176cbf 100644 --- a/src/TogglRecord.php +++ b/src/TogglRecord.php @@ -66,13 +66,12 @@ public static function load(TogglConnection $connection, $id, array $options = a public static function loadMultiple(TogglConnection $connection, array $options = array()) { $class = get_called_class(); $response = $connection->request($class::$element_plural_name, $options); - $count = 0; - foreach ($response->data['data'] as $key => $record) { - $response->data['data'][$key] = new $class($connection, $record); - $count++; + $ret = array('data' => array(), 'count' => 0); + foreach ($response->data as $key => $record) { + $ret['data'][] = new $class($connection, $record); } - $response->data['count'] = $count; - return $response->data; + $ret['count'] = count($ret['data']); + return $ret; } public function save(array $options = array()) { From 22e0978092cc86b8c145944fc1591f520a2e5ce4 Mon Sep 17 00:00:00 2001 From: tuckdesign Date: Fri, 7 Sep 2018 09:38:27 +0200 Subject: [PATCH 4/4] Added TogglReport API --- src/TogglConnection.php | 2 +- src/TogglReport.php | 45 +++++++++++++++++++++++++++++++++++ src/TogglReportConnection.php | 34 ++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/TogglReport.php create mode 100644 src/TogglReportConnection.php diff --git a/src/TogglConnection.php b/src/TogglConnection.php index 8545a67..37b6f2e 100644 --- a/src/TogglConnection.php +++ b/src/TogglConnection.php @@ -11,7 +11,7 @@ class TogglConnection { */ const API_VERSION = 'v8'; - private $userAgent = 'Toggl PHP SDK'; + public $userAgent = 'Toggl PHP SDK'; private $token; diff --git a/src/TogglReport.php b/src/TogglReport.php new file mode 100644 index 0000000..d91366c --- /dev/null +++ b/src/TogglReport.php @@ -0,0 +1,45 @@ + array(), + 'count' => 0 + ); + + if (isset($start_date) && isset($end_date)) { + + if ($end_date < $start_date) { + throw new TogglException("Start date cannot be after the end date."); + } + $options['query']['workspace_id'] = $workspaceId; + $options['query']['since'] = gmdate('Y-m-d', $start_date); + $options['query']['until'] = gmdate('Y-m-d', $end_date); + } else { + return $ret; + } + + $page = 1; + while (true) { + $options['query']['page'] = $page; + $response = $connection->request('details', $options); + if (!$response->success) throw new TogglException($response->data['error']['message']); + + foreach ($response->data['data'] as $key => $record) { + $entry = new TogglTimeEntry($connection, $record); + $entry->wid = $workspaceId; + $ret['data'][] = $entry; + } + if ($page==$response->data['total_count']) break; + $page++; + } + $ret['count'] = count($ret['data']); + return $ret; + } + +} diff --git a/src/TogglReportConnection.php b/src/TogglReportConnection.php new file mode 100644 index 0000000..5894006 --- /dev/null +++ b/src/TogglReportConnection.php @@ -0,0 +1,34 @@ +userAgent; + $url = 'https://toggl.com/reports/api/' . $this->report_api_version . '/' . $resource; + if (!empty($query)) { + $url .= '?' . http_build_query($query, NULL, '&'); + } + return $url; + } + +}