Completed
Push — master ( c3616e...d9495e )
by ARCANEDEV
08:22
created

StripeResource::scopedDelete()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 2
dl 0
loc 9
ccs 4
cts 4
cp 1
crap 1
rs 9.6666
c 0
b 0
f 0
1
<?php namespace Arcanedev\Stripe;
2
3
use Arcanedev\Stripe\Contracts\StripeResource as StripeResourceContract;
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 StripeResourceContract
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 346
    public static function baseUrl()
37
    {
38 346
        return Stripe::getApiBaseUrl();
39 4
    }
40
41
    /**
42
     * Get the refreshed resource.
43
     *
44
     * @return self
45
     */
46 168
    public function refresh()
47
    {
48 168
        list($response, $this->opts->apiKey) = Requestor::make($this->opts->apiKey, self::baseUrl())
49 168
            ->get($this->instanceUrl(), $this->retrieveParameters, $this->opts->headers);
50
51
        /** @var \Arcanedev\Stripe\Http\Response $response */
52 142
        $this->setLastResponse($response);
53 142
        $this->refreshFrom($response->getJson(), $this->opts);
54
55 142
        return $this;
56 7
    }
57
58
    /**
59
     * Get The name of the class, with namespacing and underscores stripped.
60
     *
61
     * @param  string  $class
62
     *
63
     * @return string
64
     */
65 328
    public static function className($class = '')
66
    {
67 328
        $name = self::getShortNameClass($class);
68 328
        $name = str_split_camelcase($name, '_');
69
70 328
        return strtolower(urlencode($name));
71
    }
72
73
    /**
74
     * Get Class short name.
75
     *
76
     * @param  string  $class
77
     *
78
     * @return string
79
     */
80 328
    protected static function getShortNameClass($class = '')
81
    {
82 328
        if (empty($class))
83 324
            $class = get_called_class();
84
85 328
        $class = new ReflectionClass($class);
86
87 328
        return $class->getShortName();
88
    }
89
90
    /**
91
     * Get the endpoint URL for the given class.
92
     *
93
     * @param  string  $class
94
     *
95
     * @return string
96
     */
97 322
    public static function classUrl($class = '')
98
    {
99 322
        $base = self::className($class);
100
101 322
        return "/v1/${base}s";
102
    }
103
104
    /**
105
     * Get Instance URL.
106
     *
107
     * @throws \Arcanedev\Stripe\Exceptions\InvalidRequestException
108
     *
109
     * @return string
110
     */
111
    public function instanceUrl()
112
    {
113 218
        return static::resourceUrl($this['id']);
114
    }
115
116
    /**
117
     * Get the instance endpoint URL for the given class.
118
     *
119
     * @param  string  $id
120
     *
121
     * @return string
122
     *
123
     * @throws Exceptions\InvalidRequestException
124
     */
125
    public static function resourceUrl($id)
126
    {
127 230
        if ($id === null) {
128 6
            $class = get_called_class();
129 6
            throw new Exceptions\InvalidRequestException(
130 6
                "Could not determine which URL to request: $class instance has invalid ID: $id", null
131 3
            );
132
        }
133
134 224
        return static::classUrl().'/'.urlencode(str_utf8($id));
135
    }
136
137
    /* ------------------------------------------------------------------------------------------------
138
     |  Request Functions
139
     | ------------------------------------------------------------------------------------------------
140
     */
141
    /**
142
     * Make a request.
143
     *
144
     * @param  string             $method
145
     * @param  string             $url
146
     * @param  array|null         $params
147
     * @param  array|string|null  $options
148
     *
149
     * @return array
150
     */
151
    protected function request($method, $url, $params = [], $options = null)
152
    {
153 136
        $opts = $this->opts->merge($options);
154
155
        /** @var \Arcanedev\Stripe\Http\Response $response */
156 136
        list($response, $options) = static::staticRequest($method, $url, $params, $opts);
157 136
        $this->setLastResponse($response);
158
159 136
        return [$response->getJson(), $options];
160
    }
161
162
    /**
163
     * Make a request (static).
164
     *
165
     * @param  string             $method
166
     * @param  string             $url
167
     * @param  array|null         $params
168
     * @param  array|string|null  $options
169
     *
170
     * @return array
171
     */
172
    protected static function staticRequest($method, $url, $params, $options)
