Passed
Push — master ( d8dede...d3c778 )
by Alexander
02:21
created

Client   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 452
Duplicated Lines 0 %

Test Coverage

Coverage 93.62%

Importance

Changes 0
Metric Value
dl 0
loc 452
ccs 88
cts 94
cp 0.9362
rs 9.2
c 0
b 0
f 0
wmc 34

27 Methods

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