diff --git a/lib/Client.php b/lib/Client.php index d52ad76..53a96f1 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -82,6 +82,13 @@ class Client { */ public $language; + /** + * Callback called on every new request created + * + * @var \Closure + */ + private $newRequestEventCallback; + /** * Create a new API client * @@ -104,7 +111,11 @@ public function __construct($accountcode, $accesskey, $secretkey) { * @return Request */ public function newRequest($method, $url) { - return new Request($this, $method, $url); + $request = new Request($this, $method, $url); + if (isset($this->newRequestEventCallback)) { + ($this->newRequestEventCallback)($request); + } + return $request; } /** @@ -115,4 +126,13 @@ public function newRequest($method, $url) { public function setLanguage($lang) { $this->language = $lang; } + + /** + * Set new request event callback + * + * @param \Closure $newRequestEventCallback + */ + public function setNewRequestEventCallback(\Closure $newRequestEventCallback) { + $this->newRequestEventCallback = $newRequestEventCallback; + } } diff --git a/lib/Model/Contact.php b/lib/Model/Contact.php index 12f2535..fe9621a 100644 --- a/lib/Model/Contact.php +++ b/lib/Model/Contact.php @@ -301,7 +301,7 @@ public function jsonSerialize() { $result["addresses"] = $this->addresses; } if (!is_null($this->birthdate)) { - $result["birthdate"] = Json::packTimestamp($this->birthdate); + $result["birthdate"] = !empty($this->birthdate) ? Json::packTimestamp($this->birthdate) : null; } if (!is_null($this->company)) { $result["company"] = strval($this->company); diff --git a/lib/Model/Event.php b/lib/Model/Event.php index 847ae1a..e24ed15 100644 --- a/lib/Model/Event.php +++ b/lib/Model/Event.php @@ -487,6 +487,7 @@ public static function fromJson($obj) { "webremark" => isset($obj->webremark) ? $obj->webremark : null, "createdts" => isset($obj->createdts) ? Json::unpackTimestamp($obj->createdts) : null, "lastupdatets" => isset($obj->lastupdatets) ? Json::unpackTimestamp($obj->lastupdatets) : null, + "totalmaxtickets" => isset($obj->totalmaxtickets) ? $obj->totalmaxtickets : null, )); $result->custom_fields = array(); diff --git a/lib/Model/ProductProperty.php b/lib/Model/ProductProperty.php index 0ae662c..5a60e44 100644 --- a/lib/Model/ProductProperty.php +++ b/lib/Model/ProductProperty.php @@ -79,6 +79,11 @@ public function __construct(array $data = array()) { */ public $values; + /** + * @var string + */ + public $isarchived; + /** * Unpack ProductProperty from JSON. * @@ -96,6 +101,7 @@ public static function fromJson($obj) { "description" => isset($obj->description) ? $obj->description : null, "key" => isset($obj->key) ? $obj->key : null, "values" => isset($obj->values) ? Json::unpackArray("KeyValueItem", $obj->values) : null, + "isarchived" => $obj->isarchived ?? null )); } @@ -118,6 +124,9 @@ public function jsonSerialize() { if (!is_null($this->values)) { $result["values"] = $this->values; } + if (!is_null($this->isarchived)) { + $result["isarchived"] = $this->isarchived; + } return $result; } diff --git a/lib/Request.php b/lib/Request.php index dcb91e1..7b17b22 100644 --- a/lib/Request.php +++ b/lib/Request.php @@ -83,6 +83,34 @@ class Request { */ private $responseHeaders; + /** + * The number of milliseconds to wait while trying to connect + * + * @var int + */ + private $connectTimeoutMs; + + /** + * The maximum number of milliseconds to allow the request to execute + * + * @var int + */ + private $timeoutMs; + + /** + * The proxy to tunnel requests through + * + * @var string + */ + private $proxy; + + /** + * FALSE to stop cURL from verifying the peer's certificate. + * + * @var bool + */ + private $sslVerifyPeer; + /** * Create a new API request. * @@ -149,11 +177,28 @@ private function prepare() { curl_setopt($c, CURLOPT_CUSTOMREQUEST, $this->method); curl_setopt($c, CURLOPT_HEADERFUNCTION, array($this, 'handleHeader')); + if (isset($this->sslVerifyPeer)) { + curl_setopt($c, CURLOPT_SSL_VERIFYPEER, $this->sslVerifyPeer); + } if (isset($_SERVER["TM_TRAVIS"])) { // Travis has a broken CA cert bundle, ignore errors there curl_setopt($c, CURLOPT_SSL_VERIFYPEER, FALSE); } + if (isset($this->connectTimeoutMs)) { + curl_setopt($c, CURLOPT_CONNECTTIMEOUT_MS, $this->connectTimeoutMs); + } + if (isset($this->timeoutMs)) { + curl_setopt($c, CURLOPT_TIMEOUT_MS, $this->timeoutMs); + } + if (!empty($this->proxy)) { + list($proxy, $proxyPort) = explode(':', $this->proxy); + curl_setopt($c, CURLOPT_PROXY, $proxy); + if (ctype_digit($proxyPort)) { + curl_setopt($c, CURLOPT_PROXYPORT, $proxyPort); + } + } + if ($this->client->language) { $headers[] = "Accept-Language: " . $this->client->language; } @@ -163,9 +208,7 @@ private function prepare() { $headers[] = "Expect:"; // issue with cURL when doing big size POSTs https://stackoverflow.com/questions/14158675/how-can-i-stop-curl-from-using-100-continue if ($this->bodycontenttype == "json") { foreach ($this->body as $key => $value) { - if (!is_null($value)) { - $body[$key] = $value; - } + $body[$key] = $value; } $body = json_encode($body); $headers[] = "Content-Type: application/json"; @@ -276,9 +319,16 @@ public static function checkError($c, $output, array $headers = array()) { if ($info["http_code"] == 429) { $backoff = isset($headers["retry-after"]) ? $headers["retry-after"] : 0; throw new RateLimitException($backoff); - } else if ($info["http_code"] != 200) { - if ($info["http_code"] == 0) { + } + else { + if ($info["http_code"] == 200) { + // time-outs have a 200 code incl. an error, so we should check it $output = curl_error($c); + + // No error, so return + if (empty($output)) { + return; + } } throw new ClientException($info["http_code"], $output); } @@ -291,4 +341,47 @@ public function handleHeader($curl, $header) { } return strlen($header); } + + /** + * Set number of milliseconds to wait while trying to connect + * Use 0 to wait indefinitely. + * + * @param int $connectTimeoutMs + * + */ + public function setConnectTimeoutMs(int $connectTimeoutMs) { + $this->connectTimeoutMs = $connectTimeoutMs; + } + + /** + * Set maximum time the request is allowed to take in milliseconds + * Use 0 to wait indefinitely. + * + * @param int $timeoutMs + * + */ + public function setTimeoutMs(int $timeoutMs) { + $this->timeoutMs = $timeoutMs; + } + + /** + * The proxy to tunnel requests through + * Use : seperator to to add a port + * + * @param string $proxy + * + */ + public function setProxy(string $proxy) { + $this->proxy = $proxy; + } + + /** + * FALSE to stop cURL from verifying the peer's certificate. + * + * @param bool $sslVerifyPeer + * + */ + public function setSslVerifyPeer(bool $sslVerifyPeer) { + $this->sslVerifyPeer = $sslVerifyPeer; + } }