composer package updates
[openemr.git] / vendor / stripe / stripe-php / lib / Util / Util.php
blob958069896da5ed9e727d6e6a3476cb21b639688c
1 <?php
3 namespace Stripe\Util;
5 use Stripe\StripeObject;
7 abstract class Util
9 private static $isMbstringAvailable = null;
10 private static $isHashEqualsAvailable = null;
12 /**
13 * Whether the provided array (or other) is a list rather than a dictionary.
14 * A list is defined as an array for which all the keys are consecutive
15 * integers starting at 0. Empty arrays are considered to be lists.
17 * @param array|mixed $array
18 * @return boolean true if the given object is a list.
20 public static function isList($array)
22 if (!is_array($array)) {
23 return false;
25 if ($array === []) {
26 return true;
28 if (array_keys($array) !== range(0, count($array) - 1)) {
29 return false;
31 return true;
34 /**
35 * Recursively converts the PHP Stripe object to an array.
37 * @param array $values The PHP Stripe object to convert.
38 * @return array
40 public static function convertStripeObjectToArray($values)
42 $results = [];
43 foreach ($values as $k => $v) {
44 // FIXME: this is an encapsulation violation
45 if ($k[0] == '_') {
46 continue;
48 if ($v instanceof StripeObject) {
49 $results[$k] = $v->__toArray(true);
50 } elseif (is_array($v)) {
51 $results[$k] = self::convertStripeObjectToArray($v);
52 } else {
53 $results[$k] = $v;
56 return $results;
59 /**
60 * Converts a response from the Stripe API to the corresponding PHP object.
62 * @param array $resp The response from the Stripe API.
63 * @param array $opts
64 * @return StripeObject|array
66 public static function convertToStripeObject($resp, $opts)
68 $types = [
69 // data structures
70 \Stripe\Collection::OBJECT_NAME => 'Stripe\\Collection',
72 // business objects
73 \Stripe\Account::OBJECT_NAME => 'Stripe\\Account',
74 \Stripe\AlipayAccount::OBJECT_NAME => 'Stripe\\AlipayAccount',
75 \Stripe\ApplePayDomain::OBJECT_NAME => 'Stripe\\ApplePayDomain',
76 \Stripe\ApplicationFee::OBJECT_NAME => 'Stripe\\ApplicationFee',
77 \Stripe\Balance::OBJECT_NAME => 'Stripe\\Balance',
78 \Stripe\BalanceTransaction::OBJECT_NAME => 'Stripe\\BalanceTransaction',
79 \Stripe\BankAccount::OBJECT_NAME => 'Stripe\\BankAccount',
80 \Stripe\BitcoinReceiver::OBJECT_NAME => 'Stripe\\BitcoinReceiver',
81 \Stripe\BitcoinTransaction::OBJECT_NAME => 'Stripe\\BitcoinTransaction',
82 \Stripe\Card::OBJECT_NAME => 'Stripe\\Card',
83 \Stripe\Charge::OBJECT_NAME => 'Stripe\\Charge',
84 \Stripe\CountrySpec::OBJECT_NAME => 'Stripe\\CountrySpec',
85 \Stripe\Coupon::OBJECT_NAME => 'Stripe\\Coupon',
86 \Stripe\Customer::OBJECT_NAME => 'Stripe\\Customer',
87 \Stripe\Discount::OBJECT_NAME => 'Stripe\\Discount',
88 \Stripe\Dispute::OBJECT_NAME => 'Stripe\\Dispute',
89 \Stripe\EphemeralKey::OBJECT_NAME => 'Stripe\\EphemeralKey',
90 \Stripe\Event::OBJECT_NAME => 'Stripe\\Event',
91 \Stripe\ExchangeRate::OBJECT_NAME => 'Stripe\\ExchangeRate',
92 \Stripe\ApplicationFeeRefund::OBJECT_NAME => 'Stripe\\ApplicationFeeRefund',
93 \Stripe\FileUpload::OBJECT_NAME => 'Stripe\\FileUpload',
94 \Stripe\Invoice::OBJECT_NAME => 'Stripe\\Invoice',
95 \Stripe\InvoiceItem::OBJECT_NAME => 'Stripe\\InvoiceItem',
96 \Stripe\InvoiceLineItem::OBJECT_NAME => 'Stripe\\InvoiceLineItem',
97 \Stripe\IssuerFraudRecord::OBJECT_NAME => 'Stripe\\IssuerFraudRecord',
98 \Stripe\LoginLink::OBJECT_NAME => 'Stripe\\LoginLink',
99 \Stripe\Order::OBJECT_NAME => 'Stripe\\Order',
100 \Stripe\OrderItem::OBJECT_NAME => 'Stripe\\OrderItem',
101 \Stripe\OrderReturn::OBJECT_NAME => 'Stripe\\OrderReturn',
102 \Stripe\PaymentIntent::OBJECT_NAME => 'Stripe\\PaymentIntent',
103 \Stripe\Payout::OBJECT_NAME => 'Stripe\\Payout',
104 \Stripe\Plan::OBJECT_NAME => 'Stripe\\Plan',
105 \Stripe\Product::OBJECT_NAME => 'Stripe\\Product',
106 \Stripe\Recipient::OBJECT_NAME => 'Stripe\\Recipient',
107 \Stripe\RecipientTransfer::OBJECT_NAME => 'Stripe\\RecipientTransfer',
108 \Stripe\Refund::OBJECT_NAME => 'Stripe\\Refund',
109 \Stripe\SKU::OBJECT_NAME => 'Stripe\\SKU',
110 \Stripe\Source::OBJECT_NAME => 'Stripe\\Source',
111 \Stripe\SourceTransaction::OBJECT_NAME => 'Stripe\\SourceTransaction',
112 \Stripe\Subscription::OBJECT_NAME => 'Stripe\\Subscription',
113 \Stripe\SubscriptionItem::OBJECT_NAME => 'Stripe\\SubscriptionItem',
114 \Stripe\ThreeDSecure::OBJECT_NAME => 'Stripe\\ThreeDSecure',
115 \Stripe\Token::OBJECT_NAME => 'Stripe\\Token',
116 \Stripe\Topup::OBJECT_NAME => 'Stripe\\Topup',
117 \Stripe\Transfer::OBJECT_NAME => 'Stripe\\Transfer',
118 \Stripe\TransferReversal::OBJECT_NAME => 'Stripe\\TransferReversal',
119 \Stripe\UsageRecord::OBJECT_NAME => 'Stripe\\UsageRecord',
121 if (self::isList($resp)) {
122 $mapped = [];
123 foreach ($resp as $i) {
124 array_push($mapped, self::convertToStripeObject($i, $opts));
126 return $mapped;
127 } elseif (is_array($resp)) {
128 if (isset($resp['object']) && is_string($resp['object']) && isset($types[$resp['object']])) {
129 $class = $types[$resp['object']];
130 } else {
131 $class = 'Stripe\\StripeObject';
133 return $class::constructFrom($resp, $opts);
134 } else {
135 return $resp;
140 * @param string|mixed $value A string to UTF8-encode.
142 * @return string|mixed The UTF8-encoded string, or the object passed in if
143 * it wasn't a string.
145 public static function utf8($value)
147 if (self::$isMbstringAvailable === null) {
148 self::$isMbstringAvailable = function_exists('mb_detect_encoding');
150 if (!self::$isMbstringAvailable) {
151 trigger_error("It looks like the mbstring extension is not enabled. " .
152 "UTF-8 strings will not properly be encoded. Ask your system " .
153 "administrator to enable the mbstring extension, or write to " .
154 "support@stripe.com if you have any questions.", E_USER_WARNING);
158 if (is_string($value) && self::$isMbstringAvailable && mb_detect_encoding($value, "UTF-8", true) != "UTF-8") {
159 return utf8_encode($value);
160 } else {
161 return $value;
166 * Compares two strings for equality. The time taken is independent of the
167 * number of characters that match.
169 * @param string $a one of the strings to compare.
170 * @param string $b the other string to compare.
171 * @return bool true if the strings are equal, false otherwise.
173 public static function secureCompare($a, $b)
175 if (self::$isHashEqualsAvailable === null) {
176 self::$isHashEqualsAvailable = function_exists('hash_equals');
179 if (self::$isHashEqualsAvailable) {
180 return hash_equals($a, $b);
181 } else {
182 if (strlen($a) != strlen($b)) {
183 return false;
186 $result = 0;
187 for ($i = 0; $i < strlen($a); $i++) {
188 $result |= ord($a[$i]) ^ ord($b[$i]);
190 return ($result == 0);
195 * @param array $arr A map of param keys to values.
196 * @param string|null $prefix
198 * @return string A querystring, essentially.
200 public static function urlEncode($arr, $prefix = null)
202 if (!is_array($arr)) {
203 return $arr;
206 $r = [];
207 foreach ($arr as $k => $v) {
208 if (is_null($v)) {
209 continue;
212 if ($prefix) {
213 if ($k !== null && (!is_int($k) || is_array($v))) {
214 $k = $prefix."[".$k."]";
215 } else {
216 $k = $prefix."[]";
220 if (is_array($v)) {
221 $enc = self::urlEncode($v, $k);
222 if ($enc) {
223 $r[] = $enc;
225 } else {
226 $r[] = urlencode($k)."=".urlencode($v);
230 return implode("&", $r);
233 public static function normalizeId($id)
235 if (is_array($id)) {
236 $params = $id;
237 $id = $params['id'];
238 unset($params['id']);
239 } else {
240 $params = [];
242 return [$id, $params];