Passed
Push — develop ( 454df3...d9944b )
by Jimmy
02:28
created

Client::oauthUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 10
ccs 6
cts 6
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Spinen\ClickUp\Api;
4
5
use GuzzleHttp\Client as Guzzle;
6
use GuzzleHttp\Exception\GuzzleException;
7
use Spinen\ClickUp\Exceptions\TokenException;
8
9
/**
10
 * Class Client
11
 *
12
 * @package Spinen\ClickUp
13
 */
14
class Client
15
{
16
    /**
17
     * Configs for the client
18
     *
19
     * @var array
20
     */
21
    protected $configs;
22
23
    /**
24
     * Guzzle instance
25
     *
26
     * @var Guzzle
27
     */
28
    protected $guzzle;
29
30
    /**
31
     * API Token
32
     *
33
     * @var string
34
     */
35
    protected $token;
36
37
    /**
38
     * Client constructor.
39
     *
40
     * @param array $configs
41
     * @param Guzzle $guzzle
42
     * @param string|null $token
43
     */
44 21
    public function __construct(array $configs, Guzzle $guzzle, $token = null)
45
    {
46 21
        $this->setConfigs($configs);
47 21
        $this->guzzle = $guzzle;
48 21
        $this->setToken($token);
49
    }
50
51
    /**
52
     * Shortcut to 'DELETE' request
53
     *
54
     * @param string $path
55
     *
56
     * @return array
57
     * @throws GuzzleException
58
     * @throws TokenException
59
     */
60 1
    public function delete($path): array
61
    {
62 1
        return $this->request($path, [], 'DELETE');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->request($path, array(), 'DELETE') could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
63
    }
64
65
    /**
66
     * Shortcut to 'GET' request
67
     *
68
     * @param string $path
69
     *
70
     * @return array
71
     * @throws GuzzleException
72
     * @throws TokenException
73
     */
74 1
    public function get($path): array
75
    {
76 1
        return $this->request($path, null, 'GET');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->request($path, null, 'GET') could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
77
    }
78
79
    /**
80
     * Convert OAuth code to token for user
81
     *
82
     * @param string $code
83
     *
84
     * @return string
85
     * @throws GuzzleException
86
     */
87 2
    public function oauthRequestTokenUsingCode($code): string
88
    {
89 2
        $path = 'oauth/token?' . http_build_query(
90
            [
91 2
                'client_id'     => $this->configs['oauth']['id'],
92 2
                'client_secret' => $this->configs['oauth']['secret'],
93 2
                'code'          => $code,
94
            ]
95
        );
96
97
        try {
98 2
            return json_decode(
99 2
                $this->guzzle->request(
100 2
                    'POST',
101 2
                    $this->uri($path),
102
                    [
103 2
                        'headers' => [
104
                            'Content-Type'  => 'application/json',
105
                        ],
106
                    ]
107
                )
108 1
                             ->getBody()
109 1
                             ->getContents(),
110 1
                true
111 1
            )['access_token'];
112 1
        } catch (GuzzleException $e) {
113
            // TODO: Figure out what to do with this error
114
            // TODO: Consider returning [] for 401's?
115
116 1
            throw $e;
117
        }
118
    }
119
120
    /**
121
     * Build the uri to redirect the user to start the OAuth process
122
     *
123
     * @param string $url
124
     *
125
     * @return string
126
     */
127 1
    public function oauthUri($url): string
128
    {
129 1
        return $this->uri(
130 1
            '?' . http_build_query(
131
                [
132 1
                    'client_id'    => $this->configs['oauth']['id'],
133 1
                    'redirect_uri' => $url,
134
                ]
135
            ),
136 1
            $this->configs['oauth']['url']
137
        );
138
    }
139
140
    /**
141
     * Shortcut to 'POST' request
142
     *
143
     * @param string $path
144
     * @param array $data
145
     *
146
     * @return array
147
     * @throws GuzzleException
148
     * @throws TokenException
149
     */
150 1
    public function post($path, array $data): array
151
    {
152 1
        return $this->request($path, $data, 'POST');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->request($path, $data, 'POST') could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
153
    }
154
155
    /**
156
     * Shortcut to 'PUT' request
157
     *
158
     * @param string $path
159
     * @param array $data
160
     *
161
     * @return array
162
     * @throws GuzzleException
163
     * @throws TokenException
164
     */
165 1
    public function put($path, array $data): array
166
    {
167 1
        return $this->request($path, $data, 'PUT');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->request($path, $data, 'PUT') could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
168
    }
169
170
    /**
171
     * Make an API call to ClickUp
172
     *
173
     * @param string $path
174
     * @param array|null $data
175
     * @param string|null $method
176
     *
177
     * @return array
178
     * @throws GuzzleException
179
     * @throws TokenException
180
     */
181 13
    public function request($path, $data = [], $method = 'GET'): ?array
182
    {
183 13
        if (!$this->token) {
184 2
            throw new TokenException('Must set token before making a request');
185
        }
186
187
        try {
188 13
            return json_decode(
189 13
                $this->guzzle->request(
190 13
                    $method,
191 13
                    $this->uri($path),
192
                    [
193
                        'headers' => [
194 13
                            'Authorization' => $this->token,
195 13
                            'Content-Type'  => 'application/json',
196
                        ],
197 13
                        'body'    => json_encode($data),
198
                    ]
199
                )
200 12
                             ->getBody()
201 12
                             ->getContents(),
202 12
                true
203
            );
204 1
        } catch (GuzzleException $e) {
205
            // TODO: Figure out what to do with this error
206
            // TODO: Consider returning [] for 401's?
207
208 1
            throw $e;
209
        }
210
    }
211
212
    /**
213
     * Set the configs
214
     *
215
     * @param array $configs
216
     *
217
     * @return $this
218
     */
219 21
    public function setConfigs(array $configs): self
220
    {
221 21
        $this->configs = $configs;
222
223 21
        return $this;
224
    }
225
226
    /**
227
     * Set the token
228
     *
229
     * @param string $token
230
     *
231
     * @return $this
232
     */
233 21
    public function setToken($token): self
234
    {
235 21
        $this->token = $token;
236
237 21
        return $this;
238
    }
239
240
    /**
241
     * URL to ClickUp
242
     *
243
     * If path is passed in, then append it to the end.  By default, it will use the url
244
     * in the configs, but if an url is passed in as second parameter, then it is used.
245
     *
246
     * @param string|null $path
247
     * @param string|null $url
248
     *
249
     * @return string
250
     */
251 18
    public function uri($path = null, $url = null): string
252
    {
253 18
        return rtrim(($url ?: $this->configs['url']), '/') . ($path [0] === '?' ? null : '/') . ltrim($path, '/');
254
    }
255
}
256