Completed
Push — master ( 4bd2de...78b398 )
by Elf
01:56
created

Message::removeTarget()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
crap 1
1
<?php
2
3
namespace ElfSundae\BearyChat;
4
5
use JsonSerializable;
6
7
class Message implements JsonSerializable
8
{
9
    /**
10
     * The BearyChat client for sending message.
11
     *
12
     * @var \ElfSundae\BearyChat\Client
13
     */
14
    protected $client;
15
16
    /**
17
     * The text to be sent with the message.
18
     *
19
     * @var string
20
     */
21
    protected $text;
22
23
    /**
24
     * The notification for the text.
25
     *
26
     * @var string
27
     */
28
    protected $notification;
29
30
    /**
31
     * Indicates the text field should be parsed as markdown syntax.
32
     *
33
     * @var bool
34
     */
35
    protected $markdown;
36
37
    /**
38
     * The channel that the message should be sent to.
39
     *
40
     * @var string
41
     */
42
    protected $channel;
43
44
    /**
45
     * The user that the message should be sent to.
46
     *
47
     * @var string
48
     */
49
    protected $user;
50
51
    /**
52
     * The attachments to be sent.
53
     *
54
     * @var array
55
     */
56
    protected $attachments = [];
57
58
    /**
59
     * The default values for each attachment.
60
     *
61
     * @var array
62
     */
63
    protected $attachmentDefaults = [];
64
65
    /**
66
     * Create a new message.
67
     *
68
     * @param  \ElfSundae\BearyChat\Client|null $client
69
     */
70 23
    public function __construct(Client $client = null)
71
    {
72 23
        if ($this->client = $client) {
73 5
            $this->configureDefaults($client->getMessageDefaults(), true);
74
        }
75 23
    }
76
77
    /**
78
     * Get the BearyChat client for sending message.
79
     *
80
     * @return \ElfSundae\BearyChat\Client
81
     */
82 2
    public function getClient()
83
    {
84 2
        return $this->client;
85
    }
86
87
    /**
88
     * Get the text.
89
     *
90
     * @return string
91
     */
92 8
    public function getText()
93
    {
94 8
        return $this->text;
95
    }
96
97
    /**
98
     * Set the text.
99
     *
100
     * @param  string  $text
101
     * @return $this
102
     */
103 7
    public function setText($text)
104
    {
105 7
        $this->text = $text ? (string) $text : null;
106
107 7
        return $this;
108
    }
109
110
    /**
111
     * Set the text.
112
     *
113
     * @param  string  $text
114
     * @return $this
115
     */
116 4
    public function text($text)
117
    {
118 4
        return $this->setText($text);
119
    }
120
121
    /**
122
     * Get the notification.
123
     *
124
     * @return string
125
     */
126 8
    public function getNotification()
127
    {
128 8
        return $this->notification;
129
    }
130
131
    /**
132
     * Set the notification.
133
     *
134
     * @param  string  $notification
135
     * @return $this
136
     */
137 5
    public function setNotification($notification)
138
    {
139 5
        $this->notification = $notification ? (string) $notification : null;
140
141 5
        return $this;
142
    }
143
144
    /**
145
     * Set the notification.
146
     *
147
     * @param  string  $notification
148
     * @return $this
149
     */
150 1
    public function notification($notification)
151
    {
152 1
        return $this->setNotification($notification);
153
    }
154
155
    /**
156
     * Get the markdown.
157
     *
158
     * @return bool
159
     */
160 8
    public function getMarkdown()
161
    {
162 8
        return $this->markdown;
163
    }
164
165
    /**
166
     * Set the markdown.
167
     *
168
     * @param  bool $markdown
169
     * @return $this
170
     */
171 4
    public function setMarkdown($markdown)
172
    {
173 4
        $this->markdown = (bool) $markdown;
174
175 4
        return $this;
176
    }
177
178
    /**
179
     * Set the markdown.
180
     *
181
     * @param  bool $markdown
182
     * @return $this
183
     */
184 1
    public function markdown($markdown = true)
185
    {
186 1
        return $this->setMarkdown($markdown);
187
    }
188
189
    /**
190
     * Get the channel which the message should be sent to.
191
     *
192
     * @return string
193
     */
194 11
    public function getChannel()
195
    {
196 11
        return $this->channel;
197
    }
198
199
    /**
200
     * Set the channel which the message should be sent to.
201
     *
202
     * @param  string  $channel
203
     * @return $this
204
     */
205 6
    public function setChannel($channel)
206
    {
207 6
        $this->removeTarget();
208
209 6
        if ($channel) {
210 6
            $this->channel = (string) $channel;
211
        }
212
213 6
        return $this;
214
    }
215
216
    /**
217
     * Set the channel which the message should be sent to.
218
     *
219
     * @param  string  $channel
220
     * @return $this
221
     */
222 4
    public function channel($channel)
223
    {
224 4
        return $this->setChannel($channel);
225
    }
226
227
    /**
228
     * Get the user which the message should be sent to.
229
     *
230
     * @return string
231
     */
232 11
    public function getUser()
233
    {
234 11
        return $this->user;
235
    }
236
237
    /**
238
     * Set the user which the message should be sent to.
239
     *
240
     * @param  string  $user
241
     * @return $this
242
     */
243 10
    public function setUser($user)
244
    {
245 10
        $this->removeTarget();
246
247 10
        if ($user) {
248 10
            $this->user = (string) $user;
249
        }
250
251 10
        return $this;
252
    }
253
254
    /**
255
     * Set the user which the message should be sent to.
256
     *
257
     * @param  string  $user
258
     * @return $this
259
     */
260 4
    public function user($user)
261
    {
262 4
        return $this->setUser($user);
263
    }
264
265
    /**
266
     * Get the target that the message should be sent to:
267
     * `#channel` or `@user` or null.
268
     *
269
     * @return string
270
     */
271 4
    public function getTarget()
272
    {
273 4
        if ($this->channel) {
274 1
            return '#'.$this->channel;
275
        }
276
277 4
        if ($this->user) {
278 2
            return '@'.$this->user;
279
        }
280 4
    }
281
282
    /**
283
     * Set the target (user or channel) that the message should be sent to.
284
     *
285
     * @param  string  $target  @user, #channel, channel, null
286
     * @return $this
287
     */
288 3
    public function setTarget($target)
289
    {
290 3
        $this->removeTarget();
291
292 3
        if ($target = (string) $target) {
293 3
            $mark = mb_substr($target, 0, 1);
294 3
            $to = mb_substr($target, 1);
295
296 3
            if ($mark === '@') {
297 3
                $this->setUser($to);
298 2
            } elseif ($mark === '#') {
299 1
                $this->setChannel($to);
300
            } else {
301 2
                $this->setChannel($target);
302
            }
303
        }
304
305 3
        return $this;
306
    }
307
308
    /**
309
     * Remove the target, then this message will be sent to
310
     * the webhook defined target.
311
     *
312
     * @return $this
313
     */
314 10
    public function removeTarget()
315
    {
316 10
        $this->channel = $this->user = null;
317
318 10
        return $this;
319
    }
320
321
    /**
322
     * Set the target.
323
     *
324
     * @param  string  $target
325
     * @return $this
326
     */
327 1
    public function target($target)
328
    {
329 1
        return $this->setTarget($target);
330
    }
331
332
    /**
333
     * Set the target.
334
     *
335
     * @param  string  $target
336
     * @return $this
337
     */
338 3
    public function to($target)
339
    {
340 3
        return $this->setTarget($target);
341
    }
342
343
    /**
344
     * Get the attachments defaults.
345
     *
346
     * @return array
347
     */
348 1
    public function getAttachmentDefaults()
349
    {
350 1
        return $this->attachmentDefaults;
351
    }
352
353
    /**
354
     * Set the attachments defaults.
355
     *
356
     * @param  array  $defaults
357
     * @return $this
358
     */
359 8
    public function setAttachmentDefaults($defaults)
360
    {
361 8
        if ($this->attachmentDefaults != ($defaults = (array) $defaults)) {
362 5
            $this->attachmentDefaults = $defaults;
363
364 5
            $this->setAttachments($this->attachments);
365
        }
366
367 8
        return $this;
368
    }
369
370
    /**
371
     * Get the attachments for the message.
372
     *
373
     * @return array
374
     */
375 11
    public function getAttachments()
376
    {
377 11
        return $this->attachments;
378
    }
379
380
    /**
381
     * Set the attachments for the message.
382
     *
383
     * @param  mixed  $attachments
384
     * @return $this
385
     */
386 6
    public function setAttachments($attachments)
387
    {
388 6
        $this->removeAttachments();
389
390 6
        if (is_array($attachments)) {
391 6
            foreach ($attachments as $attachment) {
392 3
                $this->addAttachment($attachment);
393
            }
394
        }
395
396 6
        return $this;
397
    }
398
399
    /**
400
     * Set the attachments for the message.
401
     *
402
     * @param  mixed  $attachments
403
     * @return $this
404
     */
405 1
    public function attachments($attachments)
406
    {
407 1
        return $this->setAttachments($attachments);
408
    }
409
410
    /**
411
     * Add an attachment to the message.
412
     *
413
     * The parameter can be an payload array that contains all of attachment's fields.
414
     * The parameters can also be attachment's fields that in order of
415
     * text, title, images and color. Except the text, other parameters
416
     * can be ignored.
417
     *
418
     * @param  mixed  $attachment
419
     * @return $this
420
     */
421 10
    public function addAttachment($attachment)
422
    {
423 10
        if (! is_array($attachment)) {
424 9
            $attachment = call_user_func_array([$this, 'getAttachmentPayload'], func_get_args());
425
        } elseif (
426 4
            ! empty($attachment['images']) &&
427 4
            $images = $this->getImagesPayload($attachment['images'])
428
        ) {
429 1
            $attachment['images'] = $images;
430
        }
431
432 10
        if (! empty($attachment)) {
433 10
            $attachment += $this->attachmentDefaults;
434
435 10
            $this->attachments[] = $attachment;
436
        }
437
438 10
        return $this;
439
    }
440
441
    /**
442
     * Get payload for an attachment.
443
     *
444
     * @param  mixed  $text
445
     * @param  mixed  $title
446
     * @param  mixed  $images
447
     * @param  mixed  $color
448
     * @return array
449
     */
450 9
    protected function getAttachmentPayload($text = null, $title = null, $images = null, $color = null)
451
    {
452 9
        $attachment = [];
453
454 9
        if ($text) {
455 9
            $attachment['text'] = $this->stringValue($text);
456
        }
457
458 9
        if ($title) {
459 5
            $attachment['title'] = $this->stringValue($title);
460
        }
461
462 9
        if ($images = $this->getImagesPayload($images)) {
463 4
            $attachment['images'] = $images;
464
        }
465
466 9
        if ($color) {
467 3
            $attachment['color'] = (string) $color;
468
        }
469
470 9
        return $attachment;
471
    }
472
473
    /**
474
     * Get payload for images.
475
     *
476
     * @param  mixed  $value
477
     * @return array
478
     */
479 9
    protected function getImagesPayload($value)
480
    {
481 9
        $images = [];
482
483 9
        foreach ((array) $value as $img) {
484 4
            if (! empty($img['url'])) {
485
                $img = $img['url'];
486
            }
487
488 4
            if (is_string($img) && ! empty($img)) {
489 4
                $images[] = ['url' => $img];
490
            }
491
        }
492
493 9
        return $images;
494
    }
495
496
    /**
497
     * Convert any type to string.
498
     *
499
     * @param  mixed  $value
500
     * @param  int  $jsonOptions
501
     * @return string
502
     */
503 9
    protected function stringValue($value, $jsonOptions = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
504
    {
505 9
        if (is_string($value)) {
506 9
            return $value;
507
        }
508
509 1
        if (method_exists($value, '__toString')) {
510
            return (string) $value;
511
        }
512
513 1
        if (method_exists($value, 'toArray')) {
514
            $value = $value->toArray();
515
        }
516
517 1
        return json_encode($value, $jsonOptions);
518
    }
519
520
    /**
521
     * Add an attachment to the message.
522
     * It alias to `addAttachment`.
523
     *
524
     * @return $this
525
     */
526 6
    public function add()
527
    {
528 6
        return call_user_func_array([$this, 'addAttachment'], func_get_args());
529
    }
530
531
    /**
532
     * Add an image attachment to the message.
533
     *
534
     * @param  string|string[]  $image
535
     * @param  string  $desc
536
     * @param  string  $title
537
     * @return $this
538
     */
539 1
    public function addImage($image, $desc = null, $title = null)
540
    {
541 1
        return $this->addAttachment($desc, $title, $image);
542
    }
543
544
    /**
545
     * Remove attachment[s] for the message.
546
     *
547
     * @return $this
548
     */
549 7
    public function removeAttachments()
550
    {
551 7
        if (func_num_args() > 0) {
552 1
            $indices = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args();
553
554 1
            foreach ($indices as $index) {
555 1
                unset($this->attachments[$index]);
556
            }
557
558 1
            $this->attachments = array_values($this->attachments);
559
        } else {
560 7
            $this->attachments = [];
561
        }
562
563 7
        return $this;
564
    }
565
566
    /**
567
     * Remove attachment[s] for the message.
568
     * It alias to `removeAttachments`.
569
     *
570
     * @return $this
571
     */
572 1
    public function remove()
573
    {
574 1
        return call_user_func_array([$this, 'removeAttachments'], func_get_args());
575
    }
576
577
    /**
578
     * Configure message defaults.
579
     *
580
     * @param  array  $defaults
581
     * @param  bool  $force
582
     * @return $this
583
     */
584 6
    public function configureDefaults(array $defaults, $force = false)
585
    {
586 6
        if ($force || empty($this->toArray())) {
587 6
            $attachmentDefaults = $this->attachmentDefaults;
588
589 6
            foreach (MessageDefaults::allKeys() as $key) {
590 6
                if (isset($defaults[$key]) && ! is_null($value = $defaults[$key])) {
591 3
                    if (strpos($key, 'attachment_') !== false) {
592 3
                        if ($key = substr($key, strlen('attachment_'))) {
593 3
                            $attachmentDefaults[$key] = $value;
594
                        }
595
                    } else {
596 6
                        $this->fillDefaults($key, $value);
597
                    }
598
                }
599
            }
600
601 6
            $this->setAttachmentDefaults($attachmentDefaults);
602
        }
603
604 6
        return $this;
605
    }
606
607
    /**
608
     * Fill with message defaults.
609
     *
610
     * @param  string  $key
611
     * @param  mixed  $value
612
     * @return void
613
     */
614 3
    protected function fillDefaults($key, $value)
615
    {
616
        if (
617 3
            ($key === MessageDefaults::USER || $key === MessageDefaults::CHANNEL) &&
618 3
            (! is_null($this->getTarget()))
619
        ) {
620 1
            return;
621
        }
622
623 3
        if ($suffix = $this->studlyCase($key)) {
624 3
            $getMethod = 'get'.$suffix;
625 3
            $setMethod = 'set'.$suffix;
626
            if (
627 3
                method_exists($this, $getMethod) &&
628 3
                is_null($this->{$getMethod}()) &&
629 3
                method_exists($this, $setMethod)
630
            ) {
631 3
                $this->{$setMethod}($value);
632
            }
633
        }
634 3
    }
635
636
    /**
637
     * Convert a string to studly caps case.
638
     *
639
     * @param  string  $string
640
     * @return string
641
     */
642 3
    protected function studlyCase($string)
643
    {
644 3
        return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $string)));
