Completed
Push — master ( 8bbda0...ede634 )
by ARCANEDEV
8s
created

StripeResource::staticRequest()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.243

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 16
ccs 7
cts 10
cp 0.7
rs 9.4285
cc 3
eloc 9
nc 3
nop 4
crap 3.243
1
<?php namespace Arcanedev\Stripe;
2
3
use Arcanedev\Stripe\Contracts\StripeResourceInterface;
4
use Arcanedev\Stripe\Http\RequestOptions;
5
use Arcanedev\Stripe\Http\Requestor;
6
use Arcanedev\Stripe\Utilities\Util;
7
use ReflectionClass;
8
9
/**
10
 * Class     StripeResource
11
 *
12
 * @package  Arcanedev\Stripe
13
 * @author   ARCANEDEV <[email protected]>
14
 */
15
abstract class StripeResource extends StripeObject implements StripeResourceInterface
16
{
17
    /* ------------------------------------------------------------------------------------------------
18
     |  Properties
19
     | ------------------------------------------------------------------------------------------------
20
     */
21
    /** @var array */
22
    private static $persistedHeaders = [
23
        'Stripe-Account' => true,
24
        'Stripe-Version' => true
25
    ];
26
27
    /* ------------------------------------------------------------------------------------------------
28
     |  Main Functions
29
     | ------------------------------------------------------------------------------------------------
30
     */
31
    /**
32
     * Get the base url.
33
     *
34
     * @return string
35
     */
36 655
    public static function baseUrl()
37
    {
38 655
        return Stripe::getApiBaseUrl();
39
    }
40
41
    /**
42
     * Get the refreshed resource.
43
     *
44
     * @return self
45
     */
46 100
    public function refresh()
47
    {
48 100
        $url    = $this->instanceUrl();
49
50 100
        list($response, $this->opts->apiKey) = Requestor::make($this->opts->apiKey, self::baseUrl())
51 100
            ->get($url, $this->retrieveParameters);
52
53
54
        /** @var \Arcanedev\Stripe\Http\Response $response */
55 10
        $this->setLastResponse($response);
56 10
        $this->refreshFrom($response->getJson(), $this->opts);
57
58 10
        return $this;
59
    }
60
61
    /**
62
     * Get The name of the class, with namespacing and underscores stripped.
63
     *
64
     * @param  string  $class
65
     *
66
     * @return string
67
     */
68 630
    public static function className($class = '')
69
    {
70 630
        $name = self::getShortNameClass($class);
71 630
        $name = str_split_camelcase($name, '_');
72
73 630
        return strtolower(urlencode($name));
74
    }
75
76
    /**
77
     * Get Class short name.
78
     *
79
     * @param  string  $class
80
     *
81
     * @return string
82
     */
83 630
    protected static function getShortNameClass($class = '')
84
    {
85 630
        if (empty($class)) {
86 515
            $class = get_called_class();
87 412
        }
88
89 630
        $class = new ReflectionClass($class);
90
91 630
        return $class->getShortName();
92
    }
93
94
    /**
95
     * Get the endpoint URL for the given class.
96
     *
97
     * @param  string  $class
98
     *
99
     * @return string
100
     */
101 615
    public static function classUrl($class = '')
102
    {
103 615
        $base   = self::className($class);
104
105 615
        return "/v1/${base}s";
106
    }
107
108
    /**
109
     * Get Instance URL.
110
     *
111
     * @throws \Arcanedev\Stripe\Exceptions\InvalidRequestException
112
     *
113
     * @return string
114
     */
115
    public function instanceUrl()
116
    {
117 135
        $id     = $this['id'];
118 135
        $class  = get_class($this);
119
120 135
        if (is_null($id)) {
121 10
            throw new Exceptions\InvalidRequestException(
122 10
                "Could not determine which URL to request: $class instance has invalid ID: $id", null
123 8
            );
124
        }
125
126 125
        $base   = $this->lsb('classUrl', $class);
127 125
        $extn   = urlencode(str_utf8($id));
128
129 125
        return "$base/$extn";
130
    }
131
132
    /* ------------------------------------------------------------------------------------------------
133
     |  Request Functions
134
     | ------------------------------------------------------------------------------------------------
135
     */
136
    /**
137
     * Make a request.
138
     *
139
     * @param  string             $method
140
     * @param  string             $url
141
     * @param  array|null         $params
142
     * @param  array|string|null  $options
143
     *
144
     * @return array
145
     */
146
    protected function request($method, $url, $params = [], $options = null)
147
    {
148 15
        $opts = $this->opts->merge($options);
149
150
        /** @var \Arcanedev\Stripe\Http\Response $response */
151 15
        list($response, $options) = static::staticRequest($method, $url, $params, $opts);
152 15
        $this->setLastResponse($response);
153
154 15
        return [$response->getJson(), $options];
155
    }
156
157
    /**
158
     * Make a request (static).
159
     *
160
     * @param  string             $method
161
     * @param  string             $url
162
     * @param  array|null         $params
163
     * @param  array|string|null  $options
164
     *
165
     * @return array
166
     */
167
    protected static function staticRequest($method, $url, $params, $options)
168
    {
169 569
        $opts      = RequestOptions::parse($options);
170 569
        $requestor = Requestor::make($opts->apiKey, static::baseUrl());
171
172 20
        list($response, $opts->apiKey) =
173 569
            $requestor->request($method, $url, $params, $opts->headers);
174
175 20
        foreach ($opts->headers as $k => $v) {
176
            if ( ! array_key_exists($k, self::$persistedHeaders)) {
177
                unset($opts->headers[$k]);
178
            }
179 16
        }
180
181 20
        return [$response, $opts];
182
    }
183
184
    /* ------------------------------------------------------------------------------------------------
185
     |  CRUD Scope Functions
186
     | ------------------------------------------------------------------------------------------------
187
     */
188
    /**
189
     * Retrieve scope.
190
     *
191
     * @param  string             $id
192
     * @param  array|string|null  $options
193
     *
194
     * @return self
195
     */
196
    protected static function scopedRetrieve($id, $options = null)
197
    {
198 90
        $opts     = RequestOptions::parse($options);
199 90
        $class    = get_called_class();
200
201
        /** @var self $resource */
202 90
        $resource = new $class($id, $opts);
203 90
        $resource->refresh();
204
205 10
        return $resource;
206
    }
207
208
    /**
209
     * List scope.
210
     *
211
     * @param  array|null        $params
212
     * @param  array|string|null $options
213
     *
214
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
215
     *
216
     * @return \Arcanedev\Stripe\Collection|array
217
     */
218
    protected static function scopedAll($params = [], $options = null)
219
    {
220 85
        self::checkArguments($params, $options);
221 75
        $url = static::classUrl();
222
223
        /** @var \Arcanedev\Stripe\Http\Response $response */
224 75
        list($response, $opts) = self::staticRequest('get', $url, $params, $options);
225
226
        $object = Util::convertToStripeObject($response->getJson(), $opts);
227
228
229
        self::checkIsCollectionObject($object);
230
231 4
        $object->setLastResponse($response);
232
        $object->setRequestParams($params);
233
234
        return $object;
235
    }
236
237
    /**
238
     * Create scope.
239
     *
240
     * @param  array|null         $params
241
     * @param  array|string|null  $options
242
     *
243
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
244
     * @throws \Arcanedev\Stripe\Exceptions\InvalidArgumentException
245
     *
246
     * @return self
247
     */
248
    protected static function scopedCreate($params = [], $options = null)
249
    {
250 489
        self::checkArguments($params, $options);
251
252 489
        $url = static::classUrl();
253
254
        /** @var \Arcanedev\Stripe\Http\Response $response */
255 489
        list($response, $opts) = self::staticRequest('post', $url, $params, $options);
256
257 15
        $object = Util::convertToStripeObject($response->getJson(), $opts);
0 ignored issues
show
Bug Compatibility introduced by
The expression \Arcanedev\Stripe\Utilit...nse->getJson(), $opts); of type array|Arcanedev\Stripe\StripeObject adds the type array to the return on line 260 which is incompatible with the return type documented by Arcanedev\Stripe\StripeResource::scopedCreate of type Arcanedev\Stripe\StripeResource.
Loading history...
258 15
        $object->setLastResponse($response);
259
260 15
        return $object;
261
    }
