Completed
Push — master ( edf678...899fcf )
by Elf
01:24
created

Message::target()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
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 21
    public function __construct(Client $client = null)
71
    {
72 21
        if ($this->client = $client) {
73 4
            $this->configureDefaults($client->getMessageDefaults(), true);
74 4
        }
75 21
    }
76
77
    /**
78
     * Get the BearyChat client for sending message.
79
     *
80
     * @return \ElfSundae\BearyChat\Client
81
     */
82 1
    public function getClient()
83
    {
84 1
        return $this->client;
85
    }
86
87
    /**
88
     * Get the text.
89
     *
90
     * @return string
91
     */
92 7
    public function getText()
93
    {
94 7
        return $this->text;
95
    }
96
97
    /**
98
     * Set the text.
99
     *
100
     * @param  string  $text
101
     * @return $this
102
     */
103 5
    public function setText($text)
104
    {
105 5
        $this->text = $text ? (string) $text : null;
106
107 5
        return $this;
108
    }
109
110
    /**
111
     * Set the text.
112
     *
113
     * @param  string  $text
114
     * @return $this
115
     */
116 3
    public function text($text)
117
    {
118 3
        return $this->setText($text);
119
    }
120
121
    /**
122
     * Get the notification.
123
     *
124
     * @return string
125
     */
126 7
    public function getNotification()
127
    {
128 7
        return $this->notification;
129
    }
130
131
    /**
132
     * Set the notification.
133
     *
134
     * @param  string  $notification
135
     * @return $this
136
     */
137 4
    public function setNotification($notification)
138
    {
139 4
        $this->notification = $notification ? (string) $notification : null;
140
141 4
        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 7
    public function getMarkdown()
161
    {
162 7
        return $this->markdown;
163
    }
164
165
    /**
166
     * Set the markdown.
167
     *
168
     * @param  bool $markdown
169
     * @return $this
170
     */
171 3
    public function setMarkdown($markdown)
172
    {
173 3
        $this->markdown = (bool) $markdown;
174
175 3
        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 10
    public function getChannel()
195
    {
196 10
        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 6
        }
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 10
    public function getUser()
233
    {
234 10
        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 10
        }
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 1
    public function getTarget()
272
    {
273 1
        if ($this->channel) {
274 1
            return '#'.$this->channel;
275
        }
276
277 1
        if ($this->user) {
278 1
            return '@'.$this->user;
279
        }
280 1
    }
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 3
            } elseif ($mark === '#') {
299 1
                $this->setChannel($to);
300 1
            } else {
301 2
                $this->setChannel($target);
302
            }
303 3
        }
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 2
    public function setAttachmentDefaults($defaults)
360
    {
361 2
        $this->attachmentDefaults = (array) $defaults;
362
363 2
        return $this;
364
    }
365
366
    /**
367
     * Get the attachments for the message.
368
     *
369
     * @return array
370
     */
371 10
    public function getAttachments()
372
    {
373 10
        return $this->attachments;
374
    }
375
376
    /**
377
     * Set the attachments for the message.
378
     *
379
     * @param  mixed  $attachments
380
     * @return $this
381
     */
382 3
    public function setAttachments($attachments)
383
    {
384 3
        $this->removeAttachments();
385
386 3
        if (is_array($attachments)) {
387 3
            foreach ($attachments as $attachment) {
388 1
                $this->addAttachment($attachment);
389 3
            }
390 3
        }
391
392 3
        return $this;
393
    }
394
395
    /**
396
     * Set the attachments for the message.
397
     *
398
     * @param  mixed  $attachments
399
     * @return $this
400
     */
401
    public function attachments($attachments)
402
    {
403
        return $this->setAttachments($attachments);
404
    }
405
406
    /**
407
     * Add an attachment to the message.
408
     *
409
     * The parameter can be an payload array that contains all of attachment's fields.
410
     * The parameters can also be attachment's fields that in order of
411
     * text, title, images and color. Except the text, other parameters
412
     * can be ignored.
413
     *
414
     * @param  mixed  $attachment
415
     * @return $this
416
     */
417 8
    public function addAttachment($attachment)
418
    {
419 8
        if (! is_array($attachment)) {
420 7
            $attachment = $this->getAttachmentPayloadFromArguments(func_get_args());
421 7
        }
422
423 8
        if (! empty($attachment)) {
424 8
            $attachment += $this->attachmentDefaults;
425
426 8
            $this->attachments[] = $attachment;
427 8
        }
428
429 8
        return $this;
430
    }