645
    }
646
647
    /**
648
     * Conveniently set message content.
649
     *
650
     * The parameters may be:
651
     * `($text, $markdown, $notification)`
652
     * or `($text, $attachment_text, $attachment_title, $attachment_images, $attachment_color)`.
653
     *
654
     * @return $this
655
     */
656 3
    public function content()
657
    {
658 3
        $arguments = func_get_args();
659 3
        $count = count($arguments);
660
661 3
        if ($count > 0) {
662 3
            $this->setText($arguments[0]);
663
        }
664
665 3
        if ($count > 1) {
666 3
            if (is_bool($arguments[1])) {
667 3
                $this->setMarkdown($arguments[1]);
668
669 3
                if ($count > 2) {
670 3
                    $this->setNotification($arguments[2]);
671
                }
672
            } else {
673 2
                call_user_func_array([$this, 'addAttachment'], array_slice($arguments, 1));
674
            }
675
        }
676
677 3
        return $this;
678
    }
679
680
    /**
681
     * Convert the message to an array.
682
     *
683
     * @return array
684
     */
685 7
    public function toArray()
686
    {
687 7
        return array_filter(
688
            [
689 7
                'text' => $this->getText(),
690 7
                'notification' => $this->getNotification(),
691 7
                'markdown' => $this->getMarkdown(),
692 7
                'channel' => $this->getChannel(),
693 7
                'user' => $this->getUser(),
694 7
                'attachments' => $this->getAttachments(),
695
            ],
696 7
            function ($value, $key) {
697
                return ! (
698 7
                    is_null($value) ||
699 7
                    ($key === 'markdown' && $value === true) ||
700 7
                    (is_array($value) && empty($value))
701
                );
702 7
            },
703 7
            ARRAY_FILTER_USE_BOTH
704
        );
705
    }
