ApiResource.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. <?php
  2. namespace Stripe;
  3. /**
  4. * Class ApiResource
  5. *
  6. * @package Stripe
  7. */
  8. abstract class ApiResource extends StripeObject
  9. {
  10. private static $HEADERS_TO_PERSIST = array('Stripe-Account' => true, 'Stripe-Version' => true);
  11. public static function baseUrl()
  12. {
  13. return Stripe::$apiBase;
  14. }
  15. /**
  16. * @return ApiResource The refreshed resource.
  17. */
  18. public function refresh()
  19. {
  20. $requestor = new ApiRequestor($this->_opts->apiKey, static::baseUrl());
  21. $url = $this->instanceUrl();
  22. list($response, $this->_opts->apiKey) = $requestor->request(
  23. 'get',
  24. $url,
  25. $this->_retrieveOptions,
  26. $this->_opts->headers
  27. );
  28. $this->setLastResponse($response);
  29. $this->refreshFrom($response->json, $this->_opts);
  30. return $this;
  31. }
  32. /**
  33. * @return string The name of the class, with namespacing and underscores
  34. * stripped.
  35. */
  36. public static function className()
  37. {
  38. $class = get_called_class();
  39. // Useful for namespaces: Foo\Charge
  40. if ($postfixNamespaces = strrchr($class, '\\')) {
  41. $class = substr($postfixNamespaces, 1);
  42. }
  43. // Useful for underscored 'namespaces': Foo_Charge
  44. if ($postfixFakeNamespaces = strrchr($class, '')) {
  45. $class = $postfixFakeNamespaces;
  46. }
  47. if (substr($class, 0, strlen('Stripe')) == 'Stripe') {
  48. $class = substr($class, strlen('Stripe'));
  49. }
  50. $class = str_replace('_', '', $class);
  51. $name = urlencode($class);
  52. $name = strtolower($name);
  53. return $name;
  54. }
  55. /**
  56. * @return string The endpoint URL for the given class.
  57. */
  58. public static function classUrl()
  59. {
  60. $base = static::className();
  61. return "/v1/${base}s";
  62. }
  63. /**
  64. * @return string The instance endpoint URL for the given class.
  65. */
  66. public static function resourceUrl($id)
  67. {
  68. if ($id === null) {
  69. $class = get_called_class();
  70. $message = "Could not determine which URL to request: "
  71. . "$class instance has invalid ID: $id";
  72. throw new Error\InvalidRequest($message, null);
  73. }
  74. $id = Util\Util::utf8($id);
  75. $base = static::classUrl();
  76. $extn = urlencode($id);
  77. return "$base/$extn";
  78. }
  79. /**
  80. * @return string The full API URL for this API resource.
  81. */
  82. public function instanceUrl()
  83. {
  84. return static::resourceUrl($this['id']);
  85. }
  86. private static function _validateParams($params = null)
  87. {
  88. if ($params && !is_array($params)) {
  89. $message = "You must pass an array as the first argument to Stripe API "
  90. . "method calls. (HINT: an example call to create a charge "
  91. . "would be: \"Stripe\\Charge::create(array('amount' => 100, "
  92. . "'currency' => 'usd', 'card' => array('number' => "
  93. . "4242424242424242, 'exp_month' => 5, 'exp_year' => 2015)))\")";
  94. throw new Error\Api($message);
  95. }
  96. }
  97. protected function _request($method, $url, $params = array(), $options = null)
  98. {
  99. $opts = $this->_opts->merge($options);
  100. list($resp, $options) = static::_staticRequest($method, $url, $params, $opts);
  101. $this->setLastResponse($resp);
  102. return array($resp->json, $options);
  103. }
  104. protected static function _staticRequest($method, $url, $params, $options)
  105. {
  106. $opts = Util\RequestOptions::parse($options);
  107. $requestor = new ApiRequestor($opts->apiKey, static::baseUrl());
  108. list($response, $opts->apiKey) = $requestor->request($method, $url, $params, $opts->headers);
  109. foreach ($opts->headers as $k => $v) {
  110. if (!array_key_exists($k, self::$HEADERS_TO_PERSIST)) {
  111. unset($opts->headers[$k]);
  112. }
  113. }
  114. return array($response, $opts);
  115. }
  116. protected static function _retrieve($id, $options = null)
  117. {
  118. $opts = Util\RequestOptions::parse($options);
  119. $instance = new static($id, $opts);
  120. $instance->refresh();
  121. return $instance;
  122. }
  123. protected static function _all($params = null, $options = null)
  124. {
  125. self::_validateParams($params);
  126. $url = static::classUrl();
  127. list($response, $opts) = static::_staticRequest('get', $url, $params, $options);
  128. $obj = Util\Util::convertToStripeObject($response->json, $opts);
  129. if (!is_a($obj, 'Stripe\\Collection')) {
  130. $class = get_class($obj);
  131. $message = "Expected type \"Stripe\\Collection\", got \"$class\" instead";
  132. throw new Error\Api($message);
  133. }
  134. $obj->setLastResponse($response);
  135. $obj->setRequestParams($params);
  136. return $obj;
  137. }
  138. protected static function _create($params = null, $options = null)
  139. {
  140. self::_validateParams($params);
  141. $url = static::classUrl();
  142. list($response, $opts) = static::_staticRequest('post', $url, $params, $options);
  143. $obj = Util\Util::convertToStripeObject($response->json, $opts);
  144. $obj->setLastResponse($response);
  145. return $obj;
  146. }
  147. /**
  148. * @param string $id The ID of the API resource to update.
  149. * @param array|null $params
  150. * @param array|string|null $opts
  151. *
  152. * @return ApiResource the updated API resource
  153. */
  154. protected static function _update($id, $params = null, $options = null)
  155. {
  156. self::_validateParams($params);
  157. $url = static::resourceUrl($id);
  158. list($response, $opts) = static::_staticRequest('post', $url, $params, $options);
  159. $obj = Util\Util::convertToStripeObject($response->json, $opts);
  160. $obj->setLastResponse($response);
  161. return $obj;
  162. }
  163. protected function _save($options = null)
  164. {
  165. $params = $this->serializeParameters();
  166. if (count($params) > 0) {
  167. $url = $this->instanceUrl();
  168. list($response, $opts) = $this->_request('post', $url, $params, $options);
  169. $this->refreshFrom($response, $opts);
  170. }
  171. return $this;
  172. }
  173. protected function _delete($params = null, $options = null)
  174. {
  175. self::_validateParams($params);
  176. $url = $this->instanceUrl();
  177. list($response, $opts) = $this->_request('delete', $url, $params, $options);
  178. $this->refreshFrom($response, $opts);
  179. return $this;
  180. }
  181. }