Attachment   C
last analyzed

Complexity

Total Complexity 72

Size/Duplication

Total Lines 736
Duplicated Lines 2.17 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 72
lcom 1
cbo 3
dl 16
loc 736
rs 5
c 0
b 0
f 0

42 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 2
F setAttributes() 0 76 19
A getFallback() 0 4 1
A setFallback() 0 6 1
A getPretext() 0 4 1
A setPretext() 0 6 1
A getText() 0 4 1
A setText() 0 6 1
A getTitle() 0 4 1
A setTitle() 0 6 1
A getTitleLink() 0 4 1
A setTitleLink() 0 6 1
A getImageUrl() 0 4 1
A setImageUrl() 0 6 1
A getThumbUrl() 0 4 1
A setThumbUrl() 0 6 1
A getAuthorName() 0 4 1
A setAuthorName() 0 6 1
A getAuthorLink() 0 4 1
A setAuthorLink() 0 6 1
A getAuthorIcon() 0 4 1
A setAuthorIcon() 0 6 1
A getColor() 0 4 1
A setColor() 0 6 1
A getFooter() 0 4 1
A setFooter() 0 6 1
A getFooterIcon() 0 4 1
A setFooterIcon() 0 6 1
A getTimestamp() 0 4 1
A setTimestamp() 0 6 1
A getMarkdownAttributes() 0 4 1
A setMarkdownAttributes() 0 6 1
A getFields() 0 4 1
A setFields() 0 15 3
B addField() 0 25 5
A getCallbackId() 0 4 1
A setCallbackId() 0 6 1
A getActions() 0 4 1
A setActions() 0 10 2
A addAction() 16 16 3
A unserialize() 0 4 1
B toArray() 0 35 3

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like Attachment often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Attachment, and based on these observations, apply Extract Interface, too.

1
<?php namespace nyx\notify\transports\slack\message;
2
3
// External dependencies
4
use nyx\core;
5
use nyx\diagnostics;
6
7
/**
8
 * Slack Message Attachment
9
 *
10
 * See {@see https://api.slack.com/docs/message-attachments} and
11
 * {@see https://api.slack.com/docs/message-buttons#attachment_fields} for Slack's documentation on using
12
 * Messages with Attachments.
13
 *
14
 * @package     Nyx\Notify
15
 * @version     0.1.0
16
 * @author      Michal Chojnacki <[email protected]>
17
 * @copyright   2012-2017 Nyx Dev Team
18
 * @link        https://github.com/unyx/nyx
19
 * @todo        PHP7.1 pass for nullable return types (missing ?string on most methods).
20
 */
