Passed
Push — master ( b808b9...919917 )
by Ehsan
04:54
created

ApiClient::getArgs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 11
ccs 6
cts 6
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Botonomous\client;
4
5
use /* @noinspection PhpUndefinedClassInspection */
6
    GuzzleHttp\Client;
7
use /* @noinspection PhpUndefinedClassInspection */
8
    GuzzleHttp\Psr7\Request;
9
use Botonomous\Config;
10
use Botonomous\Team;
11
use Botonomous\utility\ArrayUtility;
12
13
/**
14
 * Class ApiClient.
15
 */
16
class ApiClient
17
{
18
    const BASE_URL = 'https://slack.com/api/';
19
20
    private $arguments = [
21
        'rtm.start' => [
22
            'required' => [
23
                'token',
24
            ],
25
            'optional' => [
26
                'simple_latest',
27
                'no_unreads',
28
                'mpim_aware',
29
            ],
30
        ],
31
        'chat.postMessage' => [
32
            'required' => [
33
                'token',
34
                'channel',
35
                'text',
36
            ],
37
            'optional' => [
38
                'parse',
39
                'link_names',
40
                'attachments',
41
                'unfurl_links',
42
                'unfurl_media',
43
                'username',
44
                'as_user',
45
                'icon_url',
46
                'icon_emoji',
47
            ],
48
        ],
49
        'oauth.access' => [
50
            'required' => [
51
                'client_id',
52
                'client_secret',
53
                'code',
54
            ],
55
            'optional' => [
56
                'redirect_uri',
57
            ],
58
        ],
59
        'team.info' => [
60
            'required' => [
61
                'token',
62
            ],
63
        ],
64
        'im.list' => [
65
            'required' => [
66
                'token',
67
            ],
68
        ],
69
        'users.list' => [
70
            'required' => [
71
                'token',
72
            ],
73
            'optional' => [
74
                'presence',
75
            ],
76
        ],
77
        'users.info' => [
78
            'required' => [
79
                'token',
80
                'user',
81
            ],
82
        ],
83
    ];
84
85
    private $client;
86
    private $token;
87
88
    /**
89
     * ApiClient constructor.
90
     *
91
     * @param null $token
92
     */
93 37
    public function __construct($token = null)
94
    {
95 37
        $this->setToken($token);
96 37
    }
97
98
    /**
99
     * API CURL Call with post method.
100
     *
101
     * @param string $method
102
     * @param array  $arguments
103
     *
104
     * @throws \Exception
105
     *
106
     * @return mixed
107
     */
108 29
    public function apiCall($method, array $arguments = [])
109
    {
110 29
        $arguments = array_merge($arguments, $this->getArgs());
111
112
        // check the required arguments are provided
113 29
        $this->validateRequiredArguments($method, $arguments);
114
115
        // filter unwanted arguments
116 26
        $arguments = $this->filterArguments($method, $arguments);
117
118
        try {
119
            /** @noinspection PhpUndefinedClassInspection */
120 26
            $request = new Request(
121 26
                'POST',
122 26
                self::BASE_URL.$method,
123 26
                ['Content-Type' => 'application/x-www-form-urlencoded'],
124
                http_build_query($arguments)
125
            );
126
127 26
            $response = $this->getClient()->send($request);
128 2
        } catch (\Exception $e) {
129 2
            throw new \Exception('Failed to send data to the Slack API: '.$e->getMessage());
130
        }
131
132 24
        $response = json_decode($response->getBody()->getContents(), true);
133
134 24
        if (!is_array($response)) {
135 1
            throw new \Exception('Failed to process response from the Slack API');
136
        }
137
138 23
        return $response;
139
    }
140
141
    /**
142
     * @throws \Exception
143
     *
144
     * @return array
145
     */
146 30
    public function getArgs()
147
    {
148 30
        $config = new Config();
149
150
        return [
151 30
            'token'    => $this->getToken(),
152 30
            'username' => $config->get('botUsername'),
153 30
            'as_user'  => $config->get('asUser'),
154 30
            'icon_url' => $config->get('iconURL'),
155
        ];
156
    }
157
158
    /**
159
     * @param $arguments
160
     *
161
     * @return mixed
162
     */
163 2
    public function chatPostMessage($arguments)
164
    {
165 2
        return $this->apiCall('chat.postMessage', $arguments);
166
    }
167
168
    /**
169
     * @param $arguments
170
     *
171
     * @throws \Exception
172
     *
173
     * @return mixed
174
     */
175 1
    public function rtmStart($arguments)
176
    {
177 1
        return $this->apiCall('rtm.start', $arguments);
178
    }
179
180
    /**
181
     * @throws \Exception
182
     *
183
     * @return array
184
     * @return Team
185
     */
186 4
    public function teamInfo()
187
    {
188 4
        $teamInfo = $this->apiCall('team.info');
189
190 4
        if (!isset($teamInfo['team'])) {
191 2
            return [];
192
        }
193
194 2
        return $teamInfo['team'];
195
    }
196
197
    /**
198
     * @return null|\Botonomous\AbstractBaseSlack
199
     */
200 2
    public function teamInfoAsObject()
201
    {
202 2
        $teamInfo = $this->teamInfo();
203
204 2
        if (empty($teamInfo)) {
205
            /* @noinspection PhpInconsistentReturnPointsInspection */
206 1
            return;
207
        }
208
209
        // return as object
210 1
        return (new Team())->load($teamInfo);
211
    }
212
213
    /**
214
     * List all the Slack users in the team.
215
     *
216
     * @return array
217
     */
218 2
    public function usersList()
219
    {
220 2
        $result = $this->apiCall('users.list');
221
222 2
        if (!isset($result['members'])) {
223 1
            return [];
224
        }
225
226 1
        return $result['members'];
227
    }
228
229
    /**
230
     * Return a user by Slack user id.
231
     *
232
     * @param $arguments
233
     *
234
     * @throws \Exception
235
     *
236
     * @return mixed
237
     */
238 10
    public function userInfo($arguments)
239
    {
240 10
        $result = $this->apiCall('users.info', $arguments);
241
242 10
        if (!isset($result['user'])) {
243
            /* @noinspection PhpInconsistentReturnPointsInspection */
244 4
            return;
245
        }
246
247 6
        return $result['user'];
248
    }
249
250
    /**
251
     * @throws \Exception
252
     *
253
     * @return mixed
254
     */
255 1
    public function test()
256
    {
257 1
        return $this->apiCall('api.test');
258
    }
259
260
    /**
261
     * @throws \Exception
262
     *
263
     * @return array
264
     */
265 1
    public function imList()
266
    {
267 1
        $result = $this->apiCall('im.list');
268
269 1
        if (!isset($result['ims'])) {
270 1
            return [];
271
        }
272
273 1
        return $result['ims'];
274
    }
275
276
    /**
277
     * @param $arguments
278
     *
279
     * @throws \Exception
280
     *
281
     * @return mixed
282
     */
283 5
    public function oauthAccess($arguments)
284
    {
285 5
        return $this->apiCall('oauth.access', $arguments);
286
    }
287
288
    /** @noinspection PhpUndefinedClassInspection
289
     * @param Client $client
290
     */
291 29
    public function setClient(Client $client)
292
    {
293 29
        $this->client = $client;
294 29
    }
295
296
    /** @noinspection PhpUndefinedClassInspection
297
     * @return Client|null
298
     */
299 26
    public function getClient()
300
    {
301 26
        if (!isset($this->client)) {
302
            /* @noinspection PhpUndefinedClassInspection */
303 8
            $this->setClient(new Client());
304
        }
305
306 26
        return $this->client;
307
    }
308
309
    /**
310
     * @param $method
311
     * @param $arguments
312
     *
313
     * @throws \Exception
314
     *
315
     * @return bool
316
     */
317 29
    private function validateRequiredArguments($method, $arguments)
318
    {
319 29
        $validArguments = $this->getArguments($method);
320
321 29
        if (!empty($validArguments['required'])) {
322 26
            foreach ($validArguments['required'] as $argument) {
323 26
                if (!isset($arguments[$argument]) || empty($arguments[$argument])) {
324 26
                    throw new \Exception("{$argument} must be provided for {$method}");
325
                }
326
            }
327
        }
328
329 26
        return true;
330
    }
331
332
    /**
333
     * @param null $method
334
     *
335
     * @throws \Exception
336
     *
337
     * @return mixed
338
     */
339 31
    public function getArguments($method = null)
340
    {
341 31
        if ($method !== null) {
342 30
            if (!isset($this->arguments[$method])) {
343
                /* @noinspection PhpInconsistentReturnPointsInspection */
344 3
                return;
345
            }
346
347 27
            return $this->arguments[$method];
348
        }
349
350 1
        return $this->arguments;
351
    }
352
353
    /**
354
     * @param array $arguments
355
     */
356 1
    public function setArguments(array $arguments)
357
    {
358 1
        $this->arguments = $arguments;
359 1
    }
360
361
    /**
362
     * @param       $method
363
     * @param array $arguments
364
     *
365
     * @return array
366
     */
367 27
    public function filterArguments($method, array $arguments)
368
    {
369 27
        $validArguments = $this->getArguments($method);
370
371 27
        if (empty($validArguments)) {
372 3
            return $arguments;
373
        }
374
375 24
        if (!isset($validArguments['optional'])) {
376 15
            $validArguments['optional'] = [];
377
        }
378
379 24
        $extractedArguments = array_merge($validArguments['required'], $validArguments['optional']);
380
381 24
        return (new ArrayUtility())->filterArray($arguments, $extractedArguments);
382
    }
383
384
    /**
385
     * @return string
386
     */
387 30
    public function getToken()
388
    {
389
        // fall back to config
390 30
        if (empty($this->token)) {
391 30
            $this->setToken((new Config())->get('accessToken'));
392
        }
393
394 30
        return $this->token;
395
    }
396
397
    /**
398
     * @param string $token
399
     */
400 37
    public function setToken($token)
401
    {
402 37
        $this->token = $token;
403 37
    }
404
}
405