Passed
Push — master ( 77c902...b2ee30 )
by Alexander
02:49
created

Mailer::sendMessage()   A

Complexity

Conditions 5
Paths 7

Size

Total Lines 24
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
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 14
cts 14
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 get_class;
21
use function sprintf;
22
23
/**
24
 * Mailer implements a mailer based on Symfony Mailer.
25
 *
26
 * @see https://github.com/symfony/mailer
27
 */
28
final class Mailer extends BaseMailer
29
{
30
    private SymfonyMailer $symfonyMailer;
31
    private ?SMimeEncrypter $encryptor = null;
32
33
    /**
34
     * @var DkimSigner|SMimeSigner|null
35
     */
36
    private $signer = null;
37
    private array $dkimSignerOptions = [];
38
39
    /**
40
     * @param MessageFactoryInterface $messageFactory
41
     * @param MessageBodyRenderer $messageBodyRenderer
42
     * @param EventDispatcherInterface $eventDispatcher
43
     * @param TransportInterface $transport
44
     */
45 57
    public function __construct(
46
        MessageFactoryInterface $messageFactory,
47
        MessageBodyRenderer $messageBodyRenderer,
48
        EventDispatcherInterface $eventDispatcher,
49
        TransportInterface $transport
50
    ) {
51 57
        parent::__construct($messageFactory, $messageBodyRenderer, $eventDispatcher);
52 57
        $this->symfonyMailer = new SymfonyMailer($transport);
53 57
    }
54
55
    /**
56
     * Returns a new instance with the specified encryptor.
57
     *
58
     * @param SMimeEncrypter $encryptor The encryptor instance.
59
     *
60
     * @see https://symfony.com/doc/current/mailer.html#encrypting-messages
61
     *
62
     * @return self
63
     */
64 2
    public function withEncryptor(SMimeEncrypter $encryptor): self
65
    {
66 2
        $new = clone $this;
67 2
        $new->encryptor = $encryptor;
68 2
        return $new;
69
    }
70
71
    /**
72
     * Returns a new instance with the specified signer.
73
     *
74
     * @param DkimSigner|SMimeSigner|object $signer The signer instance.
75
     * @param array $options The options for DKIM signer {@see DkimSigner}.
76
     *
77
     * @throws RuntimeException If the signer is not an instance of {@see DkimSigner} or {@see SMimeSigner}.
78
     *
79
     * @see https://symfony.com/doc/current/mailer.html#signing-messages
80
     *
81
     * @return self
82
     */
83 4
    public function withSigner(object $signer, array $options = []): self
84
    {
85 4
        $new = clone $this;
86
87 4
        if ($signer instanceof DkimSigner) {
88 2
            $new->signer = $signer;
89 2
            $new->dkimSignerOptions = $options;
90 2
            return $new;
91
        }
92
93 2
        if ($signer instanceof SMimeSigner) {
94 1
            $new->signer = $signer;
95 1
            return $new;
96
        }
97
98 1
        throw new RuntimeException(sprintf(
99 1
            'The signer must be an instance of "%s" or "%s". The "%s" instance is received.',
100 1
            DkimSigner::class,
101 1
            SMimeSigner::class,
102 1
            get_class($signer),
103
        ));
104
    }
105
106
    /**
107
     * {@inheritDoc}
108
     *
109
     * @throws TransportExceptionInterface If sending failed.
110
     */
111 7
    protected function sendMessage(MessageInterface $message): void
112
    {
113 7
        if (!($message instanceof Message)) {
114 1
            throw new RuntimeException(sprintf(
115 1
                'The message must be an instance of "%s". The "%s" instance is received.',
116 1
                Message::class,
117 1
                get_class($message),
118
            ));
119
        }
120
121 6
        $message = $message->getSymfonyEmail();
122
123 6
        if ($this->encryptor !== null) {
124 2
            $message = $this->encryptor->encrypt($message);
125
        }
126
127 6
        if ($this->signer !== null) {
128 3
            $message = $this->signer instanceof DkimSigner
129 2
                ? $this->signer->sign($message, $this->dkimSignerOptions)
130 3
                : $this->signer->sign($message)
131
            ;
132
        }
133
134 6
        $this->symfonyMailer->send($message);
135 5
    }
136
}
137