Completed
Pull Request — master (#52)
by ARCANEDEV
07:42
created

Util   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 201
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Test Coverage

Coverage 86.54%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 201
ccs 45
cts 52
cp 0.8654
rs 10
c 2
b 0
f 0
wmc 22
lcom 2
cbo 1

6 Methods

Rating   Name   Duplication   Size   Complexity  
B convertStripeObjectToArray() 0 21 5
A convertToStripeObject() 0 17 3
A getClassTypeObject() 0 6 2
B secureCompare() 0 22 5
A isList() 0 11 4
A isClassTypeObjectExist() 0 8 3
1
<?php namespace Arcanedev\Stripe\Utilities;
2
3
use Arcanedev\Stripe\Collection;
4
use Arcanedev\Stripe\Contracts\Utilities\Util as UtilContract;
5
use Arcanedev\Stripe\Resources;
6
use Arcanedev\Stripe\StripeObject;
7
8
/**
9
 * Class     Util
10
 *
11
 * @package  Arcanedev\Stripe\Utilities
12
 * @author   ARCANEDEV <[email protected]>
13
 */
14
abstract class Util implements UtilContract
15
{
16
    /* -----------------------------------------------------------------
17
     |  Properties
18
     | -----------------------------------------------------------------
19
     */
20
21
    /**
22
     * Available Resources.
23
     *
24
     * @var array
25
     */
26
    private static $resources = [
27
        'account'             => Resources\Account::class,
28
        'alipay_account'      => Resources\AlipayAccount::class,
29
        'apple_pay_domain'    => Resources\ApplePayDomain::class,
30
        'balance_transaction' => Resources\BalanceTransaction::class,
31
        'bank_account'        => Resources\BankAccount::class,
32
        'bitcoin_receiver'    => Resources\BitcoinReceiver::class,
33
        'bitcoin_transaction' => Resources\BitcoinTransaction::class,
34
        'card'                => Resources\Card::class,
35
        'charge'              => Resources\Charge::class,
36
        'country_spec'        => Resources\CountrySpec::class,
37
        'coupon'              => Resources\Coupon::class,
38
        'customer'            => Resources\Customer::class,
39
        'discount'            => Resources\Discount::class,
40
        'dispute'             => Resources\Dispute::class,
41
        'event'               => Resources\Event::class,
42
        'fee_refund'          => Resources\ApplicationFeeRefund::class,
43
        'file_upload'         => Resources\FileUpload::class,
44
        'invoice'             => Resources\Invoice::class,
45
        'invoiceitem'         => Resources\InvoiceItem::class,
46
        'list'                => Collection::class,                      // List Object
47
        'login_link'          => Resources\LoginLink::class,
48
        'order'               => Resources\Order::class,
49
        'order_item'          => Resources\OrderItem::class,
50
        'order_return'        => Resources\OrderReturn::class,
51
        'payout'              => Resources\Payout::class,
52
        'plan'                => Resources\Plan::class,
53
        'product'             => Resources\Product::class,
54
        'recipient'           => Resources\Recipient::class,
55
        'recipient_transfer'  => Resources\RecipientTransfer::class,
56
        'refund'              => Resources\Refund::class,
57
        'sku'                 => Resources\Sku::class,
58
        'source'              => Resources\Source::class,
59
        'subscription'        => Resources\Subscription::class,
60
        'subscription_item'   => Resources\SubscriptionItem::class,
61
        'three_d_secure'      => Resources\ThreeDSecure::class,
62
        'token'               => Resources\Token::class,
63
        'transfer'            => Resources\Transfer::class,
64
        'transfer_reversal'   => Resources\TransferReversal::class,
65
    ];
66
67
    private static $isHashEqualsAvailable = null;
68
69
    /* -----------------------------------------------------------------
70
     |  Main Methods
71
     | -----------------------------------------------------------------
72
     */
73
74
    /**
75
     * Recursively converts the PHP Stripe object to an array.
76
     *
77
     * @param  array  $values
78
     *
79
     * @return array
80
     */
81 12
    public static function convertStripeObjectToArray($values)
82
    {
83 12
        $results = [];
84
85 12
        foreach ($values as $k => $v) {
86
            // TODO: Fix the encapsulation violation
87 12
            if ($k[0] == '_') continue;
88
89 12
            if ($v instanceof StripeObject) {
90 6
                $results[$k] = $v->toArray(true);
91 2
            }
92 12
            elseif (is_array($v)) {
93 3
                $results[$k] = self::convertStripeObjectToArray($v);
94 1
            }
95
            else {
96 12
                $results[$k] = $v;
97
            }
98 4
        }
99
100 12
        return $results;
101
    }
102
103
    /**
104
     * Converts a response from the Stripe API to the corresponding PHP object.
105
     *
106
     * @param  array  $response
107
     * @param  array  $options
108
     *
109
     * @return \Arcanedev\Stripe\StripeObject|\Arcanedev\Stripe\StripeResource|\Arcanedev\Stripe\Collection|array
110
     */
111 516
    public static function convertToStripeObject($response, $options)
112
    {
113 516
        if (self::isList($response)) {
114 429
            return array_map(function($i) use ($options) {
115 309
                return self::convertToStripeObject($i, $options);
116 429
            }, $response);
117
        }
118 516
        elseif (is_array($response)) {
119 486
            return StripeObject::scopedConstructFrom(
120 486
                self::getClassTypeObject($response),
121 162
                $response,
122 324
                $options
123 162
            );
124
        }
125
126 516
        return $response;
127
    }
128
129
    /**
130
     * Get Class Type.
131
     *
132
     * @param  array  $response
133
     *
134
     * @return string
135
     */
136 486
    private static function getClassTypeObject($response)
137
    {
138 486
        return self::isClassTypeObjectExist($response)
139 478
            ? self::$resources[ $response['object'] ]
140 486
            : StripeObject::class;
141
    }
142
143
    /**
144
     * Compares two strings for equality. The time taken is independent of the
145
     * number of characters that match.
146
     *
147
     * @param  string  $one
148
     * @param  string  $two
149
     *
150
     * @return bool
151
     */
152 18
    public static function secureCompare($one, $two)
153
    {
154 18
        if (self::$isHashEqualsAvailable === null) {
155 3
            self::$isHashEqualsAvailable = function_exists('hash_equals');
156 1
        }
157
158 18
        if (self::$isHashEqualsAvailable) {
159 18
            return hash_equals($one, $two);
160
        }
161
162
        if (strlen($one) != strlen($two)) {
163
            return false;
164
        }
165
166
        $result = 0;
167
168
        for ($i = 0; $i < strlen($one); $i++) {
169
            $result |= ord($one[$i]) ^ ord($two[$i]);
170
        }
171
172
        return ($result == 0);
173
    }
174
175
    /* -----------------------------------------------------------------
176
     |  Check Methods
177
     | -----------------------------------------------------------------
178
     */
179
180
    /**
181
     * Whether the provided array (or other) is a list rather than a dictionary.
182
     *
183
     * @param  mixed  $array
184
     *
185
     * @return bool
186
     */
187 519
    public static function isList($array)
188
    {
189 519
        if ( ! is_array($array)) return false;
190
191
        // TODO: generally incorrect, but it's correct given Stripe's response
192 489
        foreach (array_keys($array) as $k) {
193 489
            if ( ! is_numeric($k)) return false;
194 144
        }
195
196 432
        return true;
197
    }
198
199
    /**
200
     * Check if the object is a resource.
201
     *
202
     * @param  array  $response
203
     *
204
     * @return bool
205
     */
206 486
    private static function isClassTypeObjectExist($response)
207
    {
208 486
        if (isset($response['object']) && is_string($response['object'])) {
209 477
            return array_key_exists($response['object'], self::$resources);
210
        }
211
212 192
        return false;
213
    }
214
}
215