Completed
Push — master ( 9d6a1c...8772a0 )
by Ehsan
04:02
created

ApiClient::imListAsObject()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

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