Client::setUnfurlMedia()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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