Skip to content

Commit

Permalink
Switch to Zend naming convention
Browse files Browse the repository at this point in the history
  • Loading branch information
gdb committed Jun 11, 2011
1 parent d0611e3 commit aa62806
Show file tree
Hide file tree
Showing 26 changed files with 906 additions and 799 deletions.
42 changes: 42 additions & 0 deletions lib/Stripe.php
@@ -0,0 +1,42 @@
<?php

// Tested on PHP 5.2, 5.3

// This snippet (and some of the curl code) due to the Facebook SDK.
if (!function_exists('curl_init')) {
throw new Exception('Stripe needs the CURL PHP extension.');
}
if (!function_exists('json_decode')) {
throw new Exception('Stripe needs the JSON PHP extension.');
}

abstract class Stripe {
public static $apiKey;
public static $apiBase = 'https://api.stripe.com/v1';
const VERSION = '1.5.1';
}

// Utilities
require_once(dirname(__FILE__) . '/Stripe/Util.php');
require_once(dirname(__FILE__) . '/Stripe/Util/Set.php');

// Errors
require_once(dirname(__FILE__) . '/Stripe/Error.php');
require_once(dirname(__FILE__) . '/Stripe/Error/Api.php');
require_once(dirname(__FILE__) . '/Stripe/Error/ApiConnection.php');
require_once(dirname(__FILE__) . '/Stripe/Error/Authentication.php');
require_once(dirname(__FILE__) . '/Stripe/Error/Card.php');
require_once(dirname(__FILE__) . '/Stripe/Error/InvalidRequest.php');

// Plumbing
require_once(dirname(__FILE__) . '/Stripe/Object.php');
require_once(dirname(__FILE__) . '/Stripe/ApiRequestor.php');
require_once(dirname(__FILE__) . '/Stripe/ApiResource.php');

// Stripe API Resources
require_once(dirname(__FILE__) . '/Stripe/Charge.php');
require_once(dirname(__FILE__) . '/Stripe/Customer.php');
require_once(dirname(__FILE__) . '/Stripe/Invoice.php');
require_once(dirname(__FILE__) . '/Stripe/InvoiceItem.php');

?>
170 changes: 170 additions & 0 deletions lib/Stripe/ApiRequestor.php
@@ -0,0 +1,170 @@
<?php