173
    {
174 326
        $opts      = RequestOptions::parse($options);
175 326
        $requestor = Requestor::make($opts->apiKey, static::baseUrl());
176
177 318
        list($response, $opts->apiKey) =
178 326
            $requestor->request($method, $url, $params, $opts->headers);
179
180 318
        foreach ($opts->headers as $k => $v) {
181 20
            if ( ! array_key_exists($k, self::$persistedHeaders))
182 20
                unset($opts->headers[$k]);
183 159
        }
184
185 318
        return [$response, $opts];
186
    }
187
188
    /* ------------------------------------------------------------------------------------------------
189
     |  CRUD Scope Functions
190
     | ------------------------------------------------------------------------------------------------
191
     */
192
    /**
193
     * Retrieve scope.
194
     *
195
     * @param  string             $id
196
     * @param  array|string|null  $options
197
     *
198
     * @return self
199
     */
200
    protected static function scopedRetrieve($id, $options = null)
201
    {
202 164
        $class    = get_called_class();
203
204
        /** @var self $resource */
205 164
        $resource = new $class($id, RequestOptions::parse($options));
206 164
        $resource->refresh();
207
208 138
        return $resource;
209
    }
210
211
    /**
212
     * List scope.
213
     *
214
     * @param  array|null         $params
215
     * @param  array|string|null  $options
216
     *
217
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
218
     *
219
     * @return \Arcanedev\Stripe\Collection|array
220
     */
221
    protected static function scopedAll($params = [], $options = null)
222
    {
223 60
        self::checkArguments($params, $options);
224
225 56
        $url = static::classUrl();
226
227
        /** @var \Arcanedev\Stripe\Http\Response $response */
228 56
        list($response, $opts) = self::staticRequest('get', $url, $params, $options);
229
230 56
        $object = Util::convertToStripeObject($response->getJson(), $opts);
231
232 56
        self::checkIsCollectionObject($object);
233
234 56
        $object->setLastResponse($response);
235 56
        $object->setRequestParams($params);
236
237 56
        return $object;
238
    }
239
240
    /**
241
     * Create scope.
242
     *
243
     * @param  array|null         $params
244
     * @param  array|string|null  $options
245
     *
246
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
247
     * @throws \Arcanedev\Stripe\Exceptions\InvalidArgumentException
248
     *
249
     * @return self
250
     */
251
    protected static function scopedCreate($params = [], $options = null)
252
    {
253 274
        self::checkArguments($params, $options);
254
255
        /** @var \Arcanedev\Stripe\Http\Response $response */
256 274
        list($response, $opts) = static::staticRequest('post', static::classUrl(), $params, $options);
257
258 266
        $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 261 which is incompatible with the return type documented by Arcanedev\Stripe\StripeResource::scopedCreate of type Arcanedev\Stripe\StripeResource.
Loading history...
259 266
        $object->setLastResponse($response);
260
261 266
        return $object;
262
    }
263
264
    /**
265
     * Update scope.
266
     *
267
     * @param  string             $id
268
     * @param  array|null         $params
269
     * @param  array|string|null  $options
270
     *
271
     * @return self
272
     *
273
     * @throws \Arcanedev\Stripe\Exceptions\InvalidArgumentException
274
     */
275
    protected static function scopedUpdate($id, $params = null, $options = null)
276
    {
277 32
        self::checkArguments($params, $options);
278
279
        /** @var \Arcanedev\Stripe\Http\Response $response */
280 32
        list($response, $opts) = static::staticRequest('post', static::resourceUrl($id), $params, $options);
281
282 32
        $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 285 which is incompatible with the return type documented by Arcanedev\Stripe\StripeResource::scopedUpdate of type Arcanedev\Stripe\StripeResource.
Loading history...
Bug introduced by
It seems like $response->getJson() targeting Arcanedev\Stripe\Http\Response::getJson() can also be of type null; however, Arcanedev\Stripe\Utiliti...convertToStripeObject() does only seem to accept array, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
283 32
        $object->setLastResponse($response);
284
285 32
        return $object;
286
    }
287
288
    /**
289
     * Save scope.
290
     *
291
     * @param  array|string|null  $options
292
     *
293
     * @throws \Arcanedev\Stripe\Exceptions\InvalidRequestException
294
     *
295
     * @return self
296
     */
297
    protected function scopedSave($options = null)
