VOOZH about

URL: https://deepwiki.com/hypervel/mail/4.4-transport-drivers

⇱ Transport Drivers | hypervel/mail | DeepWiki


Loading...
Menu

Transport Drivers

This page documents the individual transport driver implementations available in the mail system. Each transport driver provides a specific mechanism for delivering emails, whether through external APIs, SMTP servers, or internal logging/testing facilities. For information about the overall transport architecture, pooling strategies, and failover mechanisms, see Transport System Overview.

Overview

The mail system supports multiple transport drivers, each implementing Symfony's TransportInterface contract. These drivers fall into several categories based on their purpose and delivery mechanism:

CategoryTransportsPurpose
DevelopmentArrayTransport, LogTransportTesting and debugging without sending real emails
AWS SESSesTransport, SesV2TransportAmazon Simple Email Service integration (v1 and v2 APIs)
SMTPEsmtpTransportDirect SMTP server connections with TLS support
LocalSendmailTransportSystem sendmail binary integration
API ServicesMailgunTransport, PostmarkTransportThird-party email service providers
CompositeFailoverTransport, RoundRobinTransportHigh-availability patterns using multiple transports

Sources: Diagram 3 from high-level architecture

Transport Implementation Hierarchy


All transport drivers implement the TransportInterface::send() method, which accepts a RawMessage and optional Envelope, returning a SentMessage instance. Most transports also implement Stringable to provide a string identifier for logging and debugging.

Sources: src/Transport/ArrayTransport.php14 src/Transport/LogTransport.php15 src/Transport/SesTransport.php16 src/Transport/SesV2Transport.php16

Development Transports

ArrayTransport

The ArrayTransport stores all sent messages in an in-memory collection without actually delivering them. This is the primary transport for testing email functionality.

Class: Hypervel\Mail\Transport\ArrayTransport


Key Methods:

MethodPurpose
send(RawMessage, ?Envelope)Stores message in collection and returns SentMessage
messages()Returns collection of all sent messages for assertions
flush()Clears all stored messages and returns new empty collection
__toString()Returns string identifier 'array'

Implementation Details:

The transport maintains a protected Collection property that accumulates all sent messages src/Transport/ArrayTransport.php19 When send() is called, it creates a new SentMessage instance and appends it to the collection src/Transport/ArrayTransport.php31 The envelope is created automatically if not provided using Envelope::create($message).

The flush() method is particularly useful in test suites where you need to reset state between test cases src/Transport/ArrayTransport.php45-48

Sources: src/Transport/ArrayTransport.php1-57

LogTransport

The LogTransport writes email messages to a PSR-3 logger instead of sending them. This is useful for development environments where you want to verify email content without actual delivery.

Class: Hypervel\Mail\Transport\LogTransport


Key Features:

  1. Quoted-Printable Decoding: The transport automatically detects and decodes quoted-printable encoded content to make log output human-readable src/Transport/LogTransport.php41-43

  2. Multipart Message Handling: For multipart messages (e.g., HTML with attachments), it extracts the boundary delimiter and processes each part separately src/Transport/LogTransport.php29-40

  3. Boundary Extraction: Uses Str::of() fluent string operations to parse the boundary from Content-Type headers src/Transport/LogTransport.php30-35

Decoding Logic:

The decodeQuotedPrintableContent() method splits message parts at the double CRLF separator (\r\n\r\n), applies quoted_printable_decode() to the content portion, and reassembles the message src/Transport/LogTransport.php53-64

Constructor:

The transport requires a LoggerInterface implementation via constructor injection src/Transport/LogTransport.php20-23 which is typically provided by Hyperf's PSR-11 container.

Sources: src/Transport/LogTransport.php1-82

AWS SES Transports

The system provides two AWS Simple Email Service transport implementations: SesTransport for the v1 API and SesV2Transport for the v2 API. Both extend Symfony's AbstractTransport base class.

Architecture Comparison


SesTransport (v1 API)

Class: Hypervel\Mail\Transport\SesTransport

The v1 transport uses the Aws\Ses\SesClient and calls the sendRawEmail API method.

Constructor:

__construct(SesClient $ses, array $options = [])

The $options array contains additional SES-specific configuration that gets merged with each send request src/Transport/SesTransport.php21-26

Send Implementation:

The doSend() method performs these steps:

  1. Metadata Extraction: Iterates through message headers to find MetadataHeader instances, converting them to SES tags src/Transport/SesTransport.php32-37

  2. API Call: Invokes ses->sendRawEmail() with merged options src/Transport/SesTransport.php41-56:

    • Source: Envelope sender address
    • Destinations: Collection of recipient addresses mapped to strings
    • RawMessage.Data: Complete RFC-compliant email message
    • Tags: Name-value pairs from metadata headers
  3. Error Handling: Catches AwsException and wraps it in Symfony's TransportException with the AWS error message src/Transport/SesTransport.php57-65

  4. Message ID Headers: Adds X-Message-ID and X-SES-Message-ID headers to the original message using the ID returned from SES src/Transport/SesTransport.php67-72

API Payload Structure (v1):

