/lib/taxamo/Taxamo/Swagger.php

  1. <?php 
  2. /** 
  3. * Swagger.php 
  4. */ 
  5.  
  6.  
  7. /** Autoload the model definition files */ 
  8. /** 
  9. * 
  10. * 
  11. * @param string $className the class to attempt to load 
  12. */ 
  13. function swagger_autoloader($className) { 
  14. $currentDir = dirname(__FILE__); 
  15. if (file_exists($currentDir . '/models/' . lcfirst($className) . '.php')) { 
  16. include $currentDir . '/models/' . lcfirst($className) . '.php'; 
  17. } elseif (file_exists($currentDir . '/' . lcfirst($className) . '.php')) { 
  18. include $currentDir . '/' . lcfirst($className) . '.php'; 
  19. } elseif (file_exists($currentDir . '/' . $className . '.php')) { 
  20. include $currentDir . '/' . $className . '.php'; 
  21. } elseif (file_exists($currentDir . '/models/' . $className . '.php')) { 
  22. include $currentDir . '/models/' . $className . '.php'; 
  23. spl_autoload_register('swagger_autoloader'); 
  24.  
  25.  
  26. class APIClient { 
  27.  
  28. public static $POST = "POST"; 
  29. public static $GET = "GET"; 
  30. public static $PUT = "PUT"; 
  31. public static $DELETE = "DELETE"; 
  32.  
  33. /** 
  34. * @param string $apiKey your API key 
  35. * @param string $apiServer the address of the API server 
  36. */ 
  37. function __construct($apiKey, $apiServer) { 
  38. $this->apiKey = $apiKey; 
  39. $this->apiServer = $apiServer; 
  40.  
  41.  
  42. /** 
  43. * @param string $resourcePath path to method endpoint 
  44. * @param string $method method to call 
  45. * @param array $queryParams parameters to be place in query URL 
  46. * @param array $postData parameters to be placed in POST body 
  47. * @param array $headerParams parameters to be place in request header 
  48. * @return mixed 
  49. */ 
  50. public function callAPI($resourcePath, $method, $queryParams, $postData,  
  51. $headerParams) { 
  52.  
  53. $headers = array(); 
  54.  
  55. # Allow API key from $headerParams to override default 
  56. $added_api_key = False; 
  57. if ($headerParams != null) { 
  58. foreach ($headerParams as $key => $val) { 
  59. $headers[] = "$key: $val"; 
  60. if ($key == 'token') { 
  61. $added_api_key = True; 
  62. if (! $added_api_key) { 
  63. $headers[] = "Token: " . $this->apiKey; 
  64.  
  65. if (is_object($postData) or is_array($postData)) { 
  66. $postData = json_encode($this->sanitizeForSerialization($postData)); 
  67.  
  68. $url = $this->apiServer . $resourcePath; 
  69.  
  70. $curl = curl_init(); 
  71. curl_setopt($curl, CURLOPT_TIMEOUT, 5); 
  72. // return the result on success, rather than just TRUE 
  73. curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); 
  74. curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); 
  75. curl_setopt($curl, CURLOPT_SSLVERSION, 1); 
  76. curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1); 
  77. curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); 
  78.  
  79. if (! empty($queryParams)) { 
  80. $url = ($url . '?' . http_build_query($queryParams)); 
  81.  
  82. if ($method == self::$POST) { 
  83. curl_setopt($curl, CURLOPT_POST, true); 
  84. curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); 
  85. } else if ($method == self::$PUT) { 
  86. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT"); 
  87. curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); 
  88. } else if ($method == self::$DELETE) { 
  89. curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE"); 
  90. curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); 
  91. } else if ($method != self::$GET) { 
  92. throw new Exception('Method ' . $method . ' is not recognized.'); 
  93. curl_setopt($curl, CURLOPT_URL, $url); 
  94.  
  95. // Make the request 
  96. $response = curl_exec($curl); 
  97. $response_info = curl_getinfo($curl); 
  98.  
  99. // Handle the response 
  100. if ($response_info['http_code'] == 0) { 
  101. throw new TaxamoAPIException("TIMEOUT: api call to " . $url . 
  102. " took more than 5s to return",  
  103. $postData,  
  104. $response_info); 
  105. } else if ($response_info['http_code'] == 200) { 
  106. $data = json_decode($response); 
  107. } else if ($response_info['http_code'] == 401) { 
  108. throw new TaxamoAuthenticationException("Unauthorized API request to ".$url.": ".$response,  
  109. $postData,  
  110. $response); 
  111. } else if ($response_info['http_code'] == 400) { 
  112. try { 
  113. $data = json_decode($response); 
  114. } catch (Exception $e) { 
  115. throw new TaxamoValidationException("Validation error for " . $url . 
  116. ": ".$response."post data:".$postData,  
  117. $postData,  
  118. $response); 
  119. if (isset($data->validation_failures)) { 
  120. throw new TaxamoValidationException("Validation error for " . $url,  
  121. $postData,  
  122. $response,  
  123. $data->errors,  
  124. $data->validation_failures); 
  125. } else { 
  126. var_dump($data->errors); 
  127. throw new TaxamoValidationException("Validation error for " . $url . 
  128. ": ".$response."post data:".$postData,  
  129. $postData,  
  130. $response,  
  131. $data->errors); 
  132.  
  133. } else if ($response_info['http_code'] == 404) { 
  134. $data = null; 
  135. } else { 
  136. throw new TaxamoAPIException("Can't connect to the api: " . $url . 
  137. " response code: " . $response_info['http_code'],  
  138. $postData,  
  139. $response); 
  140.  
  141. return $data; 
  142.  
  143. /** 
  144. * Build a JSON POST object 
  145. */ 
  146. protected function sanitizeForSerialization($data) 
  147. if (is_scalar($data) || null === $data) { 
  148. $sanitized = $data; 
  149. } else if ($data instanceof \DateTime) { 
  150. $sanitized = $data->format(\DateTime::ISO8601); 
  151. } else if (is_array($data)) { 
  152. foreach ($data as $property => $value) { 
  153. if ($value === null) { 
  154. unset($data[$property]); 
  155. } else { 
  156. $data[$property] = $this->sanitizeForSerialization($value); 
  157. $sanitized = $data; 
  158. } else if (is_object($data)) { 
  159. $values = array(); 
  160. foreach (array_keys($data::$swaggerTypes) as $property) { 
  161. if ($data->$property !== null) { 
  162. $values[$property] = $this->sanitizeForSerialization($data->$property); 
  163. $sanitized = $values; 
  164. } else { 
  165. $sanitized = (string)$data; 
  166.  
  167. return $sanitized; 
  168.  
  169. /** 
  170. * Take value and turn it into a string suitable for inclusion in 
  171. * the path, by url-encoding. 
  172. * @param string $value a string which will be part of the path 
  173. * @return string the serialized object 
  174. */ 
  175. public static function toPathValue($value) { 
  176. return rawurlencode($value); 
  177.  
  178. /** 
  179. * Take value and turn it into a string suitable for inclusion in 
  180. * the query, by imploding comma-separated if it's an object. 
  181. * If it's a string, pass through unchanged. It will be url-encoded 
  182. * later. 
  183. * @param object $object an object to be serialized to a string 
  184. * @return string the serialized object 
  185. */ 
  186. public static function toQueryValue($object) { 
  187. if (is_array($object)) { 
  188. return implode(', ', $object); 
  189. } else { 
  190. return $object; 
  191.  
  192. /** 
  193. * Just pass through the header value for now. Placeholder in case we 
  194. * find out we need to do something with header values. 
  195. * @param string $value a string which will be part of the header 
  196. * @return string the header string 
  197. */ 
  198. public static function toHeaderValue($value) { 
  199. return $value; 
  200.  
  201. /** 
  202. * Deserialize a JSON string into an object 
  203. * 
  204. * @param object $object object or primitive to be deserialized 
  205. * @param string $class class name is passed as a string 
  206. * @return object an instance of $class 
  207. */ 
  208.  
  209. public static function deserialize($data, $class) 
  210. if ($class == 'number') { 
  211. $class = 'float'; 
  212. if (null === $data) { 
  213. $deserialized = null; 
  214. } else if (substr($class, 0, 6) == 'array[') { 
  215. $subClass = substr($class, 6, -1); 
  216. $values = array(); 
  217. foreach ($data as $value) { 
  218. $values[] = self::deserialize($value, $subClass); 
  219. $deserialized = $values; 
  220. } elseif ($class == 'DateTime') { 
  221. $deserialized = new \DateTime($data); 
  222. } elseif (in_array($class, array('string', 'int', 'float', 'bool'))) { 
  223. settype($data, $class); 
  224. $deserialized = $data; 
  225. } else { 
  226. $instance = new $class(); 
  227. foreach ($instance::$swaggerTypes as $property => $type) { 
  228. if (isset($data->$property)) { 
  229. $instance->$property = self::deserialize($data->$property, $type); 
  230. $deserialized = $instance; 
  231.  
  232. return $deserialized; 
  233.  
  234.  
  235. class TaxamoAPIException extends Exception { 
  236. public $post_data; 
  237. public $response; 
  238.  
  239. public function __construct($message, $post_data, $response, $code = 0, Exception $previous = null) { 
  240. parent::__construct($message, $code, $previous); 
  241. $this->post_data = $post_data; 
  242. $this->response = $response; 
  243.  
  244. class TaxamoAuthenticationException extends TaxamoAPIException { 
  245.  
  246.  
  247. class TaxamoValidationException extends TaxamoAPIException { 
  248. public $errors; 
  249. public $validation_failures; 
  250.  
  251. public function __construct($message, $post_data, $response, $errors=null, $validation_failures=null, $code = 0, Exception $previous = null) { 
  252. parent::__construct($message, $post_data, $response, $code, $previous); 
  253. $this->errors = $errors; 
  254. $this->validation_failures = $validation_failures; 
  255.  
.