Mailer::sendMessage()   A
last analyzed

Complexity

Conditions 5
Paths 7

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 5

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 13
c 1
b 0
f 0
nc 7
nop 1
dl 0
loc 24
ccs 16
cts 16
cp 1
crap 5
rs 9.5222
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Mailer\Symfony;
6
7
use Psr\EventDispatcher\EventDispatcherInterface;
8
use RuntimeException;
9
use Symfony\Component\Mailer\Mailer as SymfonyMailer;
10
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
11
use Symfony\Component\Mailer\Transport\TransportInterface;
12
use Symfony\Component\Mime\Crypto\DkimSigner;
13
use Symfony\Component\Mime\Crypto\SMimeEncrypter;
14
use Symfony\Component\Mime\Crypto\SMimeSigner;
15
use Yiisoft\Mailer\Mailer as BaseMailer;
16
use Yiisoft\Mailer\MessageBodyRenderer;
17
use Yiisoft\Mailer\MessageFactoryInterface;
18
use Yiisoft\Mailer\MessageInterface;
19
20
use function sprintf;
21
22
/**
23
 * Mailer implements a mailer based on Symfony Mailer.
24
 *
25
 * @see https://github.com/symfony/mailer
26
 */
27
final class Mailer extends BaseMailer
28
{
29
    private SymfonyMailer $symfonyMailer;
30
    private ?SMimeEncrypter $encryptor = null;
31
32
    private null|DkimSigner|SMimeSigner $signer = null;
33
    private array $dkimSignerOptions = [];
34
35
    /**
36
     * @param MessageFactoryInterface $messageFactory
37
     * @param MessageBodyRenderer $messageBodyRenderer
38
     * @param EventDispatcherInterface $eventDispatcher
39
     * @param TransportInterface $transport
40
     */
41 57
    public function __construct(
42
        MessageFactoryInterface $messageFactory,
43
        MessageBodyRenderer $messageBodyRenderer,
44
        EventDispatcherInterface $eventDispatcher,
45
        TransportInterface $transport
46
    ) {
47 57
        parent::__construct($messageFactory, $messageBodyRenderer, $eventDispatcher);
48 57
        $this->symfonyMailer = new SymfonyMailer($transport);
49
    }
50
51
    /**
52
     * Returns a new instance with the specified encryptor.
53
     *
54
     * @param SMimeEncrypter $encryptor The encryptor instance.
55
     *
56
     * @see https://symfony.com/doc/current/mailer.html#encrypting-messages
57
     */
58 2
    public function withEncryptor(SMimeEncrypter $encryptor): self
59
    {
60 2
        $new = clone $this;
61 2
        $new->encryptor = $encryptor;
62 2
        return $new;
63
    }
64
65
    /**
66
     * Returns a new instance with the specified signer.
67
     *
68
     * @param DkimSigner|object|SMimeSigner $signer The signer instance.
69
     * @param array $options The options for DKIM signer {@see DkimSigner}.
70
     *
71
     * @throws RuntimeException If the signer is not an instance of {@see DkimSigner} or {@see SMimeSigner}.
72
     *
73
     * @see https://symfony.com/doc/current/mailer.html#signing-messages
74
     */
75 4
    public function withSigner(object $signer, array $options = []): self
76
    {
77 4
        $new = clone $this;
78
79 4
        if ($signer instanceof DkimSigner) {
80 2
            $new->signer = $signer;
81 2
            $new->dkimSignerOptions = $options;
82 2
            return $new;
83
        }
84
85 2
        if ($signer instanceof SMimeSigner) {
86 1
            $new->signer = $signer;
87 1
            return $new;
88
        }
89
90 1
        throw new RuntimeException(sprintf(
91 1
            'The signer must be an instance of "%s" or "%s". The "%s" instance is received.',
92 1
            DkimSigner::class,
93 1
            SMimeSigner::class,
94 1
            $signer::class,
95 1
        ));
96
    }
97
98
    /**
99
     * {@inheritDoc}
100
     *
101
     * @throws TransportExceptionInterface If sending failed.
102
     */
103 7
    protected function sendMessage(MessageInterface $message): void
104
    {
105 7
        if (!($message instanceof Message)) {
106 1
            throw new RuntimeException(sprintf(
107 1
                'The message must be an instance of "%s". The "%s" instance is received.',
108 1
                Message::class,
109 1
                $message::class,
110 1
            ));
111
        }
112
113 6
        $message = $message->getSymfonyEmail();
114
115 6
        if ($this->encryptor !== null) {
116 2
            $message = $this->encryptor->encrypt($message);
117
        }
118
119 6
        if ($this->signer !== null) {
120 3
            $message = $this->signer instanceof DkimSigner
121 2
                ? $this->signer->sign($message, $this->dkimSignerOptions)
122 1
                : $this->signer->sign($message)
123 3
            ;
124
        }
125
126 6
        $this->symfonyMailer->send($message);
127
    }
128
}
129