431
432
    /**
433
     * Convert arguments list to attachment payload.
434
     *
435
     * @param  array  $arguments
436
     * @return array
437
     */
438 7
    protected function getAttachmentPayloadFromArguments($arguments)
439
    {
440 7
        $attachment = [];
441
442 7
        foreach ($arguments as $index => $value) {
443 7
            if (empty($value)) {
444 2
                continue;
445
            }
446
447 7
            if ($index === 0) {
448 7
                $attachment['text'] = $this->stringValue($value);
449 7
            } elseif ($index === 1) {
450 2
                $attachment['title'] = $this->stringValue($value);
451 3
            } elseif ($index === 2) {
452 3
                $images = [];
453 3
                foreach ((array) $value as $img) {
454 3
                    if (is_array($img) && isset($img['url'])) {
455
                        $img = $img['url'];
456
                    }
457 3
                    if (is_string($img) && ! empty($img)) {
458 3
                        $images[] = ['url' => $img];
459 3
                    }
460 3
                }
461 3
                if (! empty($images)) {
462 3
                    $attachment['images'] = $images;
463 3
                }
464 3
            } elseif ($index === 3) {
465 2
                $attachment['color'] = (string) $value;
466 2
            }
467 7
        }
468
469 7
        return $attachment;
470
    }
471
472
    /**
473
     * Convert any type to string.
474
     *
475
     * @param  mixed  $value
476
     * @param  int  $jsonOptions
477
     * @return string
478
     */
479 7
    protected function stringValue($value, $jsonOptions = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
480
    {
481 7
        if (is_object($value)) {
482
            if (method_exists($value, '__toString')) {
483
                return (string) $value;
484
            }
485
486
            if (method_exists($value, 'toArray')) {
487
                $value = $value->toArray();
488
            }
489
        }
490
491 7
        return is_string($value) ? $value : json_encode($value, $jsonOptions);
492
    }
493
494
    /**
495
     * Add an attachment to the message.
496
     * It alias to `addAttachment`.
497
     *
498
     * @return $this
499
     */
500 4
    public function add()
501
    {
502 4
        return call_user_func_array([$this, 'addAttachment'], func_get_args());
503
    }
504
505
    /**
506
     * Add an image attachment to the message.
507
     *
508
     * @param  string|string[]  $image
509
     * @param  string  $desc
510
     * @return $this
511
     */
512 1
    public function addImage($image, $desc = null)
513
    {
514 1
        return $this->addAttachment($desc, null, $image);
515
    }
516
517
    /**
518
     * Remove attachment[s] for the message.
519
     *
520
     * @return $this
521
     */
522 4
    public function removeAttachments()
523
    {
524 4
        if (func_num_args() > 0) {
525 1
            $indices = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args();
526
527 1
            foreach ($indices as $index) {
528 1
                unset($this->attachments[$index]);
529 1
            }
530
531 1
            $this->attachments = array_values($this->attachments);
532 1
        } else {
533 4
            $this->attachments = [];
534
        }
535
536 4
        return $this;
537
    }
538
539
    /**
540
     * Remove attachment[s] for the message.
541
     * It alias to `removeAttachments`.
542
     *
543
     * @return $this
544
     */
545 1
    public function remove()
546
    {
547 1
        return call_user_func_array([$this, 'removeAttachments'], func_get_args());
548
    }
549
550
    /**
551
     * Configure message defaults.
552
     *
553
     * @param  array  $defaults
554
     * @param  bool  $force
555
     * @return $this
556
     */
557 5
    public function configureDefaults(array $defaults, $force = false)
558
    {
559 5
        if (! $force && ! empty($this->toArray())) {
560 1
            return $this;
561
        }
562
563 5
        $attachmentDefaults = $this->attachmentDefaults;
564
565 5
        foreach (MessageDefaults::allKeys() as $key) {
566 5
            if (! isset($defaults[$key]) || is_null($value = $defaults[$key])) {
567 5
                continue;
568
            }
569
570 3
            if (strpos($key, 'attachment_') !== false) {
571 2
                if ($key = substr($key, strlen('attachment_'))) {
572 2
                    $attachmentDefaults[$key] = $value;
573 2
                }
574 2
            } else {
575 3
                if ($suffix = $this->studlyCase($key)) {
576 3
                    $getMethod = 'get'.$suffix;
577 3
                    $setMethod = 'set'.$suffix;
578
                    if (
579 3
                        method_exists($this, $getMethod) &&
580 3
                        is_null($this->{$getMethod}()) &&
581 3
                        method_exists($this, $setMethod)
582 3
                    ) {
583 3
                        $this->{$setMethod}($value);
584 3
                    }
585 3
                }
586
            }
587 5
        }
588
589 5
        if ($attachmentDefaults != $this->attachmentDefaults) {
590 2
            $this->attachmentDefaults = $attachmentDefaults;
591 2
            $this->setAttachments($this->attachments);
592 2
        }
593
594 5
        return $this;
595
    }
596
597
    /**
598
     * Convert a string to studly caps case.
599
     *
600
     * @param  string  $string
601
     * @return string
602
     */
603 3
    protected function studlyCase($string)
604
    {
605 3
        return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $string)));