21
class Attachment implements core\interfaces\Serializable
22
{
23
    /**
24
     * The traits of an Attachment.
25
     */
26
    use core\traits\Serializable;
27
28
    /**
29
     * The colors an Attachment can be styled with. Note: Those only represent the colors predefined by Slack.
30
     * Otherwise, the Attachment::$color property accepts any hex color string.
31
     */
32
    const COLOR_GOOD    = 'good';
33
    const COLOR_WARNING = 'warning';
34
    const COLOR_DANGER  = 'danger';
35
36
    /**
37
     * @var string  Required. A plaintext message displayed to users using a client/interface that does not
38
     *              support attachments or interactive messages. Consider leaving a URL pointing to your
39
     *              service if the potential message actions are representable outside of Slack.
40
     *              Otherwise, let folks know what they are missing.
41
     */
42
    protected $fallback;
43
44
    /**
45
     * @var string  Optional. The text that appears above the attachment block.
46
     */
47
    protected $pretext;
48
49
    /**
50
     * @var string  Optional. The text that appears within the attachment.
51
     */
52
    protected $text;
53
54
    /**
55
     * @var string  Optional. The title of the Attachment.
56
     */
57
    protected $title;
58
59
    /**
60
     * @var string  Optional. The URL the title should link to.
61
     */
62
    protected $title_link;
63
64
    /**
65
     * @var string  Optional. The image that should appear within the attachment.
66
     */
67
    protected $image_url;
68
69
    /**
70
     * @var string  Optional. The thumbnail that should appear within the attachment.
71
     */
72
    protected $thumb_url;
73
74
    /**
75
     * @var string  Optional. The name of the author.
76
     */
77
    protected $author_name;
78
79
    /**
80
     * @var string  Optional. The URL the author's name should link to.
81
     */
82
    protected $author_link;
83
84
    /**
85
     * @var string  Optional. The author's icon.
86
     */
87
    protected $author_icon;
88
89
    /**
90
     * @var string  Optional. The color used for the border along the left side of the Attachment.
91
     */
92
    protected $color;
93
94
    /**
95
     * @var string  Optional. The text to display in the footer of the Attachment.
96
     */
97
    protected $footer;
98
99
    /**
100
     * @var string  Optional. The icon to display in the footer of the Attachment.
101
     */
102
    protected $footer_icon;
103
104
    /**
105
     * @var int     Optional. The (Unix) timestamp of the Attachment.
106
     */
107
    protected $ts;
108
109
    /**
110
     * @var array   Optional. The attributes which should be parsed by Slack as its Markdown flavour.
111
     */
112
    protected $mrkdwn_in = [];
113
114
    /**
115
     * @var attachment\Field[]  The Fields of the Attachment.
116
     */
117
    protected $fields = [];
118
119
    /**
120
     * @var string  Optional. The ID of the callback to use for the attached Actions, if any. Is required
121
     *              When those Actions are present.
122
     */
123
    protected $callbackId;
124
125
    /**
126
     * @var attachment\Action[] The Actions of the Attachment. 5 at most.
127
     */
128
    protected $actions = [];
129
130
    /**
131
     * Creates a new Attachment instance.
132
     *
133
     * @param   array   $attributes
134
     */
135
    public function __construct(array $attributes = null)
136
    {
137
        if (!empty($attributes)) {
138
            $this->setAttributes($attributes);
139
        }
140
    }
141
142
    /**
143
     * Sets the attributes of this Attachment.
144
     *
145
     * @param   array   $attributes
146
     * @return  $this
147
     */
148
    public function setAttributes(array $attributes) : Attachment
149
    {
150
        if (isset($attributes['fallback'])) {
151
            $this->setFallback($attributes['fallback']);
152
        }
153
154
        if (isset($attributes['pretext'])) {
155
            $this->setPretext($attributes['pretext']);
156
        }
157
158
        if (isset($attributes['text'])) {
159
            $this->setText($attributes['text']);
160
        }
161
162
        if (isset($attributes['title'])) {
163
            $this->setTitle($attributes['title']);
164
        }
165
166
        if (isset($attributes['title_link'])) {
167
            $this->setTitleLink($attributes['title_link']);
168
        }
169
170
        if (isset($attributes['image_url'])) {
171
            $this->setImageUrl($attributes['image_url']);
172
        }
173
174
        if (isset($attributes['thumb_url'])) {
175
            $this->setThumbUrl($attributes['thumb_url']);
176
        }
177
178
        if (isset($attributes['author_name'])) {
179
            $this->setAuthorName($attributes['author_name']);
180
        }
181
182
        if (isset($attributes['author_link'])) {
183
            $this->setAuthorLink($attributes['author_link']);
184
        }
185
186
        if (isset($attributes['author_icon'])) {
187
            $this->setAuthorIcon($attributes['author_icon']);
188
        }
189
190
        if (isset($attributes['color'])) {
191
            $this->setColor($attributes['color']);
192
        }
193
194
        if (isset($attributes['footer'])) {
195
            $this->setFooter($attributes['footer']);
196
        }
197
198
        if (isset($attributes['footer_icon'])) {
199
            $this->setFooterIcon($attributes['footer_icon']);
200
        }
201
202
        if (isset($attributes['timestamp'])) {
203
            $this->setTimestamp($attributes['timestamp']);
204
        }
205
206
        if (isset($attributes['mrkdwn_in'])) {
207
            $this->setMarkdownAttributes($attributes['mrkdwn_in']);
208
        }
209
210
        if (isset($attributes['fields'])) {
211
            $this->setFields($attributes['fields']);
212
        }
213
214
        if (isset($attributes['callback_id'])) {
215
            $this->setCallbackId($attributes['callback_id']);
216
        }
217
218
        if (isset($attributes['actions'])) {
219
            $this->setActions($attributes['actions']);
220
        }
221
222
        return $this;
223
    }
224
225
    /**
226
     * Returns the fallback text.
227
     *
228
     * @return  string
229
     */
230
    public function getFallback()
231
    {
232
        return $this->fallback;
233
    }
234
235
    /**
236
     * Sets the fallback text.
237
     *
238
     * @param   string  $fallback
239
     * @return  $this
240
     */
241
    public function setFallback(string $fallback) : Attachment
242
    {
243
        $this->fallback = $fallback;
244
245
        return $this;
246
    }
247
248
    /**
249
     * Returns the text that appears above the attachment block.
250
     *
251
     * @return  string
252
     */
253
    public function getPretext()
254
    {
255
        return $this->pretext;
256
    }
257
258
    /**
259
     * Sets the text that appears above the attachment block.
260
     *
261
     * @param   string  $pretext
262
     * @return  $this
263
     */
264
    public function setPretext(string $pretext) : Attachment
265
    {
266
        $this->pretext = $pretext;
267
268
        return $this;
269
    }
270
271
    /**
272
     * Returns the text that appears within the attachment.
273
     *
274
     * @return  string
275
     */
276
    public function getText()
277
    {
278
        return $this->text;
279
    }
280
281
    /**
282
     * Sets the text that appears within the attachment.
283
     *
284
     * @param   string  $text
285
     * @return  $this
286
     */
287
    public function setText(string $text) : Attachment
288
    {
289
        $this->text = $text;
290
291
        return $this;
292
    }
293
294
    /**
295
     * Returns the title of the Attachment.
296
     *
297
     * @return  string
298
     */
299
    public function getTitle()
300
    {
301
        return $this->title;
302
    }
303
304
    /**
305
     * Sets the title of the Attachment.
306
     *
307
     * @param   string  $title
308
     * @return  $this
309
     */
310
    public function setTitle(string $title) : Attachment
311
    {
312
        $this->title = $title;
313
314
        return $this;
315
    }
316
317
    /**
318
     * Returns the URL the title should link to.
319
     *
320
     * @return  string
321
     */
322
    public function getTitleLink()
323
    {
324
        return $this->title_link;
325
    }
326
327
    /**
328
     * Sets the URL the title should link to.
329
     *
330
     * @param   string  $link
331
     * @return  $this
332
     */
333
    public function setTitleLink(string $link) : Attachment
334
    {
335
        $this->title_link = $link;
336
337
        return $this;
338
    }
339
340
    /**
341
     * Returns the image that should appear within the attachment.
342
     *
343
     * @return  string
344
     */
345
    public function getImageUrl()
346
    {
347
        return $this->image_url;
348
    }
349
350
    /**
351
     * Sets the image that should appear within the attachment.
352
     *
353
     * @param   string  $url
354
     * @return  $this
355
     */
356
    public function setImageUrl(string $url) : Attachment
357
    {
358
        $this->image_url = $url;
359
360
        return $this;
361
    }
362
363
    /**
364
     * Returns the thumbnail that should appear within the attachment.
365
     *
366
     * @return  string
367
     */
368
    public function getThumbUrl()
369
    {
370
        return $this->thumb_url;
371
    }
372
373
    /**
374
     * Sets the thumbnail that should appear within the attachment.
375
     *
376
     * @param   string  $url
377
     * @return  $this
378
     */
379
    public function setThumbUrl(string $url) : Attachment
380
    {
381
        $this->thumb_url = $url;
382
383
        return $this;
384
    }
385
386
    /**
387
     * Returns the name of the author.
388
     *
389
     * @return  string
390
     */
391
    public function getAuthorName()
392
    {
393
        return $this->author_name;
394
    }
395
396
    /**
397
     * Sets the name of the author.
398
     *
399
     * @param   string  $author_name
400
     * @return  $this
401
     */
402
    public function setAuthorName(string $author_name) : Attachment
403
    {
404
        $this->author_name = $author_name;
405
406
        return $this;
407
    }
408
409
    /**
410
     * Returns the URL the author's name should link to.
411
     *
412
     * @return string
413
     */
414
    public function getAuthorLink()
415
    {
416
        return $this->author_link;
417
    }
418
419
    /**
420
     * Sets the URL the author's name should link to.
421
     *
422
     * @param   string  $url
423
     * @return  $this
424
     */
425
    public function setAuthorLink(string $url) : Attachment
426
    {
427
        $this->author_link = $url;
428
429
        return $this;
430
    }
431
432
    /**
433
     * Returns the author's icon.
434
     *
435
     * @return string
436
     */
437
    public function getAuthorIcon()
438
    {
439
        return $this->author_icon;
440
    }
441
442
    /**
443
     * Sets the author's icon.
444
     *
445
     * @param   string  $url
446
     * @return  $this
447
     */
448
    public function setAuthorIcon(string $url) : Attachment
449
    {
450
        $this->author_icon = $url;
451
452
        return $this;
453
    }
454
455
    /**
456
     * Returns the color used for the border along the left side of the Attachment.
457
     *
458
     * @return  string
459
     */
460
    public function getColor()
461
    {
462
        return $this->color;
463
    }
464
465
    /**
466
     * Sets the color used for the border along the left side of the Attachment.
467
     *
468
     * @param   string  $color  One of the COLOR_* class constants or a hex color code.
469
     * @return  $this
470
     */
471
    public function setColor(string $color) : Attachment
472
    {
473
        $this->color = $color;
474
475
        return $this;
476
    }
477
478
    /**
479
     * Returns the text to display in the footer of the Attachment.
480
     *
481
     * @return  string
482
     */
483
    public function getFooter()
484
    {
485
        return $this->footer;
486
    }
487
488
    /**
489
     * Sets the text to display in the footer of the Attachment.
490
     *
491
     * @param   string  $footer
492
     * @return  $this
493
     */
494
    public function setFooter(string $footer) : Attachment
495
    {
496
        $this->footer = $footer;
497
498
        return $this;
499
    }
500
501
    /**
502
     * Returns the icon to display in the footer of the Attachment.
503
     *
504
     * @return  string
505
     */
506
    public function getFooterIcon()
507
    {
508
        return $this->footer_icon;
509
    }
510
511
    /**
512
     * Sets the icon to display in the footer of the Attachment.
513
     *
514
     * @param   string  $url
515
     * @return  $this
516
     */
517
    public function setFooterIcon(string $url) : Attachment
518
    {
519
        $this->footer_icon = $url;
520
521
        return $this;
522
    }
523
524
    /**
525
     * Returns the (UNIX) timestamp of the Attachment.
526
     *
527
     * @return  int
528
     */
529
    public function getTimestamp()
530
    {
531
        return $this->ts;
532
    }
533
534
    /**
535
     * Sets the (UNIX) timestamp of the Attachment.
536
     *
537
     * @param   int     $time
538
     * @return  $this
539
     */
540
    public function setTimestamp(int $time) : Attachment
541
    {
542
        $this->ts = $time;
543
544
        return $this;
545
    }
546
547
    /**
548
     * Returns the attributes which should be parsed by Slack as its Markdown flavour.
549
     *
550
     * @return  array
551
     */
552
    public function getMarkdownAttributes() : array
553
    {
554
        return $this->mrkdwn_in;
555
    }
556
557
    /**
558
     * Sets the attributes which should be parsed by Slack as its Markdown flavour.
559
     *
560
     * @param   array   $attributes
561
     * @return  $this
562
     */
563
    public function setMarkdownAttributes(array $attributes) : Attachment
564
    {
565
        $this->mrkdwn_in = $attributes;
566
567
        return $this;
568
    }
569
570
    /**
571
     * Returns the Fields of the Attachment.
572
     *
573
     * @return  attachment\Field[]
574
     */
575
    public function getFields() : array
576
    {
577
        return $this->fields;
578
    }
579
580
    /**
581
     * Sets the Fields of the Attachment.
582
     *
583
     * @param   attachment\Field[] $fields
584
     * @return  $this
585
     */
586
    public function setFields(array $fields) : Attachment
587
    {
588
        $this->fields = [];
589
590
        foreach ($fields as $title => $value) {
591
592
            if (is_string($value)) {
593
                $this->addField($title, $value);
594
            } else {
595
                $this->addField($value);
596
            }
597
        }
598
599
        return $this;
600
    }
601
602
    /**
603
     * Adds a Field to the Attachment. Acts as a factory method.
604
     *
605
     * @param   mixed   $field
606
     * @param   string  $value  If given, then $field is treated as the title of the Field and must be a string.
607
     * @return  $this
608
     * @throws  \InvalidArgumentException
609
     */
610
    public function addField($field, string $value = null) : Attachment
611
    {
612
        if (null !== $value && is_string($field)) {
613
            $this->fields[] = new attachment\Field([
614
                'title' => $field,
615
                'value' => $value
616
            ]);
617
618
            return $this;
619
        }
620
621
        if (is_array($field)) {
622
            $this->fields[] = new attachment\Field($field);
623
624
            return $this;
625
        }
626
627
        if ($field instanceof attachment\Field) {
628
            $this->fields[] = $field;
629
630
            return $this;
631
        }
632
633
        throw new \InvalidArgumentException("Expected an array or an instance of ".attachment\Field::class.", got [".diagnostics\Debug::getTypeName($field)."] instead.");
634
    }
635
636
    /**
637
     * Returns the callback id for the Actions of this Attachment.
638
     *
639
     * @return  string
640
     */
641
    public function getCallbackId()
642
    {
643
        return $this->callbackId;
644
    }
645
646
    /**
647
     * Sets the callback id for the Actions of this Attachment.
648
     *
649
     * @param   string  $id
650
     * @return  $this
651
     */
652
    public function setCallbackId(string $id) : Attachment
653
    {
654
        $this->callbackId = $id;
655
656
        return $this;
657
    }
658
659
    /**
660
     * Returns the Actions of the Attachment.
661
     *
662
     * @return  attachment\Action[]
663
     */
664
    public function getActions() : array
665
    {
666
        return $this->actions;
667
    }
668
669
    /**
670
     * Sets the Actions of the Attachment.
671
     *
672
     * @param   array   $actions
673
     * @return  $this
674
     */
675
    public function setActions(array $actions) : Attachment
676
    {
677
        $this->actions = [];
678
679
        foreach ($actions as $action) {
680
            $this->addAction($action);
681
        }
682
683
        return $this;
684
    }
685
686
    /**
687
     * Adds an Action to the Attachment.
688
     *
689
     * @param   array|attachment\Action $action
690
     * @return  $this
691
     * @throws  \InvalidArgumentException
692
     */
693 View Code Duplication
    public function addAction($action) : Attachment
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
694
    {
695
        if (is_array($action)) {
696
            $this->actions[] = new attachment\Action($action);
697
698
            return $this;
699
        }
700
701
        if ($action instanceof attachment\Action) {
702
            $this->actions[] = $action;
703
704
            return $this;
705
        }
706
707
        throw new \InvalidArgumentException("Expected an array or an instance of ".attachment\Action::class.", got [".diagnostics\Debug::getTypeName($action)."] instead.");
708
   }
709
710
    /**
711
     * {@inheritDoc}
712
     */
713
    public function unserialize($data)
714
    {
715
        $this->setAttributes(unserialize($data));
716
    }
717
718
    /**
719
     * {@inheritDoc}
720
     */
721
    public function toArray() : array
722
    {
723
        $data = [
724
            'fallback'    => $this->getFallback(),
725
            'pretext'     => $this->getPretext(),
726
            'text'        => $this->getText(),
727
            'title'       => $this->getTitle(),
728
            'title_link'  => $this->getTitleLink(),
729
            'image_url'   => $this->getImageUrl(),
730
            'thumb_url'   => $this->getThumbUrl(),
731
            'color'       => $this->getColor(),
732
            'author_name' => $this->getAuthorName(),
733
            'author_link' => $this->getAuthorLink(),
734
            'author_icon' => $this->getAuthorIcon(),
735
            'footer'      => $this->getFooter(),
736
            'footer_icon' => $this->getFooterIcon(),
737
            'ts'          => $this->getTimestamp(),
738
            'mrkdwn_in'   => $this->getMarkdownAttributes(),
739
            'callback_id' => $this->getCallbackId(),
740
741
            // Empty, we'll populate those two in a second with the toArray'ed values of the objects instead.
742
            'fields'      => [],
743
            'actions'     => []
744
        ];
745
746
        foreach ($this->getFields() as $field) {
747
            $data['fields'][] = $field->toArray();
748
        }
749
750
        foreach ($this->getActions() as $action) {
751
            $data['actions'][] = $action->toArray();
752
        }
753
754
        return $data;
755
    }
756
}
757