706
707
    /**
708
     * Convert the message to JSON string.
709
     *
710
     * @param  int  $options
711
     * @return string
712
     */
713 1
    public function toJson($options = 0)
714
    {
715 1
        return json_encode($this->jsonSerialize(), $options);
716
    }
717
718
    /**
719
     * Serializes the object to a value that can be serialized natively by json_encode().
720
     *
721
     * @return array
722
     */
723 1
    public function jsonSerialize()
724
    {
725 1
        return $this->toArray();
726
    }
727
728
    /**
729
     * Send the message.
730
     *
731
     * The parameters accepts the same format of `content` method.
732
     *
733
     * @return bool
734
     */
735 2
    public function send()
736
    {
737 2
        if (! $this->client) {
738 1
            return false;
739
        }
740
741
        if (
742 2
            1 == func_num_args() &&
743 2
            (is_array(func_get_arg(0)) || is_object(func_get_arg(0)))
744
        ) {
745 1
            return $this->client->sendMessage(func_get_arg(0));
746
        }
747
748 2
        if (func_num_args() > 0) {
749 2
            call_user_func_array([$this, 'content'], func_get_args());
750
        }
751
752 2
        return $this->client->sendMessage($this);
753
    }
754
755
    /**
756
     * Send the message to the given target.
757
     *
758
     * @param  mixed  $target
759
     * @return bool
760
     */
761 1
    public function sendTo($target)
762
    {
763 1
        $this->to($target);
764
765 1
        return call_user_func_array([$this, 'send'], array_slice(func_get_args(), 1));
766
    }
767
768
    /**
769
     * Convert the message to its string representation.
770
     *
771
     * @return string
772
     */
773 1
    public function __toString()
774
    {
775 1
        return $this->toJson();
776
    }
777
}
778