606
    }
607
608
    /**
609
     * Convert the message to an array.
610
     *
611
     * @return array
612
     */
613 6
    public function toArray()
614
    {
615 6
        return array_filter(
616
            [
617 6
                'text' => $this->getText(),
618 6
                'notification' => $this->getNotification(),
619 6
                'markdown' => $this->getMarkdown(),
620 6
                'channel' => $this->getChannel(),
621 6
                'user' => $this->getUser(),
622 6
                'attachments' => $this->getAttachments(),
623 6
            ],
624 6
            function ($value, $key) {
625
                return ! (
626 6
                    is_null($value) ||
627 6
                    ($key === 'markdown' && $value === true) ||
628 6
                    (is_array($value) && empty($value))
629 6
                );
630 6
            },
631
            ARRAY_FILTER_USE_BOTH
632 6
        );
633
    }
634
635
    /**
636
     * Convert the message to JSON string.
637
     *
638
     * @param  int  $options
639
     * @return string
640
     */
641
    public function toJson($options = 0)
642
    {
643
        return json_encode($this->jsonSerialize(), $options);
644
    }
645
646
    /**
647
     * Serializes the object to a value that can be serialized natively by json_encode().
648
     *
649
     * @return array
650
     */
651
    public function jsonSerialize()
652
    {
653
        return $this->toArray();
654
    }
655
656
    /**
657
     * Send the message.
658
     *
659
     * The parameters can be `($text, $markdown, $notification)`, and the $text and
660
     * the $notification can be `null` that does not modify the exist field.
661
     * The parameters can also be
662
     * `($text, $attachment_text, $attachment_title, $attachment_images, $attachment_color)`.
663
     *
664
     * @return bool
665
     */
666 2
    public function send()
667
    {
668 2
        if (! $this->client) {
669 1
            return false;
670
        }
671
672 2
        if ($count = func_num_args()) {
673 2
            $firstArg = func_get_arg(0);
674
675 2
            if (1 === $count && (is_array($firstArg) || is_object($firstArg))) {
676 1
                return $this->client->sendMessage($firstArg);
677
            }
678
679 2
            if (! is_null($firstArg)) {
680 2
                $this->setText($firstArg);
681 2
            }
682
683 2
            if ($count > 1 && is_bool(func_get_arg(1))) {
684 2
                $this->setMarkdown(func_get_arg(1));
685
686 2
                if ($count > 2 && ! is_null(func_get_arg(2))) {
687 1
                    $this->setNotification(func_get_arg(2));
688 1
                }
689 2
            } elseif ($count > 1) {
690 1
                call_user_func_array(
691 1
                    [$this, 'addAttachment'],
692 1
                    array_slice(func_get_args(), 1)
693 1
                );
694 1
            }
695 2
        }
696
697 2
        return $this->client->sendMessage($this);
698
    }
699
700
    /**
701
     * Send the message to the given target.
702
     *
703
     * @param  mixed  $target
704
     * @return bool
705
     */
706 1
    public function sendTo($target)
707
    {
708 1
        $this->to($target);
709
710 1
        return call_user_func_array([$this, 'send'], array_slice(func_get_args(), 1));
711
    }
712
713
    /**
714
     * Convert the message to its string representation.
715
     *
716
     * @return string
717
     */
718
    public function __toString()
719
    {
720
        return $this->toJson();
721
    }
722
}
723