Completed
Push — master ( 0d1874...edf678 )
by Elf
01:25
created

Message::configureDefaults()   C

Complexity

Conditions 13
Paths 15

Size

Total Lines 39
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 13

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 39
ccs 21
cts 21
cp 1
rs 5.1234
cc 13
eloc 23
nc 15
nop 2
crap 13

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 19
    public function __construct(Client $client = null)
71
    {
72 19
        if ($this->client = $client) {
73 4
            $this->configureDefaults($client->getMessageDefaults(), true);
74
        }
75 19
    }
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 8
    public function getChannel()
195
    {
196 8
        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 8
    public function getUser()
229
    {
230 8
        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 7
    public function setUser($user)
240
    {
241 7
        $this->user = $user ? (string) $user : null;
242
243 7
        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 defaults.
292
     *
293
     * @return array
294
     */
295 1
    public function getAttachmentDefaults()
296
    {
297 1
        return $this->attachmentDefaults;
298
    }
299
300
    /**
301
     * Set the attachments defaults.
302
     *
303
     * @param  array  $defaults
304
     * @return $this
305
     */
306 2
    public function setAttachmentDefaults($defaults)
307
    {
308 2
        $this->attachmentDefaults = (array) $defaults;
309
310 2
        return $this;
311
    }
312
313
    /**
314
     * Get the attachments for the message.
315
     *
316
     * @return array
317
     */
318 10
    public function getAttachments()
319
    {
320 10
        return $this->attachments;
321
    }
322
323
    /**
324
     * Set the attachments for the message.
325
     *
326
     * @param  mixed  $attachments
327
     * @return $this
328
     */
329 3
    public function setAttachments($attachments)
330
    {
331 3
        $this->removeAttachments();
332
333 3
        if (is_array($attachments)) {
334 3
            foreach ($attachments as $attachment) {
335 1
                $this->addAttachment($attachment);
336
            }
337
        }
338
339 3
        return $this;
340
    }
341
342
    /**
343
     * Set the attachments for the message.
344
     *
345
     * @param  mixed  $attachments
346
     * @return $this
347
     */
348
    public function attachments($attachments)
349
    {
350
        return $this->setAttachments($attachments);
351
    }
352
353
    /**
354
     * Add an attachment to the message.
355
     *
356
     * The parameter can be an payload array that contains all of attachment's fields.
357
     * The parameters can also be attachment's fields that in order of
358
     * text, title, images and color. Except the text, other parameters
359
     * can be ignored.
360
     *
361
     * @param  mixed  $attachment
362
     * @return $this
363
     */
364 8
    public function addAttachment($attachment)
365
    {
366 8
        if (! is_array($attachment)) {
367 7
            $attachment = $this->getAttachmentPayloadFromArguments(func_get_args());
368
        }
369
370 8
        if (! empty($attachment)) {
371 8
            $attachment += $this->attachmentDefaults;
372
373 8
            $this->attachments[] = $attachment;
374
        }
375
376 8
        return $this;
377
    }
378
379
    /**
380
     * Convert arguments list to attachment payload.
381
     *
382
     * @param  array  $arguments
383
     * @return array
384
     */
385 7
    protected function getAttachmentPayloadFromArguments($arguments)
386
    {
387 7
        $attachment = [];
388
389 7
        foreach ($arguments as $index => $value) {
390 7
            if (empty($value)) {
391 2
                continue;
392
            }
393
394 7
            if ($index === 0) {
395 7
                $attachment['text'] = $this->stringValue($value);
396 3
            } elseif ($index === 1) {
397 2
                $attachment['title'] = $this->stringValue($value);
398 3
            } elseif ($index === 2) {
399 3
                $images = [];
400 3
                foreach ((array) $value as $img) {
401 3
                    if (is_array($img) && isset($img['url'])) {
402
                        $img = $img['url'];
403
                    }
404 3
                    if (is_string($img) && ! empty($img)) {
405 3
                        $images[] = ['url' => $img];
406
                    }
407
                }
408 3
                if (! empty($images)) {
409 3
                    $attachment['images'] = $images;
410
                }
411 2
            } elseif ($index === 3) {
412 7
                $attachment['color'] = (string) $value;
413
            }
414
        }
415
416 7
        return $attachment;
417
    }
418
419
    /**
420
     * Convert any type to string.
421
     *
422
     * @param  mixed  $value
423
     * @param  int  $jsonOptions
424
     * @return string
425
     */
426 7
    protected function stringValue($value, $jsonOptions = JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
427
    {
428 7
        if (is_object($value)) {
429
            if (method_exists($value, '__toString')) {
430
                return (string) $value;
431
            }
432
433
            if (method_exists($value, 'toArray')) {
434
                $value = $value->toArray();
435
            }
436
        }
437
438 7
        return is_string($value) ? $value : json_encode($value, $jsonOptions);
439
    }
440
441
    /**
442
     * Add an attachment to the message.
443
     * It alias to `addAttachment`.
444
     *
445
     * @return $this
446
     */
447 4
    public function add()
448
    {
449 4
        return call_user_func_array([$this, 'addAttachment'], func_get_args());
450
    }
451
452
    /**
453
     * Add an image attachment to the message.
454
     *
455
     * @param  string|string[]  $image
456
     * @param  string  $desc
457
     * @return $this
458
     */
459 1
    public function addImage($image, $desc = null)
460
    {
461 1
        return $this->addAttachment($desc, null, $image);
462
    }
463
464
    /**
465
     * Remove attachment[s] for the message.
466
     *
467
     * @return $this
468
     */
469 4
    public function removeAttachments()
470
    {
471 4
        if (func_num_args() > 0) {
472 1
            $indices = is_array(func_get_arg(0)) ? func_get_arg(0) : func_get_args();
473
474 1
            foreach ($indices as $index) {
475 1
                unset($this->attachments[$index]);
476
            }
477
478 1
            $this->attachments = array_values($this->attachments);
479
        } else {
480 4
            $this->attachments = [];
481
        }
482
483 4
        return $this;
484
    }
485
486
    /**
487
     * Remove attachment[s] for the message.
488
     * It alias to `removeAttachments`.
489
     *
490
     * @return $this
491
     */
492 1
    public function remove()
493
    {
494 1
        return call_user_func_array([$this, 'removeAttachments'], func_get_args());
495
    }
496
497
    /**
498
     * Configure message defaults.
499
     *
500
     * @param  array  $defaults
501
     * @param  bool  $force
502
     * @return $this
503
     */
504 5
    public function configureDefaults(array $defaults, $force = false)
505
    {
506 5
        if (! $force && ! empty($this->toArray())) {
507 1
            return $this;
508
        }
509
510 5
        $attachmentDefaults = $this->attachmentDefaults;
511
512 5
        foreach (MessageDefaults::allKeys() as $key) {
513 5
            if (! isset($defaults[$key]) || is_null($value = $defaults[$key])) {
514 5
                continue;
515
            }
516
517 3
            if (strpos($key, 'attachment_') !== false) {
518 2
                if ($key = substr($key, strlen('attachment_'))) {
519 2
                    $attachmentDefaults[$key] = $value;
520
                }
521
            } else {
522 3
                if ($suffix = $this->studlyCase($key)) {
523 3
                    $getMethod = 'get'.$suffix;
524 3
                    $setMethod = 'set'.$suffix;
525
                    if (
526 3
                        method_exists($this, $getMethod) &&
527 3
                        is_null($this->{$getMethod}()) &&
528 3
                        method_exists($this, $setMethod)
529
                    ) {
530 3
                        $this->{$setMethod}($value);
531
                    }
532
                }
533
            }
534
        }
535
536 5
        if ($attachmentDefaults != $this->attachmentDefaults) {
537 2
            $this->attachmentDefaults = $attachmentDefaults;
538 2
            $this->setAttachments($this->attachments);
539
        }
540
541 5
        return $this;
542
    }
543
544
    /**
545
     * Convert a string to studly caps case.
546
     *
547
     * @param  string  $string
548
     * @return string
549
     */
550 3
    protected function studlyCase($string)
551
    {
552 3
        return str_replace(' ', '', ucwords(str_replace(['-', '_'], ' ', $string)));
553
    }
554
555
    /**
556
     * Convert the message to an array.
557
     *
558
     * @return array
559
     */
560 6
    public function toArray()
561
    {
562 6
        return array_filter(
563
            [
564 6
                'text' => $this->getText(),
565 6
                'notification' => $this->getNotification(),
566 6
                'markdown' => $this->getMarkdown(),
567 6
                'channel' => $this->getChannel(),
568 6
                'user' => $this->getUser(),
569 6
                'attachments' => $this->getAttachments(),
570
            ],
571 6
            function ($value, $key) {
572
                return ! (
573 6
                    is_null($value) ||
574 6
                    ($key === 'markdown' && $value === true) ||
575 6
                    (is_array($value) && empty($value))
576
                );
577 6
            },
578 6
            ARRAY_FILTER_USE_BOTH
579
        );
580
    }
581
582
    /**
583
     * Convert the message to JSON string.
584
     *
585
     * @param  int  $options
586
     * @return string
587
     */
588
    public function toJson($options = 0)
589
    {
590
        return json_encode($this->jsonSerialize(), $options);
591
    }
592
593
    /**
594
     * Serializes the object to a value that can be serialized natively by json_encode().
595
     *
596
     * @return array
597
     */
598
    public function jsonSerialize()
599
    {
600
        return $this->toArray();
601
    }
602
603
    /**
604
     * Send the message.
605
     *
606
     * The parameters can be `($text, $markdown, $notification)`, and the $text and
607
     * the $notification can be `null` that does not modify the exist field.
608
     * The parameters can also be
609
     * `($text, $attachment_text, $attachment_title, $attachment_images, $attachment_color)`.
610
     *
611
     * @return bool
612
     */
613 2
    public function send()
614
    {
615 2
        if (! $this->client) {
616 1
            return false;
617
        }
618
619 2
        if ($count = func_num_args()) {
620 2
            $firstArg = func_get_arg(0);
621
622 2
            if (1 === $count && (is_array($firstArg) || is_object($firstArg))) {
623 1
                return $this->client->sendMessage($firstArg);
624
            }
625
626 2
            if (! is_null($firstArg)) {
627 2
                $this->setText($firstArg);
628
            }
629
630 2
            if ($count > 1 && is_bool(func_get_arg(1))) {
631 2
                $this->setMarkdown(func_get_arg(1));
632
633 2
                if ($count > 2 && ! is_null(func_get_arg(2))) {
634 2
                    $this->setNotification(func_get_arg(2));
635
                }
636 1
            } elseif ($count > 1) {
637 1
                call_user_func_array(
638 1
                    [$this, 'addAttachment'],
639 1
                    array_slice(func_get_args(), 1)
640
                );
641
            }
642
        }
643
644 2
        return $this->client->sendMessage($this);
645
    }
646
647
    /**
648
     * Send the message to the given target.
649
     *
650
     * @param  mixed  $target
651
     * @return bool
652
     */
653 1
    public function sendTo($target)
654
    {
655 1
        $this->to($target);
656
657 1
        return call_user_func_array([$this, 'send'], array_slice(func_get_args(), 1));
658
    }
659
660
    /**
661
     * Convert the message to its string representation.
662
     *
663
     * @return string
664
     */
665
    public function __toString()
666
    {
667
        return $this->toJson();
668
    }
669
}
670