Test Failed
Pull Request — master (#30)
by Evgeniy
02:28
created

Message::withAttachedSigners()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 2
cts 2
cp 1
crap 2
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Mailer\SwiftMailer;
6
7
use Swift_Attachment;
8
use Swift_EmbeddedFile;
9
use Swift_Message;
10
use Swift_Mime_MimePart;
11
use Swift_Signer;
12
use Throwable;
13
use Yiisoft\Mailer\MessageInterface;
14
15
use function reset;
16
17
/**
18
 * Message implements a message class based on SwiftMailer.
19
 *
20
 * @see https://swiftmailer.symfony.com/docs/messages.html
21
 * @see Mailer
22
 */
23
final class Message implements MessageInterface
24
{
25
    private Swift_Message $swiftMessage;
26 7
    private ?Throwable $error = null;
27
28 7
    public function __construct()
29
    {
30
        $this->swiftMessage = new Swift_Message();
31 51
    }
32
33 51
    public function __clone()
34 51
    {
35
        $this->swiftMessage = clone $this->swiftMessage;
36
    }
37
38
    public function getCharset(): string
39
    {
40 1
        return $this->swiftMessage->getCharset();
41
    }
42 1
43 1
    public function withCharset(string $charset): self
44
    {
45 2
        $new = clone $this;
46
        $new->swiftMessage->setCharset($charset);
47 2
        return $new;
48
    }
49
50 4
    public function getFrom()
51
    {
52 4
        return $this->swiftMessage->getFrom() ?? '';
53
    }
54 4
55
    public function withFrom($from): self
56
    {
57 4
        $new = clone $this;
58
        $new->swiftMessage->setFrom($from);
59 4
        return $new;
60
    }
61
62 10
    public function getTo()
63
    {
64 10
        return $this->swiftMessage->getTo() ?? '';
65
    }
66 10
67
    public function withTo($to): self
68
    {
69 4
        $new = clone $this;
70
        $new->swiftMessage->setTo($to);
71 4
        return $new;
72
    }
73
74 5
    public function getReplyTo()
75
    {
76 5
        return $this->swiftMessage->getReplyTo() ?? '';
77
    }
78 5
79
    public function withReplyTo($replyTo): self
80
    {
81 6
        $new = clone $this;
82
        $new->swiftMessage->setReplyTo($replyTo);
83 6
        return $new;
84
    }
85
86 11
    public function getCc()
87
    {
88 11
        return $this->swiftMessage->getCc() ?? '';
89
    }
90 11
91
    public function withCc($cc): self
92
    {
93 4
        $new = clone $this;
94
        $new->swiftMessage->setCc($cc);
95 4
        return $new;
96
    }
97
98 5
    public function getBcc()
99
    {
100 5
        return $this->swiftMessage->getBcc() ?? '';
101
    }
102 5
103
    public function withBcc($bcc): self
104
    {
105 4
        $new = clone $this;
106
        $new->swiftMessage->setBcc($bcc);
107 4
        return $new;
108
    }
109
110 5
    public function getSubject(): string
111
    {
112 5
        return (string) $this->swiftMessage->getSubject() ?? '';
113
    }
114 5
115
    public function withSubject(string $subject): self
116
    {
117 3
        $new = clone $this;
118
        $new->swiftMessage->setSubject($subject);
119 3
        return $new;
120
    }
121
122 8
    public function getTextBody(): string
123
    {
124 8
        return $this->swiftMessage->getBody() ?? '';
125
    }
126 8
127
    public function withTextBody(string $text): self
128
    {
129 1
        $new = clone $this;
130
        $new->setBody($text, 'text/plain');
131 1
        return $new;
132
    }
133
134 6
    public function getHtmlBody(): string
135
    {
136 6
        return $this->swiftMessage->getBody() ?? '';
137
    }
138 6
139
    public function withHtmlBody(string $html): self
140
    {
141 2
        $new = clone $this;
142
        $new->setBody($html, 'text/html');
143 2
        return $new;
144
    }
145
146 4
    public function withAttached(string $fileName, array $options = []): self
147
    {
148 4
        $attachment = Swift_Attachment::fromPath($fileName);
149
150 4
        if (!empty($options['fileName'])) {
151
            $attachment->setFilename($options['fileName']);
152
        }
153
154
        if (!empty($options['contentType'])) {
155
            $attachment->setContentType($options['contentType']);
156
        }
157
158
        $new = clone $this;
159
        $new->swiftMessage->attach($attachment);
160
        return $new;
161 8
    }
162
163 8
    public function withAttachedContent(string $content, array $options = []): self
164 8
    {
165 8
        $attachment = new Swift_Attachment($content);
166 8
167 8
        if (!empty($options['fileName'])) {
168 8
            $attachment->setFilename($options['fileName']);
169 8
        }
170 1
171
        if (!empty($options['contentType'])) {
172
            $attachment->setContentType($options['contentType']);
173
        }
174
175 1
        $new = clone $this;
176 1
        $new->swiftMessage->attach($attachment);
177 1
        return $new;
178 1
    }
179 1
180
    public function embed(string $fileName, array $options = []): string
181
    {
182
        $embedFile = Swift_EmbeddedFile::fromPath($fileName);
183 8
184 1
        if (!empty($options['fileName'])) {
185 1
            $embedFile->setFilename($options['fileName']);
186 1
        }
187
188 8
        if (!empty($options['contentType'])) {
189
            $embedFile->setContentType($options['contentType']);
190
        }
191 3
192 3
        $this->swiftMessage = clone $this->swiftMessage;
193 1
        return $this->swiftMessage->embed($embedFile);
194
    }
195 2
196 2
    public function embedContent(string $content, array $options = []): string
197 2
    {
198 2
        $embedFile = new Swift_EmbeddedFile($content);
199
200
        if (!empty($options['fileName'])) {
201 8
            $embedFile->setFilename($options['fileName']);
202
        }
203 1
204
        if (!empty($options['contentType'])) {
205 1
            $embedFile->setContentType($options['contentType']);
206 1
        }
207 1
208
        $this->swiftMessage = clone $this->swiftMessage;
209 1
        return $this->swiftMessage->embed($embedFile);
210 1
    }
211
212 1
    public function getHeader(string $name): array
213
    {
214 1
        $headerSet = $this->swiftMessage->getHeaders();
215
216
        if (!$headerSet->has($name)) {
217 1
            return [];
218
        }
219 1
220 1
        $headers = [];
221 1
222
        foreach ($headerSet->getAll($name) as $header) {
223 1
            $headers[] = $header->getValue();
224 1
        }
225
226 1
        return $headers;
227
    }
228 1
229
    public function withAddedHeader(string $name, string $value): self
230
    {
231
        $new = clone $this;
232
        $new->swiftMessage->getHeaders()->addTextHeader($name, $value);
233
        return $new;
234
    }
235
236
    public function withHeader(string $name, $value): self
237
    {
238
        $new = clone $this;
239
        $headerSet = $new->swiftMessage->getHeaders();
240
241
        if ($headerSet->has($name)) {
242
            $headerSet->remove($name);
243
        }
244
245
        foreach ((array) $value as $v) {
246
            $headerSet->addTextHeader($name, $v);
247
        }
248
249
        return $new;
250
    }
251
252
    public function withHeaders(array $headers): self
253
    {
254
        $new = clone $this;
255
256
        foreach ($headers as $name => $value) {
257 3
            $new = $new->withHeader($name, $value);
258
        }
259 3
260
        return $new;
261
    }
262 1
263
    public function getError(): ?Throwable
264 1
    {
265
        return $this->error;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->error also could return the type null which is incompatible with the return type mandated by Yiisoft\Mailer\MessageInterface::getError() of Throwable.
Loading history...
266 1
    }
267
268
    public function withError(Throwable $e): self
269 3
    {
270
        $new = clone $this;
271 3
        $new->error = $e;
272
        return $new;
273 3
    }
274 1
275
    public function __toString(): string
276
    {
277 3
        return $this->swiftMessage->toString();
278 3
    }
279
280
    /**
281 3
     * Returns a Swift message instance.
282
     *
283
     * @return Swift_Message Swift message instance.
284 3
     */
285
    public function getSwiftMessage(): Swift_Message
286 3
    {
287 3
        return $this->swiftMessage;
288 2
    }
289
290
    /**
291 3
     * Returns the return-path (the bounce address) of this message.
292 3
     *
293 3
     * @return string The bounce email address.
294
     */
295
    public function getReturnPath(): string
296 3
    {
297
        return $this->swiftMessage->getReturnPath() ?? '';
298
    }
299 1
300
    /**
301 1
     * Returns a new instance with the specified return-path (the bounce address) of this message.
302 1
     *
303
     * @param string $address The bounce email address.
304
     *
305 1
     * @return self
306
     */
307
    public function withReturnPath(string $address): self
308
    {
309
        $new = clone $this;
310
        $new->swiftMessage->setReturnPath($address);
311
        return $new;
312
    }
313 1
314
    /**
315 1
     * Returns the priority of this message.
316
     *
317
     * @return int The priority value as integer in range: `1..5`,
318
     * where 1 is the highest priority and 5 is the lowest.
319
     */
320
    public function getPriority(): int
321
    {
322
        return (int) $this->swiftMessage->getPriority();
323
    }
324
325 2
    /**
326
     * Returns a new instance with the specified priority of this message.
327 2
     *
328
     * @param int $priority The priority value, should be an integer in range: `1..5`,
329 2
     * where 1 is the highest priority and 5 is the lowest.
330
     *
331
     * @return self
332
     */
333
    public function withPriority(int $priority): self
334
    {
335
        $new = clone $this;
336
        $new->swiftMessage->setPriority($priority);
337
        return $new;
338 5
    }
339
340
    /**
341 5
     * Returns the addresses to which a read-receipt will be sent.
342
     *
343
     * @return array|string The receipt receive email addresses.
344
     */
345
    public function getReadReceiptTo()
346
    {
347
        return $this->swiftMessage->getReadReceiptTo() ?? '';
348
    }
349
350
    /**
351
     * Returns a new instance with the specified ask for a delivery receipt from the recipient to be sent to addresses.
352 6
     *
353
     * @param array|string $addresses The receipt receive email address(es).
354 6
     *
355
     * @return self
356 6
     */
357
    public function withReadReceiptTo($addresses): self
358
    {
359
        $new = clone $this;
360
        $new->swiftMessage->setReadReceiptTo((array) $addresses);
361
        return $new;
362
    }
363
364 4
    /**
365
     * Returns a new instance with the specified attached signers.
366 4
     *
367
     * @param Swift_Signer[] $signers
368
     *
369
     * @return self
370
     */
371
    public function withAttachedSigners(array $signers): self
372
    {
373
        $new = clone $this;
374
375
        foreach ($signers as $signer) {
376 5
            $new->swiftMessage->attachSigner($signer);
377
        }
378 5
379
        return $new;
380 5
    }
381
382
    /**
383
     * Sets the message body.
384
     *
385
     * If body is already set and its content type matches given one, it will
386
     * be overridden, if content type miss match the multipart message will be composed.
387
     *
388
     * @param string $body The body content.
389
     * @param string $contentType The body content type.
390 2
     */
391
    private function setBody(string $body, string $contentType): void
392 2
    {
393 2
        $oldBody = $this->swiftMessage->getBody();
394
        $charset = $this->swiftMessage->getCharset();
395
396 2
        if (!empty($oldBody)) {
397
            $oldContentType = $this->swiftMessage->getContentType();
398
399
            if ($oldContentType === $contentType) {
400
                $this->swiftMessage->setBody($body, $contentType);
401
                return;
402
            }
403
404
            $this->swiftMessage->setBody(null);
405
            $this->swiftMessage->setContentType('');
406
            $this->swiftMessage->addPart($oldBody, $oldContentType, $charset);
407
            $this->swiftMessage->addPart($body, $contentType, $charset);
408
            return;
409
        }
410
411
        $parts = $this->swiftMessage->getChildren();
412
        $partFound = false;
413
414
        foreach ($parts as $key => $part) {
415
            if ($part instanceof Swift_Mime_MimePart) {
416
                if ($part->getContentType() === $contentType) {
417
                    $charset = $part->getCharset();
418
                    unset($parts[$key]);
419
                    $partFound = true;
420
                    break;
421
                }
422
            }
423
        }
424
425
        if (!$partFound) {
426
            $this->swiftMessage->setBody($body, $contentType);
427
            return;
428
        }
429
430
        reset($parts);
431
        $this->swiftMessage->setChildren($parts);
432
        $this->swiftMessage->addPart($body, $contentType, $charset);
433
    }
434
}
435