Passed
Push — master ( 757eec...914788 )
by Sullivan
03:05
created

Client   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 386
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 386
rs 9
c 0
b 0
f 0
wmc 35

22 Methods

Rating   Name   Duplication   Size   Complexity  
A setAllowMarkdown() 0 3 1
F __construct() 0 44 10
A getDefaultIcon() 0 3 1
A getLinkNames() 0 3 1
A getMarkdownInAttachments() 0 3 1
A sendMessage() 0 11 2
A setLinkNames() 0 3 1
A __call() 0 3 1
A getDefaultUsername() 0 3 1
A preparePayload() 0 19 3
A setUnfurlMedia() 0 3 1
A getDefaultChannel() 0 3 1
A setDefaultChannel() 0 3 1
A setDefaultUsername() 0 3 1
A getUnfurlMedia() 0 3 1
A getAllowMarkdown() 0 3 1
A setUnfurlLinks() 0 3 1
A setDefaultIcon() 0 3 1
A getUnfurlLinks() 0 3 1
A setMarkdownInAttachments() 0 3 1
A getAttachmentsAsArrays() 0 9 2
A createMessage() 0 15 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Nexy\Slack;
6
7
use Http\Client\Common\HttpMethodsClient;
8
use Http\Client\Common\Plugin\BaseUriPlugin;
9
use Http\Client\Common\PluginClient;
10
use Http\Client\Exception;
11
use Http\Client\HttpClient;
12
use Http\Discovery\HttpClientDiscovery;
13
use Http\Discovery\MessageFactoryDiscovery;
14
use Http\Discovery\UriFactoryDiscovery;
15
16
class Client
17
{
18
    /**
19
     * The default channel to send messages to.
20
     *
21
     * @var string
22
     */
23
    private $channel;
24
25
    /**
26
     * The default username to send messages as.
27
     *
28
     * @var string
29
     */
30
    private $username;
31
32
    /**
33
     * The default icon to send messages with.
34
     *
35
     * @var string
36
     */
37
    private $icon;
38
39
    /**
40
     * Whether to link names like @regan or leave
41
     * them as plain text.
42
     *
43
     * @var bool
44
     */
45
    private $link_names = false;
46
47
    /**
48
     * Whether Slack should unfurl text-based URLs.
49
     *
50
     * @var bool
51
     */
52
    private $unfurl_links = false;
53
54
    /**
55
     * Whether Slack should unfurl media URLs.
56
     *
57
     * @var bool
58
     */
59
    private $unfurl_media = true;
60
61
    /**
62
     * Whether message text should be formatted with Slack's
63
     * Markdown-like language.
64
     *
65
     * @var bool
66
     */
67
    private $allow_markdown = true;
68
69
    /**
70
     * The attachment fields which should be formatted with
71
     * Slack's Markdown-like language.
72
     *
73
     * @var array
74
     */
75
    private $markdown_in_attachments = [];
76
77
    /**
78
     * @var HttpMethodsClient
79
     */
80
    private $httpClient;
81
82
    /**
83
     * Instantiate a new Client.
84
     *
85
     * @param string          $endpoint
86
     * @param array           $attributes
87
     * @param HttpClient|null $httpClient
88
     */
89
    public function __construct($endpoint, array $attributes = [], HttpClient $httpClient = null)
90
    {
91
        if (isset($attributes['channel'])) {
92
            $this->setDefaultChannel($attributes['channel']);
93
        }
94
95
        if (isset($attributes['username'])) {
96
            $this->setDefaultUsername($attributes['username']);
97
        }
98
99
        if (isset($attributes['icon'])) {
100
            $this->setDefaultIcon($attributes['icon']);
101
        }
102
103
        if (isset($attributes['link_names'])) {
104
            $this->setLinkNames($attributes['link_names']);
105
        }
106
107
        if (isset($attributes['unfurl_links'])) {
108
            $this->setUnfurlLinks($attributes['unfurl_links']);
109
        }
110
111
        if (isset($attributes['unfurl_media'])) {
112
            $this->setUnfurlMedia($attributes['unfurl_media']);
113
        }
114
115
        if (isset($attributes['allow_markdown'])) {
116
            $this->setAllowMarkdown($attributes['allow_markdown']);
117
        }
118
119
        if (isset($attributes['markdown_in_attachments'])) {
120
            $this->setMarkdownInAttachments($attributes['markdown_in_attachments']);
121
        }
122
123
        $this->httpClient = new HttpMethodsClient(
124
            new PluginClient(
125
                $httpClient ?: HttpClientDiscovery::find(),
126
                [
127
                    new BaseUriPlugin(
128
                        UriFactoryDiscovery::find()->createUri($endpoint)
129
                    ),
130
                ]
131
            ),
132
            MessageFactoryDiscovery::find()
133
        );
134
    }
135
136
    /**
137
     * Pass any unhandled methods through to a new Message
138
     * instance.
139
     *
140
     * @param string $name      The name of the method
141
     * @param array  $arguments The method arguments
142
     *
143
     * @return \Nexy\Slack\Message
144
     */
145
    public function __call($name, $arguments)
146
    {
147
        return \call_user_func_array([$this->createMessage(), $name], $arguments);
148
    }
149
150
    /**
151
     * Get the default channel messages will be created for.
152
     *
153
     * @return string
154
     */
155
    public function getDefaultChannel()
156
    {
157
        return $this->channel;
158
    }
159
160
    /**
161
     * Set the default channel messages will be created for.
162
     *
163
     * @param string $channel
164
     */
165
    public function setDefaultChannel($channel): void
166
    {
167
        $this->channel = $channel;
168
    }
169
170
    /**
171
     * Get the default username messages will be created for.
172
     *
173
     * @return string
174
     */
175
    public function getDefaultUsername()
176
    {
177
        return $this->username;
178
    }
179
180
    /**
181
     * Set the default username messages will be created for.
182
     *
183
     * @param string $username
184
     */
185
    public function setDefaultUsername($username): void
186
    {
187
        $this->username = $username;
188
    }
189
190
    /**
191
     * Get the default icon messages will be created with.
192
     *
193
     * @return string
194
     */
195
    public function getDefaultIcon()
196
    {
197
        return $this->icon;
198
    }
199
200
    /**
201
     * Set the default icon messages will be created with.
202
     *
203
     * @param string $icon
204
     */
205
    public function setDefaultIcon($icon): void
206
    {
207
        $this->icon = $icon;
208
    }
209
210
    /**
211
     * Get whether messages sent will have names (like @regan)
212
     * will be converted into links.
213
     *
214
     * @return bool
215
     */
216
    public function getLinkNames()
217
    {
218
        return $this->link_names;
219
    }
220
221
    /**
222
     * Set whether messages sent will have names (like @regan)
223
     * will be converted into links.
224
     *
225
     * @param bool $value
226
     */
227
    public function setLinkNames($value): void
228
    {
229
        $this->link_names = (bool) $value;
230
    }
231
232
    /**
233
     * Get whether text links should be unfurled.
234
     *
235
     * @return bool
236
     */
237
    public function getUnfurlLinks()
238
    {
239
        return $this->unfurl_links;
240
    }
241
242
    /**
243
     * Set whether text links should be unfurled.
244
     *
245
     * @param bool $value
246
     */
247
    public function setUnfurlLinks($value): void
248
    {
249
        $this->unfurl_links = (bool) $value;
250
    }
251
252
    /**
253
     * Get whether media links should be unfurled.
254
     *
255
     * @return bool
256
     */
257
    public function getUnfurlMedia()
258
    {
259
        return $this->unfurl_media;
260
    }
261
262
    /**
263
     * Set whether media links should be unfurled.
264
     *
265
     * @param bool $value
266
     */
267
    public function setUnfurlMedia($value): void
268
    {
269
        $this->unfurl_media = (bool) $value;
270
    }
271
272
    /**
273
     * Get whether message text should be formatted with
274
     * Slack's Markdown-like language.
275
     *
276
     * @return bool
277
     */
278
    public function getAllowMarkdown()
279
    {
280
        return $this->allow_markdown;
281
    }
282
283
    /**
284
     * Set whether message text should be formatted with
285
     * Slack's Markdown-like language.
286
     *
287
     * @param bool $value
288
     */
289
    public function setAllowMarkdown($value): void
290
    {
291
        $this->allow_markdown = (bool) $value;
292
    }
293
294
    /**
295
     * Get the attachment fields which should be formatted
296
     * in Slack's Markdown-like language.
297
     *
298
     * @return array
299
     */
300
    public function getMarkdownInAttachments()
301
    {
302
        return $this->markdown_in_attachments;
303
    }
304
305
    /**
306
     * Set the attachment fields which should be formatted
307
     * in Slack's Markdown-like language.
308
     *
309
     * @param array $fields
310
     */
311
    public function setMarkdownInAttachments(array $fields): void
312
    {
313
        $this->markdown_in_attachments = $fields;
314
    }
315
316
    /**
317
     * Create a new message with defaults.
318
     *
319
     * @return \Nexy\Slack\Message
320
     */
321
    public function createMessage()
322
    {
323
        $message = new Message($this);
324
325
        $message->setChannel($this->getDefaultChannel());
326
327
        $message->setUsername($this->getDefaultUsername());
328
329
        $message->setIcon($this->getDefaultIcon());
330
331
        $message->setAllowMarkdown($this->getAllowMarkdown());
332
333
        $message->setMarkdownInAttachments($this->getMarkdownInAttachments());
334
335
        return $message;
336
    }
337
338
    /**
339
     * Send a message.
340
     *
341
     * @param \Nexy\Slack\Message $message
342
     *
343
     * @throws Exception
344
     */
345
    public function sendMessage(Message $message): void
346
    {
347
        $payload = $this->preparePayload($message);
348
349
        $encoded = \json_encode($payload, JSON_UNESCAPED_UNICODE);
350
351
        if (false === $encoded) {
0 ignored issues
show
introduced by
The condition false === $encoded can never be true.
Loading history...
352
            throw new \RuntimeException(\sprintf('JSON encoding error %s: %s', \json_last_error(), \json_last_error_msg()));
353
        }
354
355
        $this->httpClient->post('', [], $encoded);
356
    }
357
358
    /**
359
     * Prepares the payload to be sent to the webhook.
360
     *
361
     * @param \Nexy\Slack\Message $message The message to send
362
     *
363
     * @return array
364
     */
365
    public function preparePayload(Message $message)
366
    {
367
        $payload = [
368
            'text' => $message->getText(),
369
            'channel' => $message->getChannel(),
370
            'username' => $message->getUsername(),
371
            'link_names' => $this->getLinkNames() ? 1 : 0,
372
            'unfurl_links' => $this->getUnfurlLinks(),
373
            'unfurl_media' => $this->getUnfurlMedia(),
374
            'mrkdwn' => $message->getAllowMarkdown(),
375
        ];
376
377
        if ($icon = $message->getIcon()) {
378
            $payload[$message->getIconType()] = $icon;
379
        }
380
381
        $payload['attachments'] = $this->getAttachmentsAsArrays($message);
382
383
        return $payload;
384
    }
385
386
    /**
387
     * Get the attachments in array form.
388
     *
389
     * @param \Nexy\Slack\Message $message
390
     *
391
     * @return array
392
     */
393
    private function getAttachmentsAsArrays(Message $message)
394
    {
395
        $attachments = [];
396
397
        foreach ($message->getAttachments() as $attachment) {
398
            $attachments[] = $attachment->toArray();
399
        }
400
401
        return $attachments;
402
    }
403
}
404