class Stripe_ApiRequestor {
public $apiKey;

public function __construct($apiKey=null) {
$this->apiKey = $apiKey;
}

public static function apiUrl($url='') {
$apiBase = Stripe::$apiBase;
return "$apiBase$url";
}

public static function utf8($value) {
if (is_string($value))
return utf8_encode($value);
else
return $value;
}

private static function objectsToIds($d) {
if ($d instanceof Stripe_ApiRequestor) {
return $d->id;
} else if (is_array($d)) {
$res = array();
foreach ($res as $k => $v)
$res[$k] = self::objectsToIds($v);
return $res;
} else {
return $d;
}
}

public static function encode($d) {
return http_build_query($d, null, '&');
}

public function request($meth, $url, $params=null) {
if (!$params)
$params = array();
list($rbody, $rcode, $myApiKey) = $this->requestRaw($meth, $url, $params);
$resp = $this->interpretResponse($rbody, $rcode);
return array($resp, $myApiKey);
}

public function handleApiError($rbody, $rcode, $resp) {
if (!is_array($resp) || !isset($resp['error']))
throw new Stripe_Error_Api("Invalid response object from API: $rbody (HTTP response code was $rcode)");
$error = $resp['error'];
switch ($rcode) {
case 400:
case 404:
throw new Stripe_Error_InvalidRequest(isset($error['message']) ? $error['message'] : null,
isset($error['param']) ? $error['param'] : null);
case 401:
throw new Stripe_Error_Authentication(isset($error['message']) ? $error['message'] : null);
case 402:
throw new Stripe_Error_Card(isset($error['message']) ? $error['message'] : null,
isset($error['param']) ? $error['param'] : null,
isset($error['code']) ? $error['code'] : null);
default:
throw new Stripe_Error_Api(isset($error['message']) ? $error['message'] : null);
}
}

private function requestRaw($meth, $url, $params) {
$myApiKey = $this->apiKey;
if (!$myApiKey)
$myApiKey = Stripe::$apiKey;
if (!$myApiKey)
throw new Stripe_Error_Authentication('No API key provided. (HINT: set your API key using "Stripe::$apiKey = <API-KEY>". You can generate API keys from the Stripe web interface. See https://stripe.com/api for details, or email support@stripe.com if you have any questions.');

$absUrl = $this->apiUrl($url);
$params = Stripe_Util::arrayClone($params);
$this->objectsToIds($params);
$langVersion = phpversion();
$uname = php_uname();
$ua = array('bindings_version' => Stripe::VERSION,
'lang' => 'php',
'lang_version' => $langVersion,
'publisher' => 'stripe',
'uname' => $uname);
$headers = array('X-Stripe-Client-User-Agent: ' . json_encode($ua),
'User-Agent: Stripe/v1 RubyBindings/' . Stripe::VERSION);
list($rbody, $rcode) = $this->curlRequest($meth, $absUrl, $headers, $params, $myApiKey);
return array($rbody, $rcode, $myApiKey);
}

private function interpretResponse($rbody, $rcode) {
try {
$resp = json_decode($rbody, true);
} catch (Exception $e) {
throw new Stripe_Error_Api("Invalid response body from API: $rbody (HTTP response code was $rcode)");
}

if ($rcode < 200 || $rcode >= 300) {
$this->handleApiError($rbody, $rcode, $resp);
}
return $resp;
}

private function curlRequest($meth, $absUrl, $headers, $params, $myApiKey) {
$curl = curl_init();
$meth = strtolower($meth);
$opts = array();
if ($meth == 'get') {
$opts[CURLOPT_HTTPGET] = 1;
if (count($params) > 0) {
$encoded = self::encode($params);
$absUrl = "$absUrl?$encoded";
}
} else if ($meth == 'post') {
$opts[CURLOPT_POST] = 1;
$opts[CURLOPT_POSTFIELDS] = self::encode($params);
} else if ($meth == 'delete') {
$opts[CURLOPT_CUSTOMREQUEST] = 'DELETE';
} else {
throw new Stripe_Error_Api("Unrecognized method $meth");
}

$absUrl = self::utf8($absUrl);
$opts[CURLOPT_URL] = $absUrl;
$opts[CURLOPT_RETURNTRANSFER] = true;
$opts[CURLOPT_CONNECTTIMEOUT] = 30;
$opts[CURLOPT_TIMEOUT] = 80;
$opts[CURLOPT_RETURNTRANSFER] = true;
$opts[CURLOPT_HTTPHEADER] = $headers;
$opts[CURLOPT_USERPWD] = $myApiKey . ':';

curl_setopt_array($curl, $opts);
$rbody = curl_exec($curl);

if (curl_errno($curl) == 60) { // CURLE_SSL_CACERT
curl_setopt($curl, CURLOPT_CAINFO,
dirname(__FILE__) . '/data/ca-certificates.crt');
$rbody = curl_exec($curl);
}

if ($rbody === false) {
$errno = curl_errno($curl);
$message = curl_error($curl);
curl_close($curl);
$this->handleCurlError($errno, $message);
}

$rcode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
return array($rbody, $rcode);
}

public function handleCurlError($errno, $message) {
$apiBase = Stripe::$apiBase;
switch ($errno) {
case CURLE_COULDNT_CONNECT:
case CURLE_COULDNT_RESOLVE_HOST:
case CURLE_OPERATION_TIMEOUTED:
$msg = "Could not connect to Stripe ($apiBase). Please check your internet connection and try again. If this problem persists, you should check Stripe's service status at https://twitter.com/stripe, or let us know at support@stripe.com.";
case CURLE_SSL_CACERT:
$msg = "Could not verify Stripe's SSL certificate. Please make sure that your network is not intercepting certificates. (Try going to $apiBase in your browser.) If this problem persists, let us know at support@stripe.com.";
default:
$msg = "Unexpected error communicating with Stripe. If this problem persists, let us know at support@stripe.com.";
}

$msg .= "\n\n(Network error: $message)";
throw new Stripe_Error_ApiConnection($msg);
}
}

?>
91 changes: 91 additions & 0 deletions lib/Stripe/ApiResource.php
@@ -0,0 +1,91 @@
<?php