262
263
    /**
264
     * Save scope.
265
     *
266
     * @param  array|string|null  $options
267
     *
268
     * @throws \Arcanedev\Stripe\Exceptions\InvalidRequestException
269
     *
270
     * @return self
271
     */
272
    protected function scopedSave($options = null)
273
    {
274 10
        $params = $this->serializeParameters();
275
276 10
        if (count($params) > 0) {
277 10
            self::checkArguments(null, $options);
278 10
            list($response, $opts) = $this->request('post', $this->instanceUrl(), $params, $options);
279 10
            $this->refreshFrom($response, $opts);
280 8
        }
281
282 10
        return $this;
283
    }
284
285
    /**
286
     * Delete Scope.
287
     *
288
     * @param  array|null         $params
289
     * @param  array|string|null  $options
290
     *
291
     * @throws \Arcanedev\Stripe\Exceptions\InvalidRequestException
292
     *
293
     * @return self
294
     */
295
    protected function scopedDelete($params = [], $options = null)
296
    {
297
        self::checkArguments($params, $options);
298
299
        list($response, $opts) = $this->request('delete', $this->instanceUrl(), $params, $options);
300
        $this->refreshFrom($response, $opts);
301
302
        return $this;
303
    }
304
305
    /* ------------------------------------------------------------------------------------------------
306
     |  Custom Scope Functions
307
     | ------------------------------------------------------------------------------------------------
308
     */
