diff --git a/lib/CurlRequest.php b/lib/CurlRequest.php index f9cd242..87014b5 100644 --- a/lib/CurlRequest.php +++ b/lib/CurlRequest.php @@ -9,6 +9,7 @@ use PHPShopify\Exception\CurlException; +use PHPShopify\Exception\ResourceRateLimitException; /* |-------------------------------------------------------------------------- @@ -47,6 +48,7 @@ protected static function init($url, $httpHeaders = array()) //Return the transfer as a string curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_USERAGENT, 'PHPClassic/PHPShopify'); $headers = array(); @@ -143,15 +145,24 @@ public static function delete($url, $httpHeaders = array()) protected static function processRequest($ch) { # Check for 429 leaky bucket error - while(1) { - $output = curl_exec($ch); - self::$lastHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); - if(self::$lastHttpCode != 429) { - break; - } - usleep(500000); + while (1) { + $output = curl_exec($ch); + $response = new CurlResponse($output); + + self::$lastHttpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + if (self::$lastHttpCode != 429) { + break; + } + + $limitHeader = explode('/', $response->getHeader('X-Shopify-Shop-Api-Call-Limit'), 2); + + if (isset($limitHeader[1]) && $limitHeader[0] < $limitHeader[1]) { + throw new ResourceRateLimitException($response->getBody()); + } + + usleep(500000); } - + if (curl_errno($ch)) { throw new Exception\CurlException(curl_errno($ch) . ' : ' . curl_error($ch)); } @@ -159,7 +170,7 @@ protected static function processRequest($ch) // close curl resource to free up system resources curl_close($ch); - return $output; + return $response->getBody(); } } diff --git a/lib/CurlResponse.php b/lib/CurlResponse.php new file mode 100644 index 0000000..cc05405 --- /dev/null +++ b/lib/CurlResponse.php @@ -0,0 +1,73 @@ +parse($response); + } + + /** + * @param string $response + */ + private function parse($response) + { + $response = \explode("\r\n\r\n", $response); + if (\count($response) > 1) { + // We want the last two parts + $response = \array_slice($response, -2, 2); + list($headers, $body) = $response; + foreach (\explode("\r\n", $headers) as $header) { + $pair = \explode(': ', $header, 2); + if (isset($pair[1])) { + $this->headers[$pair[0]] = $pair[1]; + } + } + } else { + $body = $response[0]; + } + + $this->body = $body; + } + + /** + * @return array + */ + public function getHeaders() + { + return $this->headers; + } + + /** + * @param string $key + * + * @return string + */ + public function getHeader($key) + { + return isset($this->headers[$key]) ? $this->headers[$key] : null; + } + + /** + * @return string + */ + public function getBody() + { + return $this->body; + } + + public function __toString() + { + $body = $this->getBody(); + $body = $body ? : ''; + + return $body; + } +} diff --git a/lib/Exception/ResourceRateLimitException.php b/lib/Exception/ResourceRateLimitException.php new file mode 100644 index 0000000..1e7843d --- /dev/null +++ b/lib/Exception/ResourceRateLimitException.php @@ -0,0 +1,8 @@ +