PPPStripeApiRequestor

Class ApiRequestor.

Defined (1)

The class is defined in the following location(s).

/includes/api/stripe-php/lib/ApiRequestor.php  
  1. class ApiRequestor 
  2. private $_apiKey; 
  3.  
  4. private $_apiBase; 
  5.  
  6. private static $_httpClient; 
  7.  
  8. public function __construct($apiKey = null, $apiBase = null) 
  9. $this->_apiKey = $apiKey; 
  10. if (!$apiBase) { 
  11. $apiBase = Stripe::$apiBase; 
  12. $this->_apiBase = $apiBase; 
  13.  
  14. private static function _encodeObjects($d) 
  15. if ($d instanceof ApiResource) { 
  16. return Util\Util::utf8($d->id); 
  17. } elseif ($d === true) { 
  18. return 'true'; 
  19. } elseif ($d === false) { 
  20. return 'false'; 
  21. } elseif (is_array($d)) { 
  22. $res = array(); 
  23. foreach ($d as $k => $v) { 
  24. $res[$k] = self::_encodeObjects($v); 
  25. return $res; 
  26. } else { 
  27. return Util\Util::utf8($d); 
  28.  
  29. /** 
  30. * @param string $method 
  31. * @param string $url 
  32. * @param array|null $params 
  33. * @param array|null $headers 
  34. * @return array An array whose first element is an API response and second 
  35. * element is the API key used to make the request. 
  36. */ 
  37. public function request($method, $url, $params = null, $headers = null) 
  38. if (!$params) { 
  39. $params = array(); 
  40. if (!$headers) { 
  41. $headers = array(); 
  42. list($rbody, $rcode, $rheaders, $myApiKey) = 
  43. $this->_requestRaw($method, $url, $params, $headers); 
  44. $json = $this->_interpretResponse($rbody, $rcode, $rheaders); 
  45. $resp = new ApiResponse($rbody, $rcode, $rheaders, $json); 
  46. return array($resp, $myApiKey); 
  47.  
  48. /** 
  49. * @param string $rbody A JSON string. 
  50. * @param int $rcode 
  51. * @param array $rheaders 
  52. * @param array $resp 
  53. * @throws Error\InvalidRequest if the error is caused by the user. 
  54. * @throws Error\Authentication if the error is caused by a lack of 
  55. * permissions. 
  56. * @throws Error\Card if the error is the error code is 402 (payment 
  57. * required) 
  58. * @throws Error\RateLimit if the error is caused by too many requests 
  59. * hitting the API. 
  60. * @throws Error\Api otherwise. 
  61. */ 
  62. public function handleApiError($rbody, $rcode, $rheaders, $resp) 
  63. if (!is_array($resp) || !isset($resp['error'])) { 
  64. $msg = "Invalid response object from API: $rbody " 
  65. . "(HTTP response code was $rcode)"; 
  66. throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders); 
  67.  
  68. $error = $resp['error']; 
  69. $msg = isset($error['message']) ? $error['message'] : null; 
  70. $param = isset($error['param']) ? $error['param'] : null; 
  71. $code = isset($error['code']) ? $error['code'] : null; 
  72.  
  73. switch ($rcode) { 
  74. case 400: 
  75. // 'rate_limit' code is deprecated, but left here for backwards compatibility 
  76. // for API versions earlier than 2015-09-08 
  77. if ($code == 'rate_limit') { 
  78. throw new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders); 
  79.  
  80. // intentional fall-through 
  81. case 404: 
  82. throw new Error\InvalidRequest($msg, $param, $rcode, $rbody, $resp, $rheaders); 
  83. case 401: 
  84. throw new Error\Authentication($msg, $rcode, $rbody, $resp, $rheaders); 
  85. case 402: 
  86. throw new Error\Card($msg, $param, $code, $rcode, $rbody, $resp, $rheaders); 
  87. case 429: 
  88. throw new Error\RateLimit($msg, $param, $rcode, $rbody, $resp, $rheaders); 
  89. default: 
  90. throw new Error\Api($msg, $rcode, $rbody, $resp, $rheaders); 
  91.  
  92. private static function _formatAppInfo($appInfo) 
  93. if ($appInfo !== null) { 
  94. $string = $appInfo['name']; 
  95. if ($appInfo['version'] !== null) { 
  96. $string .= '/' . $appInfo['version']; 
  97. if ($appInfo['url'] !== null) { 
  98. $string .= ' (' . $appInfo['url'] . ')'; 
  99. return $string; 
  100. } else { 
  101. return null; 
  102.  
  103. private static function _defaultHeaders($apiKey) 
  104. $appInfo = Stripe::getAppInfo(); 
  105.  
  106. $uaString = 'Stripe/v1 PhpBindings/' . Stripe::VERSION; 
  107.  
  108. $langVersion = phpversion(); 
  109. $uname = php_uname(); 
  110. $curlVersion = curl_version(); 
  111. $appInfo = Stripe::getAppInfo(); 
  112. $ua = array( 
  113. 'bindings_version' => Stripe::VERSION,  
  114. 'lang' => 'php',  
  115. 'lang_version' => $langVersion,  
  116. 'publisher' => 'stripe',  
  117. 'uname' => $uname,  
  118. 'httplib' => 'curl ' . $curlVersion['version'],  
  119. 'ssllib' => $curlVersion['ssl_version'],  
  120. ); 
  121. if ($appInfo !== null) { 
  122. $uaString .= ' ' . self::_formatAppInfo($appInfo); 
  123. $ua['application'] = $appInfo; 
  124.  
  125. $defaultHeaders = array( 
  126. 'X-Stripe-Client-User-Agent' => json_encode($ua),  
  127. 'User-Agent' => $uaString,  
  128. 'Authorization' => 'Bearer ' . $apiKey,  
  129. ); 
  130. return $defaultHeaders; 
  131.  
  132. private function _requestRaw($method, $url, $params, $headers) 
  133. $myApiKey = $this->_apiKey; 
  134. if (!$myApiKey) { 
  135. $myApiKey = Stripe::$apiKey; 
  136.  
  137. if (!$myApiKey) { 
  138. $msg = 'No API key provided. (HINT: set your API key using ' 
  139. . '"Stripe::setApiKey(<API-KEY>)". You can generate API keys from ' 
  140. . 'the Stripe web interface. See https://stripe.com/api for ' 
  141. . 'details, or email support@stripe.com if you have any questions.'; 
  142. throw new Error\Authentication($msg); 
  143.  
  144. $absUrl = $this->_apiBase.$url; 
  145. $params = self::_encodeObjects($params); 
  146. $defaultHeaders = $this->_defaultHeaders($myApiKey); 
  147. if (Stripe::$apiVersion) { 
  148. $defaultHeaders['Stripe-Version'] = Stripe::$apiVersion; 
  149.  
  150. if (Stripe::$accountId) { 
  151. $defaultHeaders['Stripe-Account'] = Stripe::$accountId; 
  152.  
  153. $hasFile = false; 
  154. $hasCurlFile = class_exists('\CURLFile', false); 
  155. foreach ($params as $k => $v) { 
  156. if (is_resource($v)) { 
  157. $hasFile = true; 
  158. $params[$k] = self::_processResourceParam($v, $hasCurlFile); 
  159. } elseif ($hasCurlFile && $v instanceof \CURLFile) { 
  160. $hasFile = true; 
  161.  
  162. if ($hasFile) { 
  163. $defaultHeaders['Content-Type'] = 'multipart/form-data'; 
  164. } else { 
  165. $defaultHeaders['Content-Type'] = 'application/x-www-form-urlencoded'; 
  166.  
  167. $combinedHeaders = array_merge($defaultHeaders, $headers); 
  168. $rawHeaders = array(); 
  169.  
  170. foreach ($combinedHeaders as $header => $value) { 
  171. $rawHeaders[] = $header . ': ' . $value; 
  172.  
  173. list($rbody, $rcode, $rheaders) = $this->httpClient()->request( 
  174. $method,  
  175. $absUrl,  
  176. $rawHeaders,  
  177. $params,  
  178. $hasFile 
  179. ); 
  180. return array($rbody, $rcode, $rheaders, $myApiKey); 
  181.  
  182. private function _processResourceParam($resource, $hasCurlFile) 
  183. if (get_resource_type($resource) !== 'stream') { 
  184. throw new Error\Api( 
  185. 'Attempted to upload a resource that is not a stream' 
  186. ); 
  187.  
  188. $metaData = stream_get_meta_data($resource); 
  189. if ($metaData['wrapper_type'] !== 'plainfile') { 
  190. throw new Error\Api( 
  191. 'Only plainfile resource streams are supported' 
  192. ); 
  193.  
  194. if ($hasCurlFile) { 
  195. // We don't have the filename or mimetype, but the API doesn't care 
  196. return new \CURLFile($metaData['uri']); 
  197. } else { 
  198. return '@'.$metaData['uri']; 
  199.  
  200. private function _interpretResponse($rbody, $rcode, $rheaders) 
  201. try { 
  202. $resp = json_decode($rbody, true); 
  203. } catch (Exception $e) { 
  204. $msg = "Invalid response body from API: $rbody " 
  205. . "(HTTP response code was $rcode)"; 
  206. throw new Error\Api($msg, $rcode, $rbody); 
  207.  
  208. if ($rcode < 200 || $rcode >= 300) { 
  209. $this->handleApiError($rbody, $rcode, $rheaders, $resp); 
  210. return $resp; 
  211.  
  212. public static function setHttpClient($client) 
  213. self::$_httpClient = $client; 
  214.  
  215. private function httpClient() 
  216. if (!self::$_httpClient) { 
  217. self::$_httpClient = HttpClient\CurlClient::instance(); //TODO do I need full namespace? 
  218. return self::$_httpClient;