/api/vendor/stripe/stripe-php/lib/Stripe/Object.php

https://gitlab.com/x33n/respond · PHP · 265 lines · 229 code · 20 blank · 16 comment · 29 complexity · b3a2392a686a16bfb43de5d7b48cb514 MD5 · raw file

  1. <?php
  2. class Stripe_Object implements ArrayAccess
  3. {
  4. /**
  5. * @var Stripe_Util_Set Attributes that should not be sent to the API because
  6. * they're not updatable (e.g. API key, ID).
  7. */
  8. public static $permanentAttributes;
  9. /**
  10. * @var Stripe_Util_Set Attributes that are nested but still updatable from
  11. * the parent class's URL (e.g. metadata).
  12. */
  13. public static $nestedUpdatableAttributes;
  14. public static function init()
  15. {
  16. self::$permanentAttributes = new Stripe_Util_Set(array('_apiKey', 'id'));
  17. self::$nestedUpdatableAttributes = new Stripe_Util_Set(array('metadata'));
  18. }
  19. protected $_apiKey;
  20. protected $_values;
  21. protected $_unsavedValues;
  22. protected $_transientValues;
  23. protected $_retrieveOptions;
  24. public function __construct($id=null, $apiKey=null)
  25. {
  26. $this->_apiKey = $apiKey;
  27. $this->_values = array();
  28. $this->_unsavedValues = new Stripe_Util_Set();
  29. $this->_transientValues = new Stripe_Util_Set();
  30. $this->_retrieveOptions = array();
  31. if (is_array($id)) {
  32. foreach ($id as $key => $value) {
  33. if ($key != 'id') {
  34. $this->_retrieveOptions[$key] = $value;
  35. }
  36. }
  37. $id = $id['id'];
  38. }
  39. if ($id !== null) {
  40. $this->id = $id;
  41. }
  42. }
  43. // Standard accessor magic methods
  44. public function __set($k, $v)
  45. {
  46. if ($v === "") {
  47. throw new InvalidArgumentException(
  48. 'You cannot set \''.$k.'\'to an empty string. '
  49. .'We interpret empty strings as NULL in requests. '
  50. .'You may set obj->'.$k.' = NULL to delete the property'
  51. );
  52. }
  53. if (self::$nestedUpdatableAttributes->includes($k)
  54. && isset($this->$k) && is_array($v)) {
  55. $this->$k->replaceWith($v);
  56. } else {
  57. // TODO: may want to clear from $_transientValues (Won't be user-visible).
  58. $this->_values[$k] = $v;
  59. }
  60. if (!self::$permanentAttributes->includes($k))
  61. $this->_unsavedValues->add($k);
  62. }
  63. public function __isset($k)
  64. {
  65. return isset($this->_values[$k]);
  66. }
  67. public function __unset($k)
  68. {
  69. unset($this->_values[$k]);
  70. $this->_transientValues->add($k);
  71. $this->_unsavedValues->discard($k);
  72. }
  73. public function __get($k)
  74. {
  75. if (array_key_exists($k, $this->_values)) {
  76. return $this->_values[$k];
  77. } else if ($this->_transientValues->includes($k)) {
  78. $class = get_class($this);
  79. $attrs = join(', ', array_keys($this->_values));
  80. $message = "Stripe Notice: Undefined property of $class instance: $k. "
  81. . "HINT: The $k attribute was set in the past, however. "
  82. . "It was then wiped when refreshing the object "
  83. . "with the result returned by Stripe's API, "
  84. . "probably as a result of a save(). The attributes currently "
  85. . "available on this object are: $attrs";
  86. error_log($message);
  87. return null;
  88. } else {
  89. $class = get_class($this);
  90. error_log("Stripe Notice: Undefined property of $class instance: $k");
  91. return null;
  92. }
  93. }
  94. // ArrayAccess methods
  95. public function offsetSet($k, $v)
  96. {
  97. $this->$k = $v;
  98. }
  99. public function offsetExists($k)
  100. {
  101. return array_key_exists($k, $this->_values);
  102. }
  103. public function offsetUnset($k)
  104. {
  105. unset($this->$k);
  106. }
  107. public function offsetGet($k)
  108. {
  109. return array_key_exists($k, $this->_values) ? $this->_values[$k] : null;
  110. }
  111. public function keys()
  112. {
  113. return array_keys($this->_values);
  114. }
  115. /**
  116. * This unfortunately needs to be public to be used in Util.php
  117. *
  118. * @param string $class
  119. * @param array $values
  120. * @param string|null $apiKey
  121. *
  122. * @return Stripe_Object The object constructed from the given values.
  123. */
  124. public static function scopedConstructFrom($class, $values, $apiKey=null)
  125. {
  126. $obj = new $class(isset($values['id']) ? $values['id'] : null, $apiKey);
  127. $obj->refreshFrom($values, $apiKey);
  128. return $obj;
  129. }
  130. /**
  131. * @param array $values
  132. * @param string|null $apiKey
  133. *
  134. * @return Stripe_Object The object of the same class as $this constructed
  135. * from the given values.
  136. */
  137. public static function constructFrom($values, $apiKey=null)
  138. {
  139. return self::scopedConstructFrom(__CLASS__, $values, $apiKey);
  140. }
  141. /**
  142. * Refreshes this object using the provided values.
  143. *
  144. * @param array $values
  145. * @param string $apiKey
  146. * @param boolean $partial Defaults to false.
  147. */
  148. public function refreshFrom($values, $apiKey, $partial=false)
  149. {
  150. $this->_apiKey = $apiKey;
  151. // Wipe old state before setting new. This is useful for e.g. updating a
  152. // customer, where there is no persistent card parameter. Mark those values
  153. // which don't persist as transient
  154. if ($partial) {
  155. $removed = new Stripe_Util_Set();
  156. } else {
  157. $removed = array_diff(array_keys($this->_values), array_keys($values));
  158. }
  159. foreach ($removed as $k) {
  160. if (self::$permanentAttributes->includes($k))
  161. continue;
  162. unset($this->$k);
  163. }
  164. foreach ($values as $k => $v) {
  165. if (self::$permanentAttributes->includes($k) && isset($this[$k]))
  166. continue;
  167. if (self::$nestedUpdatableAttributes->includes($k) && is_array($v)) {
  168. $this->_values[$k] = Stripe_Object::scopedConstructFrom(
  169. 'Stripe_AttachedObject', $v, $apiKey
  170. );
  171. } else {
  172. $this->_values[$k] = Stripe_Util::convertToStripeObject($v, $apiKey);
  173. }
  174. $this->_transientValues->discard($k);
  175. $this->_unsavedValues->discard($k);
  176. }
  177. }
  178. /**
  179. * @return array A recursive mapping of attributes to values for this object,
  180. * including the proper value for deleted attributes.
  181. */
  182. public function serializeParameters()
  183. {
  184. $params = array();
  185. if ($this->_unsavedValues) {
  186. foreach ($this->_unsavedValues->toArray() as $k) {
  187. $v = $this->$k;
  188. if ($v === NULL) {
  189. $v = '';
  190. }
  191. $params[$k] = $v;
  192. }
  193. }
  194. // Get nested updates.
  195. foreach (self::$nestedUpdatableAttributes->toArray() as $property) {
  196. if (isset($this->$property)
  197. && $this->$property instanceOf Stripe_Object) {
  198. $params[$property] = $this->$property->serializeParameters();
  199. }
  200. }
  201. return $params;
  202. }
  203. // Pretend to have late static bindings, even in PHP 5.2
  204. protected function _lsb($method)
  205. {
  206. $class = get_class($this);
  207. $args = array_slice(func_get_args(), 1);
  208. return call_user_func_array(array($class, $method), $args);
  209. }
  210. protected static function _scopedLsb($class, $method)
  211. {
  212. $args = array_slice(func_get_args(), 2);
  213. return call_user_func_array(array($class, $method), $args);
  214. }
  215. public function __toJSON()
  216. {
  217. if (defined('JSON_PRETTY_PRINT')) {
  218. return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
  219. } else {
  220. return json_encode($this->__toArray(true));
  221. }
  222. }
  223. public function __toString()
  224. {
  225. $class = get_class($this);
  226. return $class . ' JSON: ' . $this->__toJSON();
  227. }
  228. public function __toArray($recursive=false)
  229. {
  230. if ($recursive) {
  231. return Stripe_Util::convertStripeObjectToArray($this->_values);
  232. } else {
  233. return $this->_values;
  234. }
  235. }
  236. }
  237. Stripe_Object::init();