Email   C
last analyzed

Complexity

Total Complexity 56

Size/Duplication

Total Lines 453
Duplicated Lines 0 %

Coupling/Cohesion

Components 6
Dependencies 1

Importance

Changes 0
Metric Value
wmc 56
lcom 6
cbo 1
dl 0
loc 453
c 0
b 0
f 0
rs 5.5555

39 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A getFrom() 0 4 1
A setFrom() 0 5 1
A getFromName() 0 4 1
A setFromName() 0 5 1
A getReplyTo() 0 4 1
A setReplyTo() 0 5 1
A getReplyToName() 0 4 1
A setReplyToName() 0 5 1
A getTo() 0 4 1
A setTo() 0 5 1
A addTo() 0 5 1
A getCc() 0 4 1
A setCc() 0 5 1
A addCc() 0 5 1
A getBcc() 0 4 1
A setBcc() 0 5 1
A addBcc() 0 5 1
A getEncoding() 0 4 1
A setEncoding() 0 5 1
A getSubject() 0 4 1
A setSubject() 0 5 1
A getBody() 0 4 1
A setBody() 0 9 4
B addAttachment() 0 13 6
A addAttachments() 0 8 3
A setAttachments() 0 7 1
A getAttachments() 0 4 1
A getAttachmentsDir() 0 4 1
A setAttachmentsDir() 0 5 1
A hasAttachments() 0 4 2
C getComputedAttachments() 0 29 7
A getTemplate() 0 4 1
A setTemplate() 0 5 1
A hasTemplate() 0 4 1
A getTemplateParams() 0 4 1
A setTemplateParams() 0 5 1
A getCharset() 0 4 1
A setCharset() 0 5 1

How to fix   Complexity   

Complex Class

