Data source: SMTP
1Presentation
This data source is a minimal SMTP client, which sends emails by connecting to a configurable SMTP relay: an external server (Gmail, Mailgun, Mailjet, Brevo…) or a local one (Postfix/Exim on smtp://localhost).
It does not depend on any external library (it uses PHP sockets directly) and connects to a single relay. Direct delivery to the recipient's MX server is not supported: a relay is always required.
Like the Slack or Discord data sources, this is a write-only data source: read methods (get(), read(), find()…) are inert or throw an exception.
If you have correctly configured the connection parameters, Temma automatically creates an object of type \Temma\Datasources\Smtp. By convention, we will assume that you named this connection smtp in the etc/temma.php file (see the configuration documentation).
In controllers, the connection is then available by writing:
$smtp = $this->smtp;
In the other objects managed by the dependency injection component, the connection is accessible by writing:
$smtp = $loader->dataSources->smtp;
$smtp = $loader->dataSources['smtp'];
2Configuration
2.1DSN
In the etc/temma.php file (see the configuration documentation), you declare the DSN (Data Source Name) used to connect to the SMTP relay. Three schemes are available, depending on the connection encryption mode:
-
smtp://[user:password@]server[:port]
Cleartext connection. Default port: 25. -
smtp+tls://[user:password@]server[:port]
Encrypted connection via STARTTLS (encryption is negotiated after the connection). Default port: 587. -
smtps://[user:password@]server[:port]
Encrypted connection from the start (implicit TLS). Default port: 465.
Authentication is optional: it is only triggered if the DSN contains a user:password pair (PLAIN or LOGIN mechanisms, preferably over an encrypted connection). A local relay such as smtp://localhost:25 therefore connects without authentication.
Examples:
// Gmail relay with STARTTLS and authentication
'smtp+tls://user:password@smtp.gmail.com:587'
// local relay without authentication
'smtp://localhost:25'
The data source factory recognizes the smtp://, smtp+tls:// and smtps:// prefixes. The generic form is also usable: [\Temma\Datasources\Smtp]smtp://….
2.2Optional parameters
The DSN accepts optional query parameters:
- helo: name announced in the EHLO/HELO command.
- timeout: network timeout, in seconds.
- verify: TLS certificate verification (1 to enable, 0 to disable; enabled by default).
smtp+tls://user:pass@smtp.example.com:587?helo=mysite.com&timeout=10&verify=1
2.3Construction from parameters
A password (or username) containing special characters is cumbersome to encode in a DSN. You can then describe the connection using separate parameters instead of a DSN. The accepted parameters are: host, port, user, password, security (none, starttls or tls), helo, timeout and verify.
'x-email' => [
'smtp' => [
'host' => 'smtp.example.com',
'port' => 587,
'user' => 'user@example.com',
'password' => 'p@ss:w/rd!',
'security' => 'starttls',
],
],
This form is equivalent to the corresponding DSN. It is notably used by the Email helper through the smtp directive in array form.
3Envelope and message
Sending an SMTP email relies on two distinct notions:
- the envelope: the sender (MAIL FROM) and the list of recipients (RCPT TO) actually used by the SMTP protocol;
- the message: the full RFC 5322 stream (From, To, Cc, Subject, Date, Message-ID, MIME headers… and the body).
The envelope and the message are independent. For example, blind carbon copy recipients appear in the envelope (so they get delivered) but not in the message headers (no Bcc header).
The data source handles SMTP transparency (CRLF line-ending normalization and "dot-stuffing" of body lines starting with a dot). You provide a normal RFC 5322 message; the protocol-level compliance is automatic.
4Sending
4.1set()
The set() method is the normal sending path (it is the one used by the Email helper). It expects a structured array value describing the envelope and the message:
$smtp->set($id, [
'from' => 'sender@example.com',
'recipients' => ['dest1@example.com', 'dest2@example.com'],
'message' => $rawRfc5322Message,
]);
- from: envelope sender, used for MAIL FROM.
- recipients: list of recipients, one RCPT TO per entry.
- message: full RFC 5322 stream, sent in DATA.
The first parameter ($id) is a simple identifier (Message-ID or application identifier), used for logging.
This "portable" structure is what makes it possible to use any data source as a transport: an SMTP source delivers the message, a File or S3 source archives it, a message queue source enqueues it, and so on. The envelope travels in the value, never in the options nor in the key.
4.2write()
The write() method offers raw access: the value is directly the RFC 5322 stream, and the envelope is passed in the third parameter ($options).
$smtp->write($id, $rawRfc5322Message, [
'from' => 'sender@example.com',
'recipients' => ['dest1@example.com', 'dest2@example.com'],
]);
Sending is immediate in both cases.
5Using the Email helper
In practice, this data source mostly serves as a transport for the Email helper. You then call neither set() nor write() yourself: the helper builds the message and the envelope, then delegates delivery. Refer to the Sending through an SMTP relay section of the Email helper.