ApiResource.php 3.4 KB

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