Completed
Branch master (6434aa)
by Elf
06:56
created

Message::remove()   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 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 18
    public function __construct(Client $client = null)
71
    {
72 18
        if ($this->client = $client) {
73 4
            $this->configureDefaults($client->getMessageDefaults());
74
        }
75 18
    }
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 6
    public function getText()
93
    {
94 6
        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 6
    public function getNotification()
127
    {
128 6
        return $this->notification;
129
    }
130
131
    /**
132
     * Set the notification.
133
     *
134
     * @param  string  $notification
135
     * @return $this
136
     */
137 3
    public function setNotification($notification)
138
    {
139 3
        $this->notification = $notification ? (string) $notification : null;
140
141 3
        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 6
    public function getMarkdown()
161
    {
162 6
        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 7
    public function getChannel()
195
    {
196 7
        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 3
    public function setChannel($channel)
206
    {
207 3
        $this->channel = $channel ? (string) $channel : null;
208
209 3
        return $this;
210
    }
211
212
    /**
213
     * Set the channel which the message should be sent to.
214
     *
215
     * @param  string  $channel
216
     * @return $this
217
     */
218 1
    public function channel($channel)
219
    {
220 1
        return $this->setChannel($channel);
221
    }
222
223
    /**
224
     * Get the user which the message should be sent to.
225
     *
226
     * @return string
227
     */
228 7
    public function getUser()
229
    {
230 7
        return $this->user;
231
    }
232
233
    /**
234
     * Set the user which the message should be sent to.
235
     *
236
     * @param  string  $user
237
     * @return $this
238
     */
239 6
    public function setUser($user)
240
    {
241 6
        $this->user = $user ? (string) $user : null;
242
243 6
        return $this;
244
    }
245
246
    /**
247
     * Set the user which the message should be sent to.
248
     *
249
     * @param  string  $user
250
     * @return $this
251
     */
252 1
    public function user($user)
253
    {
254 1
        return $this->setUser($user);
255
    }
256
257
    /**
258
     * Set the target (user or channel) that the message should be sent to.
259
     *
260
     * The target may be started with '@' for sending to user, and the channel's
261
     * starter mark '#' is optional.
262
     *
263
     * It will remove all targets if the given target is null.
264
     *
265
     * @param  string  $target
266
     * @return $this
267
     */
268 3
    public function to($target)
269
    {
270 3
        $this->channel = $this->user = null;
271
272 3
        if (! empty($target)) {
273 3
            $target = (string) $target;
274
275 3
            $mark = mb_substr($target, 0, 1);
276 3
            $to = mb_substr($target, 1);
277
278 3
            if ($mark === '@' && ! empty($to)) {
279 3
                $this->setUser($to);
280 2
            } elseif ($mark === '#' && ! empty($to)) {
281 1
                $this->setChannel($to);
282
            } else {
283 2
                $this->setChannel($target);
284
            }
285
        }
286
287 3
        return $this;
288
    }
289
290
    /**
291
     * Get the attachments for the message.
292
     *
293
     * @return array
294
     */
295 9
    public function getAttachments()
296
    {
297 9
        return $this->attachments;
298
    }
299
300
    /**
301
     * Set the attachments for the message.
302
     *
303
     * @param  mixed  $attachments
304
     * @return $this
305
     */
306 1
    public function setAttachments($attachments)
307
    {
308 1
        $this->removeAttachments();
309
310 1
        if (is_array($attachments)) {
311 1
            foreach ($attachments as $attachment) {
312 1
                $this->addAttachment($attachment);
313
            }
314
        }
315
316 1
        return $this;
317
    }
318
319
    /**
320
     * Set the attachments for the message.
321
     *
322
     * @param  mixed  $attachments
323
     * @return $this
324
     */
325
    public function attachments($attachments)
326
    {
327
        return $this->setAttachments($attachments);
328
    }
329
330
    /**
331
     * Add an attachment to the message.
332
     *
333
     * The parameter can be an payload array that contains all of attachment's fields.
334
     * The parameters can also be attachment's fields that in order of
335
     * text, title, images and color. Except the text, other parameters
336
     * can be ignored.
337
     *
338
     * @param  mixed  $attachment
339
     * @return $this
340
     */
341 8
    public function addAttachment($attachment)
342
    {
343 8
        if (! is_array($attachment)) {
344 7
            $attachment = $this->getAttachmentPayloadFromArguments(func_get_args());
345
        }
346
347 8
        if (! empty($attachment)) {
348 8
            $attachment += $this->attachmentDefaults;
349
350 8
            $this->attachments[] = $attachment;
351
        }
352
353 8
        return $this;
354
    }
355
356
    /**
357
     * Convert arguments list to attachment payload.
358
     *
359
     * @param  array  $arguments
360
     * @return array
361
     */
362 7
    protected function getAttachmentPayloadFromArguments($arguments)
363
    {
364 7
        $attachment = [];
365
366 7
        foreach ($arguments as $index => $value) {
367 7
            if (empty($value)) {
368 2
                continue;
369
            }
370
371 7
            if ($index === 0) {
372 7
                $attachment['text'] = $this->stringValue($value);
373 3
            } elseif ($index === 1) {
374 2
                $attachment['title'] = $this->stringValue($value);
375 3
            } elseif ($index === 2) {
376 3
                $images = [];
377 3
                foreach ((array) $value as $img) {
378 3
                    if (is_array($img) && isset($img['url'])) {
379
                        $img = $img['url'];
380
                    }
381 3
                    if (is_string($img) && ! empty($img)) {
382 3
                        $images[] = ['url' => $img];
383
                    }
384
                }
385 3
                if (! empty($images)) {
386 3
                    $attachment['images'] = $images;
387
                }
388 2
            } elseif ($index === 3) {
389 7
                $attachment['color'] = (string) $value;
390
            }
391
        }
392
393 7
        return $attachment;
394
    }
395
396
    /**
397
     * Get the attachments' defaults.
398
     *
399
     * @return array
400
     */
401 1
    public function getAttachmentDefaults()
402
    {
403 1
        return $this->attachmentDefaults;
404
    }
405
406
    /**
407
     * Set the attachments' defaults.
408
     *
409
     * @param  array  $defaults
410
     * @return $this
411
     */
412 2
    public function setAttachmentDefaults(array $defaults)
413
    {
414 2
        $this->attachmentDefaults = $defaults;
415
416 2
        return $this;
417
    }
418
419
    /**
420
     * Add an attachment to the message.
421
     * It alias to `addAttachment`.
422
     *
423
     * @return $this
424
     */
425 4
    public function add()
426
    {
427 4
        return call_user_func_array([$this, 'addAttachment'], func_get_args());
428
    }
429
430
    /**
431
     * Add an image attachment to the message.
432
     *
433
     * @param  string|string[]  $image
434
     * @param  string  $desc
435
     * @return $this
436
     */
437 1
    public function addImage($image, $desc = null)
438
    {
439 1
        return $this->addAttachment($desc, null, $image);
440
    }
441
442
    /**
443
     * Remove attachment[s] for the message.
444
     *
445
     * @return $this
446
     */
447 2
    public function removeAttachments()
448
    {
449 2
        if (func_num_args() > 0) {
450 1
            $indices = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args();
451
452 1
            foreach ($indices as $index) {
453 1
                unset($this->attachments[$index]);
454
            }
455
456 1
            $this->attachments = array_values($this->attachments);
457
        } else {
458 2
            $this->attachments = [];
459
        }
460
461 2
        return $this;
462
    }
463
464
    /**
465
     * Remove attachment[s] for the message.
466
     * It alias to `removeAttachments`.
467
     *
468
     * @return $this
469
     */
470 1
    public function remove()
471
    {
472 1
        return call_user_func_array([$this, 'removeAttachments'], func_get_args());
473
    }
474
475
    /**
476
     * Configure message defaults.
477
     *
478
     * @param  array  $defaults
479
     */
480 4
    protected function configureDefaults(array $defaults)
481
    {
482 4
        if (isset($defaults[MessageDefaults::CHANNEL])) {
483
            $this->setChannel($defaults[MessageDefaults::CHANNEL]);
484
        }
485 4
        if (isset($defaults[MessageDefaults::USER])) {
486 2
            $this->setUser($defaults[MessageDefaults::USER]);
487
        }
488 4
        if (isset($defaults[MessageDefaults::MARKDOWN])) {
489
            $this->setMarkdown($defaults[MessageDefaults::MARKDOWN]);
490
        }
491 4
        if (isset($defaults[MessageDefaults::NOTIFICATION])) {
492 2
            $this->setNotification($defaults[MessageDefaults::NOTIFICATION]);
493
        }
494 4
        if (isset($defaults[MessageDefaults::ATTACHMENT_COLOR])) {
495 2
            $this->attachmentDefaults['color'] = $defaults[MessageDefaults::ATTACHMENT_COLOR];
496
        }
497 4
    }
498
499
    /**
500
     * Convert any type to string.
501
     *
502
     * @param  mixed  $value
503
     * @param  int  $jsonOptions
504
     * @return string
505
     */
506 7
    protected function stringValue($value, $jsonOptions = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
507
    {
508 7
        if (is_object($value)) {
509
            if (method_exists($value, '__toString')) {
510
                return (string) $value;
511
            }
512
513
            if (method_exists($value, 'toArray')) {
514
                $value = $value->toArray();
515
            }
516
        }
517
518 7
        return is_string($value) ? $value : json_encode($value, $jsonOptions);
519
    }
520
521
    /**
522
     * Convert the message to an array.
523
     *
524
     * @return array
525
     */
526 5
    public function toArray()
527
    {
528 5
        return array_filter(
529
            [
530 5
                'text' => $this->getText(),
531 5
                'notification' => $this->getNotification(),
532 5
                'markdown' => $this->getMarkdown(),
533 5
                'channel' => $this->getChannel(),
534 5
                'user' => $this->getUser(),
535 5
                'attachments' => $this->getAttachments(),
536
            ],
537 5
            function ($value, $key) {
538
                return ! (
539 5
                    is_null($value) ||
540 5
                    ($key === 'markdown' && $value === true) ||
541 5
                    (is_array($value) && empty($value))
542
                );
543 5
            },
544 5
            ARRAY_FILTER_USE_BOTH
545
        );
546
    }
547
548
    /**
549
     * Convert the message to JSON string.
550
     *
551
     * @param  int  $options
552
     * @return string
553
     */
554
    public function toJson($options = 0)
555
    {
556
        return json_encode($this->jsonSerialize(), $options);
557
    }
558
559
    /**
560
     * Serializes the object to a value that can be serialized natively by json_encode().
561
     *
562
     * @return array
563
     */
564
    public function jsonSerialize()
565
    {
566
        return $this->toArray();
567
    }
568
569
    /**
570
     * Send the message.
571
     *
572
     * The parameters can be `($text, $markdown, $notification)`, and the $text and
573
     * the $notification can be `null` that does not modify the exist field.
574
     * The parameters can also be
575
     * `($text, $attachment_text, $attachment_title, $attachment_images, $attachment_color)`.
576
     *
577
     * @return bool
578
     */
579 2
    public function send()
580
    {
581 2
        if (! $this->client) {
582 1
            return false;
583
        }
584
585 2
        if ($count = func_num_args()) {
586 2
            $firstArg = func_get_arg(0);
587
588 2
            if (1 === $count && (is_array($firstArg) || is_object($firstArg))) {
589 1
                return $this->client->sendMessage($firstArg);
590
            }
591
592 2
            if (! is_null($firstArg)) {
593 2
                $this->setText($firstArg);
594
            }
595
596 2
            if ($count > 1 && is_bool(func_get_arg(1))) {
597 2
                $this->setMarkdown(func_get_arg(1));
598
599 2
                if ($count > 2 && ! is_null(func_get_arg(2))) {
600 2
                    $this->setNotification(func_get_arg(2));
601
                }
602 1
            } elseif ($count > 1) {
603 1
                call_user_func_array(
604 1
                    [$this, 'addAttachment'],
605 1
                    array_slice(func_get_args(), 1)
606
                );
607
            }
608
        }
609
610 2
        return $this->client->sendMessage($this);
611
    }
612
613
    /**
614
     * Send the message to the given target.
615
     *
616
     * @param  mixed  $target
617
     * @return bool
618
     */
619 1
    public function sendTo($target)
620
    {
621 1
        $this->to($target);
622
623 1
        return call_user_func_array([$this, 'send'], array_slice(func_get_args(), 1));
624
    }
625
626
    /**
627
     * Convert the message to its string representation.
628
     *
629
     * @return string
630
     */
631
    public function __toString()
632
    {
633
        return $this->toJson();
634
    }
635
}
636