Completed
Push — master ( e9ed53...cdaf2c )
by Elf
01:23
created

Message::__toString()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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