Changeset View
Changeset View
Standalone View
Standalone View
externals/stripe-php/lib/Stripe/Object.php
| <?php | <?php | ||||
| class Stripe_Object implements ArrayAccess | class Stripe_Object implements ArrayAccess | ||||
| { | { | ||||
| public static $_permanentAttributes; | /** | ||||
| * @var Stripe_Util_Set Attributes that should not be sent to the API because | |||||
| * they're not updatable (e.g. API key, ID). | |||||
| */ | |||||
| public static $permanentAttributes; | |||||
| /** | |||||
| * @var Stripe_Util_Set Attributes that are nested but still updatable from | |||||
| * the parent class's URL (e.g. metadata). | |||||
| */ | |||||
| public static $nestedUpdatableAttributes; | |||||
| public static function init() | public static function init() | ||||
| { | { | ||||
| self::$_permanentAttributes = new Stripe_Util_Set(array('_apiKey')); | self::$permanentAttributes = new Stripe_Util_Set(array('_apiKey', 'id')); | ||||
| self::$nestedUpdatableAttributes = new Stripe_Util_Set(array('metadata')); | |||||
| } | } | ||||
| protected $_apiKey; | protected $_apiKey; | ||||
| protected $_values; | protected $_values; | ||||
| protected $_unsavedValues; | protected $_unsavedValues; | ||||
| protected $_transientValues; | protected $_transientValues; | ||||
| protected $_retrieveOptions; | |||||
| public function __construct($id=null, $apiKey=null) | public function __construct($id=null, $apiKey=null) | ||||
| { | { | ||||
| $this->_apiKey = $apiKey; | $this->_apiKey = $apiKey; | ||||
| $this->_values = array(); | $this->_values = array(); | ||||
| $this->_unsavedValues = new Stripe_Util_Set(); | $this->_unsavedValues = new Stripe_Util_Set(); | ||||
| $this->_transientValues = new Stripe_Util_Set(); | $this->_transientValues = new Stripe_Util_Set(); | ||||
| if ($id) | |||||
| $this->_retrieveOptions = array(); | |||||
| if (is_array($id)) { | |||||
| foreach ($id as $key => $value) { | |||||
| if ($key != 'id') { | |||||
| $this->_retrieveOptions[$key] = $value; | |||||
| } | |||||
| } | |||||
| $id = $id['id']; | |||||
| } | |||||
| if ($id !== null) { | |||||
| $this->id = $id; | $this->id = $id; | ||||
| } | } | ||||
| } | |||||
| // Standard accessor magic methods | // Standard accessor magic methods | ||||
| public function __set($k, $v) | public function __set($k, $v) | ||||
| { | { | ||||
| // TODO: may want to clear from $_transientValues. (Won't be user-visible.) | if ($v === "") { | ||||
| throw new InvalidArgumentException( | |||||
| 'You cannot set \''.$k.'\'to an empty string. ' | |||||
| .'We interpret empty strings as NULL in requests. ' | |||||
| .'You may set obj->'.$k.' = NULL to delete the property' | |||||
| ); | |||||
| } | |||||
| if (self::$nestedUpdatableAttributes->includes($k) | |||||
| && isset($this->$k) && is_array($v)) { | |||||
| $this->$k->replaceWith($v); | |||||
| } else { | |||||
| // TODO: may want to clear from $_transientValues (Won't be user-visible). | |||||
| $this->_values[$k] = $v; | $this->_values[$k] = $v; | ||||
| if (!self::$_permanentAttributes->includes($k)) | } | ||||
| if (!self::$permanentAttributes->includes($k)) | |||||
| $this->_unsavedValues->add($k); | $this->_unsavedValues->add($k); | ||||
| } | } | ||||
| public function __isset($k) | public function __isset($k) | ||||
| { | { | ||||
| return isset($this->_values[$k]); | return isset($this->_values[$k]); | ||||
| } | } | ||||
| public function __unset($k) | public function __unset($k) | ||||
| { | { | ||||
| unset($this->_values[$k]); | unset($this->_values[$k]); | ||||
| $this->_transientValues->add($k); | $this->_transientValues->add($k); | ||||
| $this->_unsavedValues->discard($k); | $this->_unsavedValues->discard($k); | ||||
| } | } | ||||
| public function __get($k) | public function __get($k) | ||||
| { | { | ||||
| if (isset($this->_values[$k])) { | if (array_key_exists($k, $this->_values)) { | ||||
| return $this->_values[$k]; | return $this->_values[$k]; | ||||
| } else if ($this->_transientValues->includes($k)) { | } else if ($this->_transientValues->includes($k)) { | ||||
| $class = get_class($this); | $class = get_class($this); | ||||
| $attrs = join(', ', array_keys($this->_values)); | $attrs = join(', ', array_keys($this->_values)); | ||||
| error_log("Stripe Notice: Undefined property of $class instance: $k. HINT: The $k attribute was set in the past, however. It was then wiped when refreshing the object with the result returned by Stripe's API, probably as a result of a save(). The attributes currently available on this object are: $attrs"); | $message = "Stripe Notice: Undefined property of $class instance: $k. " | ||||
| . "HINT: The $k attribute was set in the past, however. " | |||||
| . "It was then wiped when refreshing the object " | |||||
| . "with the result returned by Stripe's API, " | |||||
| . "probably as a result of a save(). The attributes currently " | |||||
| . "available on this object are: $attrs"; | |||||
| error_log($message); | |||||
| return null; | return null; | ||||
| } else { | } else { | ||||
| $class = get_class($this); | $class = get_class($this); | ||||
| error_log("Stripe Notice: Undefined property of $class instance: $k"); | error_log("Stripe Notice: Undefined property of $class instance: $k"); | ||||
| return null; | return null; | ||||
| } | } | ||||
| } | } | ||||
| // ArrayAccess methods | // ArrayAccess methods | ||||
| public function offsetSet($k, $v) | public function offsetSet($k, $v) | ||||
| { | { | ||||
| $this->$k = $v; | $this->$k = $v; | ||||
| } | } | ||||
| public function offsetExists($k) | public function offsetExists($k) | ||||
| { | { | ||||
| return isset($this->$k); | return array_key_exists($k, $this->_values); | ||||
| } | } | ||||
| public function offsetUnset($k) | public function offsetUnset($k) | ||||
| { | { | ||||
| unset($this->$k); | unset($this->$k); | ||||
| } | } | ||||
| public function offsetGet($k) | public function offsetGet($k) | ||||
| { | { | ||||
| return isset($this->_values[$k]) ? $this->_values[$k] : null; | return array_key_exists($k, $this->_values) ? $this->_values[$k] : null; | ||||
| } | } | ||||
| // This unfortunately needs to be public to be used in Util.php | public function keys() | ||||
| { | |||||
| return array_keys($this->_values); | |||||
| } | |||||
| /** | |||||
| * This unfortunately needs to be public to be used in Util.php | |||||
| * | |||||
| * @param string $class | |||||
| * @param array $values | |||||
| * @param string|null $apiKey | |||||
| * | |||||
| * @return Stripe_Object The object constructed from the given values. | |||||
| */ | |||||
| public static function scopedConstructFrom($class, $values, $apiKey=null) | public static function scopedConstructFrom($class, $values, $apiKey=null) | ||||
| { | { | ||||
| $obj = new $class(isset($values['id']) ? $values['id'] : null, $apiKey); | $obj = new $class(isset($values['id']) ? $values['id'] : null, $apiKey); | ||||
| $obj->refreshFrom($values, $apiKey); | $obj->refreshFrom($values, $apiKey); | ||||
| return $obj; | return $obj; | ||||
| } | } | ||||
| /** | |||||
| * @param array $values | |||||
| * @param string|null $apiKey | |||||
| * | |||||
| * @return Stripe_Object The object of the same class as $this constructed | |||||
| * from the given values. | |||||
| */ | |||||
| public static function constructFrom($values, $apiKey=null) | public static function constructFrom($values, $apiKey=null) | ||||
| { | { | ||||
| $class = get_class(); | return self::scopedConstructFrom(__CLASS__, $values, $apiKey); | ||||
| return self::scopedConstructFrom($class, $values, $apiKey); | |||||
| } | } | ||||
| /** | |||||
| * Refreshes this object using the provided values. | |||||
| * | |||||
| * @param array $values | |||||
| * @param string $apiKey | |||||
| * @param boolean $partial Defaults to false. | |||||
| */ | |||||
| public function refreshFrom($values, $apiKey, $partial=false) | public function refreshFrom($values, $apiKey, $partial=false) | ||||
| { | { | ||||
| $this->_apiKey = $apiKey; | $this->_apiKey = $apiKey; | ||||
| // Wipe old state before setting new. This is useful for e.g. updating a | // Wipe old state before setting new. This is useful for e.g. updating a | ||||
| // customer, where there is no persistent card parameter. Mark those values | // customer, where there is no persistent card parameter. Mark those values | ||||
| // which don't persist as transient | // which don't persist as transient | ||||
| if ($partial) | if ($partial) { | ||||
| $removed = new Stripe_Util_Set(); | $removed = new Stripe_Util_Set(); | ||||
| else | } else { | ||||
| $removed = array_diff(array_keys($this->_values), array_keys($values)); | $removed = array_diff(array_keys($this->_values), array_keys($values)); | ||||
| } | |||||
| foreach ($removed as $k) { | foreach ($removed as $k) { | ||||
| if (self::$_permanentAttributes->includes($k)) | if (self::$permanentAttributes->includes($k)) | ||||
| continue; | continue; | ||||
| unset($this->$k); | unset($this->$k); | ||||
| } | } | ||||
| foreach ($values as $k => $v) { | foreach ($values as $k => $v) { | ||||
| if (self::$_permanentAttributes->includes($k)) | if (self::$permanentAttributes->includes($k) && isset($this[$k])) | ||||
| continue; | continue; | ||||
| if (self::$nestedUpdatableAttributes->includes($k) && is_array($v)) { | |||||
| $this->_values[$k] = Stripe_Object::scopedConstructFrom( | |||||
| 'Stripe_AttachedObject', $v, $apiKey | |||||
| ); | |||||
| } else { | |||||
| $this->_values[$k] = Stripe_Util::convertToStripeObject($v, $apiKey); | $this->_values[$k] = Stripe_Util::convertToStripeObject($v, $apiKey); | ||||
| } | |||||
| $this->_transientValues->discard($k); | $this->_transientValues->discard($k); | ||||
| $this->_unsavedValues->discard($k); | $this->_unsavedValues->discard($k); | ||||
| } | } | ||||
| } | } | ||||
| /** | |||||
| * @return array A recursive mapping of attributes to values for this object, | |||||
| * including the proper value for deleted attributes. | |||||
| */ | |||||
| public function serializeParameters() | |||||
| { | |||||
| $params = array(); | |||||
| if ($this->_unsavedValues) { | |||||
| foreach ($this->_unsavedValues->toArray() as $k) { | |||||
| $v = $this->$k; | |||||
| if ($v === NULL) { | |||||
| $v = ''; | |||||
| } | |||||
| $params[$k] = $v; | |||||
| } | |||||
| } | |||||
| // Get nested updates. | |||||
| foreach (self::$nestedUpdatableAttributes->toArray() as $property) { | |||||
| if (isset($this->$property) | |||||
| && $this->$property instanceOf Stripe_Object) { | |||||
| $params[$property] = $this->$property->serializeParameters(); | |||||
| } | |||||
| } | |||||
| return $params; | |||||
| } | |||||
| // Pretend to have late static bindings, even in PHP 5.2 | |||||
| protected function _lsb($method) | |||||
| { | |||||
| $class = get_class($this); | |||||
| $args = array_slice(func_get_args(), 1); | |||||
| return call_user_func_array(array($class, $method), $args); | |||||
| } | |||||
| protected static function _scopedLsb($class, $method) | |||||
| { | |||||
| $args = array_slice(func_get_args(), 2); | |||||
| return call_user_func_array(array($class, $method), $args); | |||||
| } | |||||
| public function __toJSON() | public function __toJSON() | ||||
| { | { | ||||
| if (defined('JSON_PRETTY_PRINT')) | if (defined('JSON_PRETTY_PRINT')) { | ||||
| return json_encode($this->__toArray(true), JSON_PRETTY_PRINT); | return json_encode($this->__toArray(true), JSON_PRETTY_PRINT); | ||||
| else | } else { | ||||
| return json_encode($this->__toArray(true)); | return json_encode($this->__toArray(true)); | ||||
| } | } | ||||
| } | |||||
| public function __toString() | public function __toString() | ||||
| { | { | ||||
| return $this->__toJSON(); | return $this->__toJSON(); | ||||
| } | } | ||||
| public function __toArray($recursive=false) | public function __toArray($recursive=false) | ||||
| { | { | ||||
| if ($recursive) | if ($recursive) { | ||||
| return Stripe_Util::convertStripeObjectToArray($this->_values); | return Stripe_Util::convertStripeObjectToArray($this->_values); | ||||
| else | } else { | ||||
| return $this->_values; | return $this->_values; | ||||
| } | } | ||||
| } | } | ||||
| } | |||||
| Stripe_Object::init(); | Stripe_Object::init(); | ||||