309
    /**
310
     * Custom Post Call.
311
     *
312
     * @param  string             $url
313
     * @param  array|null         $params
314
     * @param  array|string|null  $options
315
     *
316
     * @return self
317
     */
318
    protected function scopedPostCall($url, $params = [], $options = null)
319
    {
320
        $opts      = RequestOptions::parse($options);
321
        $requestor = Requestor::make($opts->getApiKey(), static::baseUrl());
322
323
        /** @var \Arcanedev\Stripe\Http\Response $response */
324
        list($response, $options) = $requestor->post($url, $params);
325
326
        $this->refreshFrom($response->getJson(), $options);
327
        $this->setLastResponse($response);
328
329
        return $this;
330
    }
331
332
    /* ------------------------------------------------------------------------------------------------
333
     |  Check Functions
334
     | ------------------------------------------------------------------------------------------------
335
     */
336
    /**
337
     * Check Arguments.
338
     *
339
     * @param  array|null         $params
340
     * @param  array|string|null  $options
341
     *
342
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
343
     * @throws \Arcanedev\Stripe\Exceptions\BadMethodCallException
344
     * @throws \Arcanedev\Stripe\Exceptions\InvalidArgumentException
345
     */
346
    private static function checkArguments($params = [], $options = null)
347
    {
348 574
        self::checkParameters($params);
349 569
        self::checkOptions($options);
350 564
    }
351
352
    /**
353
     * Check parameters.
354
     *
355
     * @param  array|null  $params
356
     *
357
     * @throws \Arcanedev\Stripe\Exceptions\InvalidArgumentException
358
     */
359
    private static function checkParameters($params)
360
    {
361 574
        if ($params && ! is_array($params)) {
362
            $message = 'You must pass an array as the first argument to Stripe API method calls.  '
363
                . '(HINT: an example call to create a charge would be: '
364 4
                . 'StripeCharge::create([\'amount\' => 100, \'currency\' => \'usd\', '
365 4
                . '\'card\' => [\'number\' => 4242424242424242, \'exp_month\' => 5, '
366 5
                . '\'exp_year\' => 2015]]))';
367
368 5
            throw new Exceptions\InvalidArgumentException($message);
369
        }
370 569
    }
371
372
    /**
373
     * Check Options.
374
     *
375
     * @param  array|string|null  $options
376
     *
377
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
378
     */
379
    private static function checkOptions($options)
380
    {
381 569
        if ($options && (
382 10
                ! $options instanceof RequestOptions &&
383 10
                ! is_string($options) &&
384 122
                ! is_array($options)
385 8
            )
386 455
        ) {
387
            $message = 'The second argument to Stripe API method calls is an '
388
                . 'optional per-request apiKey, which must be a string.  '
389 5
                . '(HINT: you can set a global apiKey by "Stripe::setApiKey(<apiKey>)")';
390
391 5
            throw new Exceptions\ApiException($message, 500);
392
        }
393 564
    }
394
395
    /**
396
     * Check the object is a Collection class.
397
     *
398
     * @param  mixed  $object
399
     *
400
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
401
     */
402
    private static function checkIsCollectionObject($object)
403
    {
404
        if ( ! is_a($object, 'Arcanedev\\Stripe\\Collection')) {
405
            $class   = get_class($object);
406
            $message = 'Expected type "Arcanedev\Stripe\Collection", got "' . $class . '" instead';
407
408
            throw new Exceptions\ApiException($message);
409
        }
410
    }
411
}
412