ErrorHandling::client()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
c 0
b 0
f 0
rs 10
cc 2
eloc 1
nc 2
nop 1
1
<?php
2
3
namespace Amelia\Monzo\Api;
4
5
use Closure;
6
use Amelia\Monzo\Exceptions\InvalidTokenException;
7
8
/**
9
 * Handle common retrying.
10
 *
11
 * @property \Amelia\Monzo\Client $client
12
 * @property string|null $token
13
 * @property string|null $refreshToken
14
 */
15
trait ErrorHandling
16
{
17
    /**
18
     * Run an API call with error handling in case our access token is expired.
19
     *
20
     * @param \Closure $callback
21
     * @return mixed
22
     */
23
    protected function retry(Closure $callback)
24
    {
25
        try {
26
            return $callback();
27
        } catch (InvalidTokenException $e) {
28
            if ($this->hasRefreshToken()) {
29
                $this->refresh();
30
31
                return $callback();
32
            }
33
34
            throw $e;
35
        }
36
    }
37
38
    /**
39
     * Refresh the credentials for this request.
40
     *
41
     * @return array
42
     */
43
    public function refresh()
44
    {
45
        $result = $this->client->refresh($this->getRefreshToken());
46
47
        $token = $result['access_token'];
48
        $refreshToken = $result['refresh_token'];
49
50
        if ($this->hasUser()) {
51
            $user = $this->getUser();
52
53
            $user->updateMonzoCredentials($token, $refreshToken);
54
        }
55
56
        $this->token = $token;
57
        $this->refreshToken = $refreshToken;
58
59
        return $result;
60
    }
61
62
    /**
63
     * Call a specific endpoint on the client, with retrying for access tokens.
64
     *
65
     * @param string $method The method we want to use (GET, POST, PUT, DELETE, PATCH)
66
     * @param string $endpoint The endpoint we want to hit.
67
     * @param array $query The query params we're going to send.
68
     * @param array $data The form params we're going to send (if non-GET)
69
     * @param null|string $key The key we're expecting inside of this method
70
     * @param bool $new If a new client should be used or not.
71
     * @return array
72
     */
73
    public function call(string $method, string $endpoint, array $query = [], array $data = [], ?string $key = null, bool $new = true)
74
    {
75
        return $this->retry(function () use ($method, $endpoint, $query, $data, $key, $new) {
76
            return $this->client($new)
77
                ->token($this->getAccessToken())
78
                ->call($method, $endpoint, $query, $data, $key);
79
        });
80
    }
81
82
    /**
83
     * Get a client instance.
84
     *
85
     * @param bool $new
86
     * @return \Amelia\Monzo\Contracts\Client
87
     */
88
    protected function client(bool $new = true)
89
    {
90
        return $new ? $this->client->newClient() : $this->client;
91
    }
92
}
93