SMTPMailService   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 121
Duplicated Lines 0 %

Test Coverage

Coverage 92.68%

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 32
dl 0
loc 121
ccs 38
cts 41
cp 0.9268
rs 10
c 6
b 0
f 0
wmc 12

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 2
A getRecipients() 0 17 4
A getClient() 0 9 2
A send() 0 9 1
A disconnect() 0 6 1
A getSender() 0 11 2
1
<?php
2
3
namespace Kodus\Mail\SMTP;
4
5
use Kodus\Mail\MailService;
6
use Kodus\Mail\Message;
7
use Kodus\Mail\MIMEWriter;
8
use Kodus\Mail\SMTP\Authenticator\NoAuthenticator;
9
10
/**
11
 * This Mail Service implementation delivers Messages directly to an SMTP server.
12
 *
13
 * It will block the script while connecting and delivering the Message.
14
 */
15
class SMTPMailService implements MailService
16
{
17
    /**
18
     * @var SMTPConnector
19
     */
20
    private $connector;
21
22
    /**
23
     * @var SMTPAuthenticator
24
     */
25
    protected $authenticator;
26
27
    /**
28
     * @var string
29
     */
30
    protected $client_domain;
31
32
    /**
33
     * @var SMTPClient|null
34
     */
35
    private $client;
36
37
    /**
38
     * @param SMTPConnector          $connector     provides the SMTP connection
39
     * @param SMTPAuthenticator|null $authenticator performs SMTP authentication (or NULL to use `NoAuthenticator`)
40
     * @param string                 $client_domain client domain-name (provided in handshakes when connecting)
41 1
     */
42
    public function __construct(SMTPConnector $connector, ?SMTPAuthenticator $authenticator, string $client_domain)
43 1
    {
44 1
        $this->connector = $connector;
45 1
        $this->authenticator = $authenticator ?: new NoAuthenticator();
46 1
        $this->client_domain = $client_domain;
47
    }
48 1
49
    public function send(Message $message): void
50 1
    {
51 1
        $this->getClient()->sendMail(
52 1
            $this->getSender($message),
53 1
            $this->getRecipients($message),
54 1
            function ($socket) use ($message) {
55
                $writer = new MIMEWriter($socket);
56 1
57 1
                $writer->writeMessage($message);
58 1
            }
59 1
        );
60
    }
61
62
    /**
63
     * Internally disconnect the SMTP Client.
64
     *
65
     * Long-running services may wish to disconnect the SMTP client after sending a batch
66
     * of Messages, to avoid timeouts.
67
     */
68
    public function disconnect(): void
69
    {
70
        // NOTE: this will cause the SMTP Client instance will fall out of scope, which
71
        //       will trigger it's destructor, which will send QUIT and close the socket.
72
73
        $this->client = null;
74
    }
75
76
    /**
77
     * Connect and authenticate SMTP Client (if not already connected)
78
     *
79
     * @return SMTPClient
80
     */
81
    protected function getClient(): SMTPClient
82 1
    {
83
        if (! isset($this->client)) {
84 1
            $this->client = $this->connector->connect($this->client_domain);
85 1
86
            $this->authenticator->authenticate($this->client);
87 1
        }
88 1
89
        return $this->client;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->client could return the type null which is incompatible with the type-hinted return Kodus\Mail\SMTP\SMTPClient. Consider adding an additional type-check to rule them out.
Loading history...
90 1
    }
91
92
    /**
93
     * Determine the sender e-mail address from the "Sender" or first "From" field of the Message
94
     *
95
     * @param Message $message
96
     *
97
     * @return string sender e-mail address
98
     */
99
    private function getSender(Message $message): string
100 1
    {
101
        $sender = $message->getSender();
102 1
103
        if ($sender) {
104 1
            return $sender->getEmail();
105 1
        }
106
107
        $from = $message->getFrom();
108 1
109
        return $from[0]->getEmail();
110 1
    }
111
112
    /**
113
     * Extract recipient e-mail addresses from the "To", "CC" and "BCC" fields of the Message
114
     *
115
     * @param Message $message
116
     *
117
     * @return string[] list of recipient e-mail addresses
118
     */
119
    private function getRecipients(Message $message): array
120 1
    {
121
        $recipients = [];
122 1
123
        foreach ($message->getTo() as $recipient) {
124 1
            $recipients[] = $recipient->getEmail();
125 1
        }
126 1
127
        foreach ($message->getCC() as $recipient) {
128 1
            $recipients[] = $recipient->getEmail();
129 1
        }
130 1
131
        foreach ($message->getBCC() as $recipient) {
132 1
            $recipients[] = $recipient->getEmail();
133 1
        }
134 1
135
        return $recipients;
136 1
    }
137
}
138