Passed
Push — master ( c8ed24...0a0550 )
by Ehsan
02:51
created

ApiClient::getArrayUtility()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

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