Passed
Push — master ( ba6145...56b83d )
by Alexander
02:23
created

Message::getReturnPath()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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