abstract class Stripe_ApiResource extends Stripe_Object {
protected function ident() {
return array($this['id']);
}

protected static function scopedRetrieve($class, $id, $apiKey=null) {
$instance = new $class($id, $apiKey);
$instance->refresh();
return $instance;
}

public function refresh() {
$requestor = new Stripe_ApiRequestor($this->apiKey);
$url = $this->instanceUrl();
list($response, $apiKey) = $requestor->request('get', $url);
$this->refreshFrom($response, $apiKey);
return $this;
}

public static function classUrl($class) {
if (substr($class, 0, strlen('Stripe')) == 'Stripe')
$class = substr($class, strlen('Stripe'));
$class = str_replace('_', '', $class);
$name = urlencode($class);
$name = strtolower($name);
return "/${name}s";
}

public function instanceUrl() {
$id = $this['id'];
if (!$id) {
$class = get_class($this);
throw new Stripe_Error_InvalidRequest("Could not determine which URL to request: $class instance has invalid ID: $id");
}
$id = Stripe_ApiRequestor::utf8($id);
$class = get_class($this);
$base = self::classUrl($class);
$extn = urlencode($id);
return "$base/$extn";
}

private static function validateCall($method, $params=null, $apiKey=null) {
if ($params && !is_array($params))
throw new StripeError("You must pass an array as the first argument to Stripe API method calls. (HINT: an example call to create a charge would be: \"StripeCharge::create(array('amount' => 100, 'currency' => 'usd', 'card' => array('number' => 4242424242424242, 'exp_month' => 5, 'exp_year' => 2015)))\")");
if ($apiKey && !is_string($apiKey))
throw new StripeError('The second argument to Stripe API method calls is an optional per-request apiKey, which must be a string. (HINT: you can set a global apiKey by "Stripe::$apiKey = <apiKey>")');
}

protected static function scopedAll($class, $params=null, $apiKey=null) {
self::validateCall('all', $params, $apiKey);
$requestor = new Stripe_ApiRequestor($apiKey);
$url = self::classUrl($class);
list($response, $apiKey) = $requestor->request('get', $url, $params);
return Stripe_Util::convertToStripeObject($response, $apiKey);
}

protected static function scopedCreate($class, $params=null, $apiKey=null) {
self::validateCall('create', $params, $apiKey);
$requestor = new Stripe_ApiRequestor($apiKey);
$url = self::classUrl($class);
list($response, $apiKey) = $requestor->request('post', $url, $params);
return Stripe_Util::convertToStripeObject($response, $apiKey);
}

protected function scopedSave($class) {
self::validateCall('save');
if ($this->unsavedValues) {
$requestor = new Stripe_ApiRequestor($this->apiKey);
$params = array();
foreach ($this->unsavedValues->toArray() as $k)
$params[$k] = $this->$k;
$url = $this->instanceUrl();
list($response, $apiKey) = $requestor->request('post', $url, $params);
$this->refreshFrom($response, $apiKey);
}
return $this;
}

protected function scopedDelete($class) {
self::validateCall('delete');
$requestor = new Stripe_ApiRequestor($this->apiKey);
$url = $this->instanceUrl();
list($response, $apiKey) = $requestor->request('delete', $url);
$this->refreshFrom($response, $apiKey);
return $this;
}
}

?>
33 changes: 33 additions & 0 deletions lib/Stripe/Charge.php
@@ -0,0 +1,33 @@
<?php

class Stripe_Charge extends Stripe_ApiResource {
public static function constructFrom($values, $apiKey=null) {
$class = get_class();
return self::scopedConstructFrom($class, $values, $apiKey);
}

public static function retrieve($id, $apiKey=null) {
$class = get_class();
return self::scopedRetrieve($class, $id, $apiKey);
}

public static function all($params=null, $apiKey=null) {
$class = get_class();
return self::scopedAll($class, $params, $apiKey);
}

public static function create($params=null, $apiKey=null) {
$class = get_class();
return self::scopedCreate($class, $params, $apiKey);
}

public function refund() {
$requestor = new Stripe_ApiRequestor($this->apiKey);
$url = $this->instanceUrl() . '/refund';
list($response, $apiKey) = $requestor->request('post', $url);
$this->refreshFrom($response, $apiKey);
return $this;
}
}

?>

0 comments on commit aa62806

Please sign in to comment.