Complex classes like Email 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 Email, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types=1);
3
4
namespace AcMailer\Model;
5
6
use AcMailer\Exception\InvalidArgumentException;
7
use Zend\Mime\Message;
8
use Zend\Mime\Part;
9
use Zend\Stdlib\AbstractOptions;
10
11
final class Email extends AbstractOptions
12
{
13
    const DEFAULT_CHARSET = 'utf-8';
14
15
    /**
16
     * @var string
17
     */
18
    private $from = '';
19
    /**
20
     * @var string
21
     */
22
    private $fromName = '';
23
    /**
24
     * @var string
25
     */
26
    private $replyTo = '';
27
    /**
28
     * @var string
29
     */
30
    private $replyToName = '';
31
    /**
32
     * @var array
33
     */
34
    private $to = [];
35
    /**
36
     * @var array
37
     */
38
    private $cc = [];
39
    /**
40
     * @var array
41
     */
42
    private $bcc = [];
43
    /**
44
     * @var string
45
     */
46
    private $encoding = '';
47
    /**
48
     * @var string
49
     */
50
    private $subject = '';
51
    /**
52
     * @var string|Part|Message
53
     */
54
    private $body = '';
55
    /**
56
     * @var string|null
57
     */
58
    private $template;
59
    /**
60
     * @var array
61
     */
62
    private $templateParams = [];
63
    /**
64
     * @var array
65
     */
66
    private $attachments = [];
67
    /**
68
     * @var array
69
     */
70
    private $attachmentsDir = [];
71
    /**
72
     * @var string
73
     */
74
    private $charset = self::DEFAULT_CHARSET;
75
76
    public function __construct($options = null)
77
    {
78
        $this->__strictMode__ = false;
79
        parent::__construct($options);
80
    }
81
82
    /**
83
     * @return string
84
     */
85
    public function getFrom(): string
86
    {
87
        return $this->from;
88
    }
89
90
    /**
91
     * @param string $from
92
     * @return $this|self
93
     */
94
    public function setFrom(string $from): self
95
    {
96
        $this->from = $from;
97
        return $this;
98
    }
99
100
    /**
101
     * @return string
102
     */
103
    public function getFromName(): string
104
    {
105
        return $this->fromName;
106
    }
107
108
    /**
109
     * @param string $fromName
110
     * @return $this|self
111
     */
112
    public function setFromName(string $fromName): self
113
    {
114
        $this->fromName = $fromName;
115
        return $this;
116
    }
117
118
    /**
119
     * @return string
120
     */
121
    public function getReplyTo(): string
122
    {
123
        return $this->replyTo;
124
    }
125
126
    /**
127
     * @param string $replyTo
128
     * @return $this|self
129
     */
130
    public function setReplyTo(string $replyTo): self
131
    {
132
        $this->replyTo = $replyTo;
133
        return $this;
134
    }
135
136
    /**
137
     * @return string
138
     */
139
    public function getReplyToName(): string
140
    {
141
        return $this->replyToName;
142
    }
143
144
    /**
145
     * @param string $replyToName
146
     * @return $this|self
147
     */
148
    public function setReplyToName(string $replyToName): self
149
    {
150
        $this->replyToName = $replyToName;
151
        return $this;
152
    }
153
154
    /**
155
     * @return array
156
     */
157
    public function getTo(): array
158
    {
159
        return $this->to;
160
    }
161
162
    /**
163
     * @param array $to
164
     * @return $this|self
165
     */
166
    public function setTo(array $to): self
167
    {
168
        $this->to = $to;
169
        return $this;
170
    }
171
172
    public function addTo(string $to): self
173
    {
174
        $this->to[] = $to;
175
        return $this;
176
    }
177
178
    /**
179
     * @return array
180
     */
181
    public function getCc(): array
182
    {
183
        return $this->cc;
184
    }
185
186
    /**
187
     * @param array $cc
188
     * @return $this|self
189
     */
190
    public function setCc(array $cc): self
191
    {
192
        $this->cc = $cc;
193
        return $this;
194
    }
195
196
    public function addCc(string $cc): self
197
    {
198
        $this->cc[] = $cc;
199
        return $this;
200
    }
201
202
    /**
203
     * @return array
204
     */
205
    public function getBcc(): array
206
    {
207
        return $this->bcc;
208
    }
209
210
    /**
211
     * @param array $bcc
212
     * @return $this|self
213
     */
214
    public function setBcc(array $bcc): self
215
    {
216
        $this->bcc = $bcc;
217
        return $this;
218
    }
219
220
    public function addBcc(string $bcc): self
221
    {
222
        $this->bcc[] = $bcc;
223
        return $this;
224
    }
225
226
    /**
227
     * @return string
228
     */
229
    public function getEncoding(): string
230
    {
231
        return $this->encoding;
232
    }
233
234
    /**
235
     * @param string $encoding
236
     * @return $this|self
237
     */
238
    public function setEncoding(string $encoding): self
239
    {
240
        $this->encoding = $encoding;
241
        return $this;
242
    }
243
244
    /**
245
     * @return string
246
     */
247
    public function getSubject(): string
248
    {
249
        return $this->subject;
250
    }
251
252
    /**
253
     * @param string $subject
254
     * @return $this|self
255
     */
256
    public function setSubject(string $subject): self
257
    {
258
        $this->subject = $subject;
259
        return $this;
260
    }
261
262
    /**
263
     * @return string|Part|Message
264
     */
265
    public function getBody()
266
    {
267
        return $this->body;
268
    }
269
270
    /**
271
     * @param string|Part|Message $body
272
     * @return $this|self
273
     * @throws InvalidArgumentException
274
     */
275
    public function setBody($body): self
276
    {
277
        if (! \is_string($body) && ! $body instanceof Part && ! $body instanceof Message) {
278
            throw InvalidArgumentException::fromValidTypes(['string', Part::class, Message::class], $body);
279
        }
280
281
        $this->body = $body;
282
        return $this;
283
    }
284
285
    /**
286
     * @param string|resource|array|Part $file
287
     * @param string|null $filename
288
     * @return $this
289
     * @throws InvalidArgumentException
290
     */
291
    public function addAttachment($file, string $filename = null): self
292
    {
293
        if (! \is_string($file) && ! \is_array($file) && ! \is_resource($file) && ! $file instanceof Part) {
294
            throw InvalidArgumentException::fromValidTypes(['string', 'array', 'resource', Part::class], $file);
295
        }
296
297
        if ($filename !== null) {
298
            $this->attachments[$filename] = $file;
299
        } else {
300
            $this->attachments[] = $file;
301
        }
302
        return $this;
303
    }
304
305
    /**
306
     * @param array $files
307
     * @return $this
308
     * @throws InvalidArgumentException
309
     */
310
    public function addAttachments(array $files): self
311
    {
312
        foreach ($files as $key => $file) {
313
            $this->addAttachment($file, \is_string($key) ? $key : null);
314
        }
315
316
        return $this;
317
    }
318
319
    /**
320
     * @param array $files
321
     * @return $this
322
     * @throws InvalidArgumentException
323
     */
324
    public function setAttachments(array $files): self
325
    {
326
        $this->attachments = [];
327
        $this->addAttachments($files);
328
329
        return $this;
330
    }
331
332
    /**
333
     * Returns the list of attachments
334
     * @return array
335
     */
336
    public function getAttachments(): array
337
    {
338
        return $this->attachments;
339
    }
340
341
    /**
342
     * @return array
343
     */
344
    public function getAttachmentsDir(): array
345
    {
346
        return $this->attachmentsDir;
347
    }
348
349
    /**
350
     * @param array $attachmentsDir
351
     * @return $this|self
352
     */
353
    public function setAttachmentsDir(array $attachmentsDir): self
354
    {
355
        $this->attachmentsDir = $attachmentsDir;
356
        return $this;
357
    }
358
359
    /**
360
     * @return bool
361
     */
362
    public function hasAttachments(): bool
363
    {
364
        return ! empty($this->attachments) || ! empty($this->attachmentsDir);
365
    }
366
367
    /**
368
     * Processes the attachments dir and merges the result with the attachments array, then returns the result
369
     *
370
     * @return array
371
     */
372
    public function getComputedAttachments(): array
373
    {
374
        if (! $this->hasAttachments()) {
375
            return [];
376
        }
377
        $attachments = $this->getAttachments();
378
379
        // Process the attachments dir if any, and include the files in that folder
380
        $dir = $this->getAttachmentsDir();
381
        $path = $dir['path'] ?? null;
382
        $recursive = (bool) ($dir['recursive'] ?? false);
383
384
        if (\is_string($path) && \is_dir($path)) {
385
            $files = $recursive ? new \RecursiveIteratorIterator(
386
                new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS),
387
                \RecursiveIteratorIterator::CHILD_FIRST
388
            ) : new \DirectoryIterator($path);
389
390
            /* @var \SplFileInfo $fileInfo */
391
            foreach ($files as $fileInfo) {
392
                if ($fileInfo->isDir()) {
393
                    continue;
394
                }
395
                $attachments[] = $fileInfo->getPathname();
396
            }
397
        }
398
399
        return $attachments;
400
    }
401
402
    /**
403
     * @return string|null
404
     */
405
    public function getTemplate()
406
    {
407
        return $this->template;
408
    }
409
410
    /**
411
     * @param string|null $template
412
     * @return $this|self
413
     */
414
    public function setTemplate(string $template = null): self
415
    {
416
        $this->template = $template;
417
        return $this;
418
    }
419
420
    /**
421
     * @return bool
422
     */
423
    public function hasTemplate(): bool
424
    {
425
        return $this->template !== null;
426
    }
427
428
    /**
429
     * @return array
430
     */
431
    public function getTemplateParams(): array
432
    {
433
        return $this->templateParams;
434
    }
435
436
    /**
437
     * @param array $templateParams
438
     * @return $this|self
439
     */
440
    public function setTemplateParams(array $templateParams): self
441
    {
442
        $this->templateParams = $templateParams;
443
        return $this;
444
    }
445
446
    /**
447
     * @return string
448
     */
449
    public function getCharset(): string
450
    {
451
        return $this->charset;
452
    }
453
454
    /**
455
     * @param string $charset
456
     * @return $this|self
457
     */
458
    public function setCharset(string $charset): self
459
    {
460
        $this->charset = $charset;
461
        return $this;
462
    }
463
}
464