mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-29 00:40:57 +01:00
cc586b0afa
Summary: various stripe stuff, including - external stripe library - payment form - test controller to play with payment form, sample business logic My main questions / discussion topics are... - is the stripe PHP library too big? (ie should I write something more simple just for phabricator?) -- if its cool, what is the best way to include the client? (ie should I make it a submodule rather than the flat copy here?) - is the JS I wrote (too) ridiculous? -- particularly unhappy with the error message stuff being in JS *but* it seemed the best choice given the most juicy error messages come from the stripe JS such that the overall code complexity is lowest this way. - how should the stripe JS be included? -- flat copy like I did here? -- some sort of external? -- can we just load it off stripe servers at request time? (I like that from the "if stripe is down, stripe is down" perspective) - wasn't sure if the date control was too silly and should just be baked into the form? -- for some reason I feel like its good to be prepared to walk away from Stripe / switch providers here, though I think this is on the wrong side of pragmatic Test Plan: - played around with sample client form Reviewers: epriestley Reviewed By: epriestley CC: aran Differential Revision: https://secure.phabricator.com/D2096
142 lines
3.8 KiB
PHP
142 lines
3.8 KiB
PHP
<?php
|
|
|
|
class Stripe_Object implements ArrayAccess
|
|
{
|
|
public static $_permanentAttributes;
|
|
|
|
public static function init()
|
|
{
|
|
self::$_permanentAttributes = new Stripe_Util_Set(array('_apiKey'));
|
|
}
|
|
|
|
protected $_apiKey;
|
|
protected $_values;
|
|
protected $_unsavedValues;
|
|
protected $_transientValues;
|
|
|
|
public function __construct($id=null, $apiKey=null)
|
|
{
|
|
$this->_apiKey = $apiKey;
|
|
$this->_values = array();
|
|
$this->_unsavedValues = new Stripe_Util_Set();
|
|
$this->_transientValues = new Stripe_Util_Set();
|
|
if ($id)
|
|
$this->id = $id;
|
|
}
|
|
|
|
// Standard accessor magic methods
|
|
public function __set($k, $v)
|
|
{
|
|
// TODO: may want to clear from $_transientValues. (Won't be user-visible.)
|
|
$this->_values[$k] = $v;
|
|
if (!self::$_permanentAttributes->includes($k))
|
|
$this->_unsavedValues->add($k);
|
|
}
|
|
public function __isset($k)
|
|
{
|
|
return isset($this->_values[$k]);
|
|
}
|
|
public function __unset($k)
|
|
{
|
|
unset($this->_values[$k]);
|
|
$this->_transientValues->add($k);
|
|
$this->_unsavedValues->discard($k);
|
|
}
|
|
public function __get($k)
|
|
{
|
|
if (isset($this->_values[$k])) {
|
|
return $this->_values[$k];
|
|
} else if ($this->_transientValues->includes($k)) {
|
|
$class = get_class($this);
|
|
$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");
|
|
return null;
|
|
} else {
|
|
$class = get_class($this);
|
|
error_log("Stripe Notice: Undefined property of $class instance: $k");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// ArrayAccess methods
|
|
public function offsetSet($k, $v)
|
|
{
|
|
$this->$k = $v;
|
|
}
|
|
public function offsetExists($k)
|
|
{
|
|
return isset($this->$k);
|
|
}
|
|
public function offsetUnset($k)
|
|
{
|
|
unset($this->$k);
|
|
}
|
|
public function offsetGet($k)
|
|
{
|
|
return isset($this->_values[$k]) ? $this->_values[$k] : null;
|
|
}
|
|
|
|
// This unfortunately needs to be public to be used in Util.php
|
|
public static function scopedConstructFrom($class, $values, $apiKey=null)
|
|
{
|
|
$obj = new $class(isset($values['id']) ? $values['id'] : null, $apiKey);
|
|
$obj->refreshFrom($values, $apiKey);
|
|
return $obj;
|
|
}
|
|
|
|
public static function constructFrom($values, $apiKey=null)
|
|
{
|
|
$class = get_class();
|
|
return self::scopedConstructFrom($class, $values, $apiKey);
|
|
}
|
|
|
|
public function refreshFrom($values, $apiKey, $partial=false)
|
|
{
|
|
$this->_apiKey = $apiKey;
|
|
// 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
|
|
// which don't persist as transient
|
|
if ($partial)
|
|
$removed = new Stripe_Util_Set();
|
|
else
|
|
$removed = array_diff(array_keys($this->_values), array_keys($values));
|
|
|
|
foreach ($removed as $k) {
|
|
if (self::$_permanentAttributes->includes($k))
|
|
continue;
|
|
unset($this->$k);
|
|
}
|
|
|
|
foreach ($values as $k => $v) {
|
|
if (self::$_permanentAttributes->includes($k))
|
|
continue;
|
|
$this->_values[$k] = Stripe_Util::convertToStripeObject($v, $apiKey);
|
|
$this->_transientValues->discard($k);
|
|
$this->_unsavedValues->discard($k);
|
|
}
|
|
}
|
|
|
|
public function __toJSON()
|
|
{
|
|
if (defined('JSON_PRETTY_PRINT'))
|
|
return json_encode($this->__toArray(true), JSON_PRETTY_PRINT);
|
|
else
|
|
return json_encode($this->__toArray(true));
|
|
}
|
|
|
|
public function __toString()
|
|
{
|
|
return $this->__toJSON();
|
|
}
|
|
|
|
public function __toArray($recursive=false)
|
|
{
|
|
if ($recursive)
|
|
return Stripe_Util::convertStripeObjectToArray($this->_values);
|
|
else
|
|
return $this->_values;
|
|
}
|
|
}
|
|
|
|
|
|
Stripe_Object::init();
|