298
    {
299 78
        if (count($params = $this->serializeParameters()) > 0) {
300 68
            self::checkArguments(null, $options);
301 68
            list($response, $opts) = $this->request('post', $this->instanceUrl(), $params, $options);
302 68
            $this->refreshFrom($response, $opts);
303 34
        }
304
305 78
        return $this;
306
    }
307
308
    /**
309
     * Delete Scope.
310
     *
311
     * @param  array|null         $params
312
     * @param  array|string|null  $options
313
     *
314
     * @throws \Arcanedev\Stripe\Exceptions\InvalidRequestException
315
     *
316
     * @return self
317
     */
318
    protected function scopedDelete($params = [], $options = null)
319
    {
320 28
        self::checkArguments($params, $options);
321
322 28
        list($response, $opts) = $this->request('delete', $this->instanceUrl(), $params, $options);
323 28
        $this->refreshFrom($response, $opts);
324
325 28
        return $this;
326
    }
327
328
    /* ------------------------------------------------------------------------------------------------
329
     |  Custom Scope Functions
330
     | ------------------------------------------------------------------------------------------------
331
     */
332
    /**
333
     * Custom Post Call.
334
     *
335
     * @param  string             $url
336
     * @param  array|null         $params
337
     * @param  array|string|null  $options
338
     *
339
     * @return self
340
     */
341
    protected function scopedPostCall($url, $params = [], $options = null)
342
    {
343
        /** @var \Arcanedev\Stripe\Http\Response $response */
344 18
        list($response, $options) = Requestor::make(RequestOptions::parse($options)->getApiKey(), static::baseUrl())
345 18
            ->post($url, $params);
346
347 18
        $this->refreshFrom($response->getJson(), $options);
348 18
        $this->setLastResponse($response);
349
350 18
        return $this;
351
    }
352
353
    /* ------------------------------------------------------------------------------------------------
354
     |  Check Functions
355
     | ------------------------------------------------------------------------------------------------
356
     */
357
    /**
358
     * Check Arguments.
359
     *
360
     * @param  array|null         $params
361
     * @param  array|string|null  $options
362
     *
363
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
364
     * @throws \Arcanedev\Stripe\Exceptions\BadMethodCallException
365
     * @throws \Arcanedev\Stripe\Exceptions\InvalidArgumentException
366
     */
367
    protected static function checkArguments($params = [], $options = null)
368
    {
369 326
        self::checkParameters($params);
370 324
        self::checkOptions($options);
371 322
    }
372
373
    /**
374
     * Check parameters.
375
     *
376
     * @param  array|null  $params
377
     *
378
     * @throws \Arcanedev\Stripe\Exceptions\InvalidArgumentException
379
     */
380
    private static function checkParameters($params)
381
    {
382 326
        if ($params && ! is_array($params)) {
383 2
            throw new Exceptions\InvalidArgumentException(
384
                'You must pass an array as the first argument to Stripe API method calls.  '
385
                . '(HINT: an example call to create a charge would be: '
386 1
                . 'StripeCharge::create([\'amount\' => 100, \'currency\' => \'usd\', '
387 1
                . '\'card\' => [\'number\' => 4242424242424242, \'exp_month\' => 5, '
388 2
                . '\'exp_year\' => 2015]]))');
389
        }
390 324
    }
391
392
    /**
393
     * Check Options.
394
     *
395
     * @param  array|string|null  $options
396
     *
397
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
398
     */
399
    private static function checkOptions($options)
400
    {
401 324
        if ($options && (
402 30
                ! $options instanceof RequestOptions &&
403 30
                ! is_string($options) &&
404 173
                ! is_array($options)
405 11
            )
406 162
        ) {
407 2
            throw new Exceptions\ApiException(
408
                'The second argument to Stripe API method calls is an '
409 91
                . 'optional per-request apiKey, which must be a string.  '
410 2
                . '(HINT: you can set a global apiKey by "Stripe::setApiKey(<apiKey>)")',
411 1
                500
412 1
            );
413
        }
414 322
    }
415
416
    /**
417
     * Check the object is a Collection class.
418
     *
419
     * @param  mixed  $object
420
     *
421
     * @throws \Arcanedev\Stripe\Exceptions\ApiException
422
     */
423
    private static function checkIsCollectionObject($object)
424
    {
425 56
        if ( ! is_a($object, Collection::class)) {
426
            throw new Exceptions\ApiException(
427
                'Expected type "Arcanedev\Stripe\Collection", got "'.get_class($object).'" instead'
428
            );
429
        }
430 56
    }
431
}
432