VOOZH about

URL: https://deepwiki.com/hypervel/mail/4-core-architecture

⇱ Core Architecture | hypervel/mail | DeepWiki


Loading...
Menu

Core Architecture

This page provides a comprehensive architectural overview of the hypervel/mail system's core components and their interactions. It explains the major layers of the mail system, the primary classes and their responsibilities, and the flow of email processing from creation to delivery.

For detailed information about specific components:

System Overview

The hypervel/mail package is structured into five primary architectural layers:

LayerPrimary ClassesResponsibility
Factory LayerMailManagerCreates and configures Mailer instances based on configuration
Mail Processing LayerMailer, Mailable, PendingMailHandles email composition, sending, and queuing
Rendering LayerMarkdown, ComponentTagCompiler, Blade ViewsTransforms email content into HTML/text
Transport LayerTransportInterface implementationsDelivers emails via various protocols and services
Queue LayerSendQueuedMailable, QueueFactoryEnables asynchronous email delivery

The system follows a factory pattern where MailManager creates configured Mailer instances, which then process Mailable objects through the rendering pipeline before dispatching them via transports.

Sources: src/MailManager.php44-562 src/Mailer.php33-518 src/Mailable.php42-1518

Core Component Architecture


Diagram: Core Component Architecture and Class Relationships

This diagram maps the primary classes in the system and their interactions. Each component references the actual file paths where the classes are defined.

Sources: src/MailManager.php1-562 src/Mailer.php1-518 src/Mailable.php1-1518 src/PendingMail.php1-200 src/Markdown.php1-300

Primary Components

MailManager (Factory Layer)

The MailManager class (src/MailManager.php44-562) serves as the central factory for creating and configuring Mailer instances. It implements the Factory pattern and provides:

  • Driver Resolution: Resolves mailer configurations by name from mail.php config
  • Transport Creation: Creates Symfony TransportInterface instances via createSymfonyTransport() method
  • Connection Pooling: Wraps transports in TransportPoolProxy for poolable drivers
  • Custom Extensions: Allows registering custom transport drivers via extend() method
  • Global Address Management: Sets global from/reply-to/to addresses on mailers

Key methods:

For detailed information, see Mail Manager and Factory Pattern.

Sources: src/MailManager.php44-562

Mailer (Mail Processing Layer)

The Mailer class (src/Mailer.php33-518) implements both MailerContract and MailQueueContract interfaces. It is responsible for:

  • Sending Emails: Processes Mailable objects or view-based emails via send() method
  • View Rendering: Renders Blade/Markdown views using FactoryInterface
  • Queue Management: Queues Mailable objects for asynchronous delivery
  • Event Dispatching: Fires MessageSending and MessageSent events
  • Global Addresses: Applies global from/to/reply-to addresses to all messages
  • Transport Communication: Sends email through configured TransportInterface

Key methods:

For detailed information, see Mailer Component.

Sources: src/Mailer.php33-518

Mailable (Mail Processing Layer)

The Mailable class (src/Mailable.php42-1518) is the core abstraction for defining emails. It provides:

  • Fluent Configuration: Chainable methods for setting recipients, subject, attachments
  • Content Definition: Supports Blade views, Markdown, and raw HTML
  • Data Hydration: Optional envelope(), content(), headers(), attachments() methods
  • Queue Integration: Automatic queueing when implementing ShouldQueue
  • Testing Support: Extensive assertion methods for testing email content

The Mailable lifecycle:

  1. Optional build() method called via container
  2. Data hydration from envelope/headers/content/attachments methods
  3. View building (Markdown, Blade, or HTML)
  4. View data aggregation from properties and callbacks
  5. Sending via send() or queueing via queue()

Key methods:

For detailed information, see Working with Mailables and Mailable Lifecycle and Preparation.

Sources: src/Mailable.php42-1518

PendingMail (Mail Processing Layer)

The PendingMail class (src/PendingMail.php) implements the fluent builder pattern for specifying recipients and locale before sending. It is created by Mailer::to(), Mailer::cc(), and Mailer::bcc() methods.

Key characteristics:

  • Stores recipients (to/cc/bcc) and locale temporarily
  • Applies stored values to Mailable before sending
  • Provides send(), queue(), later() methods that accept Mailable instances
  • Enables clean syntax: Mail::to($user)->send(new OrderShipped($order))

For detailed information, see Fluent Mail Interface (PendingMail).

Sources: src/PendingMail.php1-200

Email Sending Flow


Diagram: Synchronous Email Sending Sequence

This diagram shows the complete flow from application code through to transport delivery for a synchronous email send operation.

Sources: src/Mailable.php163-182 src/Mailable.php1340-1353 src/Mailer.php215-264 src/Mailer.php453-459

Asynchronous Processing Flow

When a Mailable implements ShouldQueue or is explicitly queued, the system follows a different path:


Diagram: Asynchronous Email Sending via Queue

This diagram illustrates how Mailable objects are wrapped in SendQueuedMailable jobs and processed asynchronously by queue workers.