FieldSourceType
Sourceenvelope->getSender()String (email address)
Destinationsenvelope->getRecipients()Array of strings
RawMessage.Datamessage->toString()Base64-encoded message
TagsMetadataHeader instancesArray of name-value pairs

Sources: src/Transport/SesTransport.php1-106

SesV2Transport (v2 API)

Class: Hypervel\Mail\Transport\SesV2Transport

The v2 transport uses the Aws\SesV2\SesV2Client and calls the sendEmail API method with a restructured payload format.

Key Differences from v1:

  1. API Method: Uses ses->sendEmail() instead of sendRawEmail() src/Transport/SesV2Transport.php41

  2. Metadata Field: Tags are stored in EmailTags rather than Tags src/Transport/SesV2Transport.php35

  3. Recipient Structure: Recipients are nested under Destination.ToAddresses instead of flat Destinations src/Transport/SesV2Transport.php46-51

  4. Content Wrapping: Raw message data is wrapped in Content.Raw.Data instead of RawMessage.Data src/Transport/SesV2Transport.php53-57

API Payload Structure (v2):

FieldSourceType
Sourceenvelope->getSender()String (email address)
Destination.ToAddressesenvelope->getRecipients()Array of strings
Content.Raw.Datamessage->toString()Base64-encoded message
EmailTagsMetadataHeader instancesArray of name-value pairs

String Representation:

Sources: src/Transport/SesV2Transport.php1-110

SES Transport Options

Both SES transports support runtime option management:

MethodPurpose
getOptions()Returns current options array
setOptions(array)Replaces options array and returns it
ses()Returns the underlying SesClient or SesV2Client instance

These options can include SES-specific parameters like:

  • ConfigurationSetName: Track sending statistics
  • ReturnPath: Bounce handling address
  • SourceArn: IAM role for sending authorization
  • ReturnPathArn: IAM role for bounce handling

Sources: src/Transport/SesTransport.php76-97 src/Transport/SesV2Transport.php79-101

Metadata Header Handling

Both SES transports convert Symfony's MetadataHeader instances into SES tags for tracking and categorization:


The metadata extraction loop src/Transport/SesTransport.php32-37 and src/Transport/SesV2Transport.php32-37 checks each header using instanceof MetadataHeader, then accesses the key-value pair through getKey() and getValue() methods.

Sources: src/Transport/SesTransport.php32-38 src/Transport/SesV2Transport.php32-38

Other Available Transports

While not detailed in this document due to file availability, the following transports are also supported through Symfony Mailer integration:

SMTP Transport

Package: symfony/mailer
Class: Symfony\Component\Mailer\Transport\Smtp\EsmtpTransport

Provides direct SMTP connections with TLS/STARTTLS support. Configured via DSN: smtp://user:pass@host:port.

Sendmail Transport

Package: symfony/mailer
Class: Symfony\Component\Mailer\Transport\SendmailTransport

Executes the local system's sendmail binary. Configured via DSN: sendmail://default.

Mailgun Transport

Package: symfony/mailgun-mailer
Class: Symfony\Component\Mailer\Bridge\Mailgun\Transport\MailgunApiTransport

Integrates with Mailgun's HTTP API. Requires API key and domain configuration.

Postmark Transport

Package: symfony/postmark-mailer
Class: Symfony\Component\Mailer\Bridge\Postmark\Transport\PostmarkApiTransport

Integrates with Postmark's HTTP API. Requires server token configuration.

Sources: Diagram 3 from high-level architecture

Transport Interface Contract

All transports must implement the core TransportInterface contract from Symfony Mailer:


Method Contract:

  • Input: RawMessage (the complete RFC-compliant email) and optional Envelope (sender/recipients)
  • Output: SentMessage (wrapper containing the original message, envelope, and transport-specific metadata)
  • Exceptions: May throw TransportException on delivery failure

Envelope Creation: If no envelope is provided, transports create one using Envelope::create($message), which extracts sender/recipients from message headers.

Sources: src/Transport/ArrayTransport.php29-32 src/Transport/LogTransport.php25-48 src/Transport/SesTransport.php28-73 src/Transport/SesV2Transport.php28-77

Transport String Identifiers

Each transport provides a string identifier via __toString() that is used in logging, debugging, and configuration:

Transport ClassIdentifier
ArrayTransport'array'
LogTransport'log'
SesTransport'ses'
SesV2Transport'ses-v2'
EsmtpTransport'smtp'
SendmailTransport'sendmail'
MailgunApiTransport'mailgun'
PostmarkApiTransport'postmark'

These identifiers appear in configuration files and are used by the MailManager for transport resolution. See Mail Manager and Factory Pattern for details on how these identifiers map to transport instances.

Sources: src/Transport/ArrayTransport.php53-56 src/Transport/LogTransport.php78-81 src/Transport/SesTransport.php102-105 src/Transport/SesV2Transport.php106-109

Configuration Examples

Transport drivers are typically configured in config/mail.php and referenced by the MailManager. For complete configuration documentation, see Configuration.

ArrayTransport (testing):


LogTransport (development):


SesTransport (production):


SesV2Transport (production with v2 API):


The MailManager uses these configurations to instantiate the appropriate transport driver when creating Mailer instances. See Mail Manager and Factory Pattern for the resolution mechanism.