Passed
Push — master ( 53a102...982204 )
by Alexander
02:01
created

Client::getMessage()   A

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 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
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($this);
0 ignored issues
show
Unused Code introduced by
The call to Maknz\Slack\Message::__construct() has too many arguments starting with $this. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

433
        $message = /** @scrutinizer ignore-call */ new Message($this);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
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, ['body' => $encoded]);
476
    }
477
478
    /**
479
     * Send the message.
480
     *
481
     * @param string|\Maknz\Slack\Message $text The text to send
482
     *
483
     * @return \Maknz\Slack\Message
484
     *
485
     * @throws \RuntimeException
486
     */
487 1
    public function send($text = null)
488
    {
489 1
        if ($text instanceof Message) {
490
            $message = $text;
491
        } else {
492 1
            $message = $this->getOrCreateMessage();
493 1
            if ($text !== null) {
494 1
                $message->setText($text);
495
            }
496
        }
497
498 1
        $this->sendMessage($message);
499
500
        $this->message = null;
501
502
        return $message;
503
    }
504
505
    /**
506
     * Prepares the payload to be sent to the webhook.
507
     *
508
     * @param \Maknz\Slack\Message $message The message to send
509
     *
510
     * @return array
511
     */
512 6
    public function preparePayload(Message $message)
513
    {
514 6
        $payload = [
515 6
            'text'         => $message->getText(),
516 6
            'channel'      => $message->getChannel(),
517 6
            'username'     => $message->getUsername(),
518 6
            'response_type'=> $this->getResponseType(),
519 6
            'link_names'   => $this->getLinkNames() ? 1 : 0,
520 6
            'unfurl_links' => $this->getUnfurlLinks(),
521 6
            'unfurl_media' => $this->getUnfurlMedia(),
522 6
            'mrkdwn'       => $message->getAllowMarkdown(),
523
        ];
524
525 6
        if ($icon = $message->getIcon()) {
526
            $payload[$message->getIconType()] = $icon;
527
        }
528
529 6
        if (count($message->getBlocks())) {
530 1
            $payload['blocks'] = $message->getBlocksAsArrays();
531
        } else {
532 5
            $payload['attachments'] = $this->getAttachmentsAsArrays($message);
533
        }
534
535 6
        return $payload;
536
    }
537
538
    /**
539
     * Get the attachments in array form.
540
     *
541
     * @param \Maknz\Slack\Message $message
542
     *
543
     * @return array
544
     */
545 5
    protected function getAttachmentsAsArrays(Message $message)
546
    {
547 5
        $attachments = [];
548
549 5
        foreach ($message->getAttachments() as $attachment) {
550 3
            $attachments[] = $attachment->toArray();
551
        }
552
553 5
        return $attachments;
554
    }
555
}
556