Sources: src/Mailable.php187-201 src/Mailable.php222-229 src/Mailer.php269-278 src/SendQueuedMailable.php1-100

Transport System Architecture

The transport layer abstracts the actual delivery mechanism. All transports implement Symfony's TransportInterface:

TransportClassUse Case
SMTPSymfony\Component\Mailer\Transport\Smtp\EsmtpTransportStandard SMTP servers
SESHypervel\Mail\Transport\SesTransportAWS Simple Email Service V1
SES V2Hypervel\Mail\Transport\SesV2TransportAWS Simple Email Service V2
SendmailSymfony\Component\Mailer\Transport\SendmailTransportLocal sendmail binary
MailgunVia Symfony BridgeMailgun API
PostmarkVia Symfony BridgePostmark API
LogHypervel\Mail\Transport\LogTransportDevelopment/debugging
ArrayHypervel\Mail\Transport\ArrayTransportTesting
FailoverSymfony\Component\Mailer\Transport\FailoverTransportAutomatic failover
RoundRobinSymfony\Component\Mailer\Transport\RoundRobinTransportLoad balancing

The MailManager creates transports via factory methods like createSmtpTransport(), createSesTransport(), etc. (src/MailManager.php155-188). For poolable transports, it wraps them in TransportPoolProxy for connection reuse (src/MailManager.php179-184).

For detailed information, see Transport System Overview and Transport Drivers.

Sources: src/MailManager.php155-425 src/Transport/SesTransport.php src/Transport/ArrayTransport.php src/Transport/LogTransport.php

Component Interaction Table

The following table summarizes how the core components interact with each other:

From ComponentTo ComponentInteraction MethodPurpose
ApplicationMailManagermailer(name)Get configured Mailer instance
MailManagerMailernew Mailer(...)Create Mailer with transport
MailManagerTransportInterfacecreateSymfonyTransport()Create transport from config
ApplicationMailablenew Mailable()Create email definition
MailableMailersend(mailer)Send email immediately
MailerPendingMailto(users)Create fluent recipient builder
PendingMailMailablesend(mailable)Send with pre-set recipients
MailableQueueFactoryqueue(factory)Queue for async delivery
MailerFactoryInterfacerender(view, data)Render email view
MailableMarkdownmarkdownRenderer()Render Markdown content
MailerTransportInterfacesend(message)Deliver email
SendQueuedMailableMailablehandle() -> send()Process queued email

Sources: src/MailManager.php87-148 src/Mailer.php113-120 src/Mailer.php215-264 src/Mailable.php163-182 src/Mailable.php187-201

Configuration Resolution

The MailManager resolves configuration through a multi-step process:

  1. Get Configuration (src/MailManager.php459-475):

    • Checks for legacy mail.driver format for BC compatibility
    • Otherwise reads from mail.mailers.{name} array
    • Parses connection URLs if present via ConfigurationUrlParser
  2. Create Transport (src/MailManager.php155-188):

    • Checks for custom creators registered via extend()
    • Determines transport method name (e.g., createSmtpTransport)
    • Wraps in TransportPoolProxy if driver is poolable
    • Calls appropriate factory method
  3. Configure Mailer (src/MailManager.php115-148):

    • Creates Mailer instance with name, views, transport, events
    • Sets queue factory if available
    • Applies global addresses (from, reply_to, to, return_path)

Sources: src/MailManager.php115-148 src/MailManager.php155-188 src/MailManager.php459-475

Event System

The mail system dispatches events at key points in the sending process:

EventTrigger PointFile ReferenceCan Prevent Send
MessageSendingBefore transport dispatchsrc/Mailer.php464-473Yes
MessageSentAfter successful sendsrc/Mailer.php478-483No

The MessageSending event includes a shouldSend() method that returns true by default. Event listeners can set this to false to prevent the email from being sent (src/Events/MessageSending.php).

Both events receive:

  • The Symfony Email object (MessageSending) or SentMessage (MessageSent)
  • The data array passed during sending

For detailed information, see Event System.

Sources: src/Mailer.php464-483 src/Events/MessageSending.php src/Events/MessageSent.php

Dependency Injection

The system leverages Hyperf's container for dependency injection:

Container-Resolved Dependencies:

Container-Aware Methods:

Sources: src/MailManager.php78-82 src/Mailer.php70-76 src/Mailable.php1343-1346

Thread Safety and Connection Pooling

For high-throughput applications, the system supports connection pooling via TransportPoolProxy (src/TransportPoolProxy.php):

Poolable Transports (src/MailManager.php71-73):

  • smtp, sendmail, mailgun, ses, ses_v2, postmark, resend, failover, roundrobin

Pool Configuration (via pool key in mailer config):

  • min_connections - Minimum pool size
  • max_connections - Maximum pool size
  • wait_timeout - Connection wait timeout
  • max_idle_time - Idle connection lifetime

The pool proxy manages connection lifecycle and provides thread-safe access to transport instances in coroutine environments.

For detailed information, see Transport Pooling.

Sources: src/MailManager.php71-73 src/MailManager.php179-184 src/TransportPoolProxy.php1-100