Issues (12)

src/Api/Client.php (2 issues)

1
<?php
2
3
namespace Spinen\ClickUp\Api;
4
5
use GuzzleHttp\Client as Guzzle;
6
use GuzzleHttp\Exception\GuzzleException;
7
use Illuminate\Support\Str;
8
use Spinen\ClickUp\Exceptions\TokenException;
9
10
/**
11
 * Class Client
12
 *
13
 * @package Spinen\ClickUp
14
 */
15
class Client
16
{
17
    /**
18
     * Configs for the client
19
     *
20
     * @var array
21
     */
22
    protected $configs;
23
24
    /**
25
     * Guzzle instance
26
     *
27
     * @var Guzzle
28
     */
29
    protected $guzzle;
30
31
    /**
32
     * API Token
33
     *
34
     * @var string
35
     */
36
    protected $token;
37
38
    /**
39
     * Client constructor.
40
     *
41
     * @param array $configs
42
     * @param Guzzle $guzzle
43
     * @param string|null $token
44
     */
45 23
    public function __construct(array $configs, Guzzle $guzzle, $token = null)
46
    {
47 23
        $this->setConfigs($configs);
48 23
        $this->guzzle = $guzzle;
49 23
        $this->setToken($token);
50 23
    }
51
52
    /**
53
     * Shortcut to 'DELETE' request
54
     *
55
     * @param string $path
56
     *
57
     * @return array|null
58
     * @throws GuzzleException
59
     * @throws TokenException
60
     */
61 1
    public function delete($path): ?array
62
    {
63 1
        return $this->request($path, [], 'DELETE');
64
    }
65
66
    /**
67
     * Shortcut to 'GET' request
68
     *
69
     * @param string $path
70
     *
71
     * @return array|null
72
     * @throws GuzzleException
73
     * @throws TokenException
74
     */
75 1
    public function get($path): ?array
76
    {
77 1
        return $this->request($path, [], 'GET');
78
    }
79
80
    /**
81
     * Convert OAuth code to token for user
82
     *
83
     * @param string $code
84
     *
85
     * @return string
86
     * @throws GuzzleException
87
     */
88 2
    public function oauthRequestTokenUsingCode($code): string
89
    {
90 2
        $path = 'oauth/token?' . http_build_query(
91
            [
92 2
                'client_id'     => $this->configs['oauth']['id'],
93 2
                'client_secret' => $this->configs['oauth']['secret'],
94 2
                'code'          => $code,
95
            ]
96
        );
97
98
        try {
99 2
            return json_decode(
100 2
                $this->guzzle->request(
101 2
                    'POST',
102 2
                    $this->uri($path),
103
                    [
104
                        'headers' => [
105 2
                            'Content-Type'  => 'application/json',
106
                        ],
107
                    ]
108
                )
109 1
                             ->getBody()
110 1
                             ->getContents(),
111 1
                true
112 1
            )['access_token'];
113 1
        } catch (GuzzleException $e) {
114
            // TODO: Figure out what to do with this error
115
            // TODO: Consider returning [] for 401's?
116
117 1
            throw $e;
118
        }
119
    }
120
121
    /**
122
     * Build the uri to redirect the user to start the OAuth process
123
     *
124
     * @param string $url
125
     *
126
     * @return string
127
     */
128 1
    public function oauthUri($url): string
129
    {
130 1
        return $this->uri(
131 1
            '?' . http_build_query(
132
                [
133 1
                    'client_id'    => $this->configs['oauth']['id'],
134 1
                    'redirect_uri' => $url,
135
                ]
136
            ),
137 1
            $this->configs['oauth']['url']
138
        );
139
    }
140
141
    /**
142
     * Shortcut to 'POST' request
143
     *
144
     * @param string $path
145
     * @param array $data
146
     *
147
     * @return array|null
148
     * @throws GuzzleException
149
     * @throws TokenException
150
     */
151 1
    public function post($path, array $data): ?array
152
    {
153 1
        return $this->request($path, $data, 'POST');
154
    }
155
156
    /**
157
     * Shortcut to 'PUT' request
158
     *
159
     * @param string $path
160
     * @param array $data
161
     *
162
     * @return array|null
163
     * @throws GuzzleException
164
     * @throws TokenException
165
     */
166 1
    public function put($path, array $data): ?array
167
    {
168 1
        return $this->request($path, $data, 'PUT');
169
    }
170
171
    /**
172
     * Make an API call to ClickUp
173
     *
174
     * @param string $path
175
     * @param array|null $data
176
     * @param string|null $method
177
     *
178
     * @return array|null
179
     * @throws GuzzleException
180
     * @throws TokenException
181
     */
182 13
    public function request($path, $data = [], $method = 'GET'): ?array
183
    {
184 13
        if (!$this->token) {
185 2
            throw new TokenException('Must set token before making a request');
186
        }
187
188
        try {
189 13
            return json_decode(
190 13
                $this->guzzle->request(
191
                    $method,
0 ignored issues
show
It seems like $method can also be of type null; however, parameter $method of GuzzleHttp\Client::request() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

191
                    /** @scrutinizer ignore-type */ $method,
Loading history...
192 13
                    $this->uri($path),
193
                    [
194
                        'headers' => [
195 13
                            'Authorization' => $this->token,
196 13
                            'Content-Type'  => 'application/json',
197
                        ],
198 13
                        'body'    => empty($data) ? null : json_encode($data),
199
                    ]
200
                )
201 12
                             ->getBody()
202 12
                             ->getContents(),
203 12
                true
204
            );
205 1
        } catch (GuzzleException $e) {
206
            // TODO: Figure out what to do with this error
207
            // TODO: Consider returning [] for 401's?
208
209 1
            throw $e;
210
        }
211
    }
212
213
    /**
214
     * Set the configs
215
     *
216
     * @param array $configs
217
     *
218
     * @return $this
219
     */
220 23
    public function setConfigs(array $configs): self
221
    {
222
        // Replace empty strings with nulls in config values
223
        $this->configs = array_map(function($value) {
224 23
            return $value === "" ? null : $value;
225 23
        }, $configs);
226
227 23
        return $this;
228
    }
229
230
    /**
231
     * Set the token
232
     *
233
     * @param string $token
234
     *
235
     * @return $this
236
     */
237 23
    public function setToken($token): self
238
    {
239 23
        $this->token = $token;
240
241 23
        return $this;
242
    }
243
244
    /**
245
     * URL to ClickUp
246
     *
247
     * If path is passed in, then append it to the end. By default, it will use the url
248
     * in the configs, but if a url is passed in as a second parameter then it is used.
249
     * If no url is found it will use the hard-coded v2 ClickUp API URL.
250
     *
251
     * @param string|null $path
252
     * @param string|null $url
253
     *
254
     * @return string
255
     */
256 20
    public function uri($path = null, $url = null): string
257
    {
258 20
        $url = $url ?? $this->configs['url'] ?? 'https://api.clickup.com/api/v2';
259
260 20
        return rtrim($url, '/') . (Str::startsWith($path, '?') ? null : '/') . ltrim($path, '/');
0 ignored issues
show
It seems like $path can also be of type null; however, parameter $string of ltrim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

260
        return rtrim($url, '/') . (Str::startsWith($path, '?') ? null : '/') . ltrim(/** @scrutinizer ignore-type */ $path, '/');
Loading history...
261
    }
262
}
263