ApiResource.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace Stripe;
  3. /**
  4. * Class ApiResource.
  5. */
  6. abstract class ApiResource extends StripeObject
  7. {
  8. use ApiOperations\Request;
  9. /**
  10. * @return \Stripe\Util\Set A list of fields that can be their own type of
  11. * API resource (say a nested card under an account for example), and if
  12. * that resource is set, it should be transmitted to the API on a create or
  13. * update. Doing so is not the default behavior because API resources
  14. * should normally be persisted on their own RESTful endpoints.
  15. */
  16. public static function getSavedNestedResources()
  17. {
  18. static $savedNestedResources = null;
  19. if (null === $savedNestedResources) {
  20. $savedNestedResources = new Util\Set();
  21. }
  22. return $savedNestedResources;
  23. }
  24. /**
  25. * @var bool A flag that can be set a behavior that will cause this
  26. * resource to be encoded and sent up along with an update of its parent
  27. * resource. This is usually not desirable because resources are updated
  28. * individually on their own endpoints, but there are certain cases,
  29. * replacing a customer's source for example, where this is allowed.
  30. */
  31. public $saveWithParent = false;
  32. public function __set($k, $v)
  33. {
  34. parent::__set($k, $v);
  35. $v = $this->{$k};
  36. if ((static::getSavedNestedResources()->includes($k))
  37. && ($v instanceof ApiResource)) {
  38. $v->saveWithParent = true;
  39. }
  40. }
  41. /**
  42. * @throws Exception\ApiErrorException
  43. *
  44. * @return ApiResource the refreshed resource
  45. */
  46. public function refresh()
  47. {
  48. $requestor = new ApiRequestor($this->_opts->apiKey, static::baseUrl());
  49. $url = $this->instanceUrl();
  50. list($response, $this->_opts->apiKey) = $requestor->request(
  51. 'get',
  52. $url,
  53. $this->_retrieveOptions,
  54. $this->_opts->headers
  55. );
  56. $this->setLastResponse($response);
  57. $this->refreshFrom($response->json, $this->_opts);
  58. return $this;
  59. }
  60. /**
  61. * @return string the base URL for the given class
  62. */
  63. public static function baseUrl()
  64. {
  65. return Stripe::$apiBase;
  66. }
  67. /**
  68. * @return string the endpoint URL for the given class
  69. */
  70. public static function classUrl()
  71. {
  72. // Replace dots with slashes for namespaced resources, e.g. if the object's name is
  73. // "foo.bar", then its URL will be "/v1/foo/bars".
  74. $base = \str_replace('.', '/', static::OBJECT_NAME);
  75. return "/v1/{$base}s";
  76. }
  77. /**
  78. * @param null|string $id the ID of the resource
  79. *
  80. * @throws Exception\UnexpectedValueException if $id is null
  81. *
  82. * @return string the instance endpoint URL for the given class
  83. */
  84. public static function resourceUrl($id)
  85. {
  86. if (null === $id) {
  87. $class = static::class;
  88. $message = 'Could not determine which URL to request: '
  89. . "{$class} instance has invalid ID: {$id}";
  90. throw new Exception\UnexpectedValueException($message);
  91. }
  92. $id = Util\Util::utf8($id);
  93. $base = static::classUrl();
  94. $extn = \urlencode($id);
  95. return "{$base}/{$extn}";
  96. }
  97. /**
  98. * @return string the full API URL for this API resource
  99. */
  100. public function instanceUrl()
  101. {
  102. return static::resourceUrl($this['id']);
  103. }
  104. }