VOOZH about

URL: https://deepwiki.com/hypervel/mail/5.1-creating-mailable-classes

⇱ Creating Mailable Classes | hypervel/mail | DeepWiki


Loading...
Menu

Creating Mailable Classes

Purpose and Scope

This document explains how to create and configure mailable classes in the hypervel/mail package. It covers the Mailable base class structure, the mailable lifecycle from creation to delivery, content definition methods (build(), envelope(), content(), attachments()), view rendering options, and basic sending mechanisms.

For details on the Envelope class and metadata configuration, see Envelope and Metadata. For attachment handling specifics, see Attachments. For the fluent PendingMail interface used to configure recipients at send-time, see Fluent Mail Interface.


Mailable Class Structure

The Mailable class (src/Mailable.php42) serves as the base class for all email messages in the system. It implements the MailableContract interface and provides a rich API for defining email content, recipients, and behavior.

Core Components


Sources: src/Mailable.php42-46 src/Mailable.php48-151

Property Categories

CategoryPropertiesPurpose
Recipients$from, $to, $cc, $bcc, $replyToStore recipient addresses as arrays of ['address' => ..., 'name' => ...]
Content$view, $markdown, $html, $textViewDefine which template/content to render
Metadata$subject, $locale, $theme, $mailerControl message properties and behavior
Attachments$attachments, $rawAttachments, $diskAttachmentsStore file attachments in various formats
View Data$viewData, $callbacksPass data to templates and modify Symfony message
Tags/Metadata$tags, $metadataAdd transport-specific headers (SES, Mailgun, etc.)

Sources: src/Mailable.php48-151


Mailable Lifecycle

The mailable lifecycle consists of distinct phases from instantiation through delivery. Understanding this flow is essential for proper mailable implementation.

Lifecycle State Diagram


Sources: src/Mailable.php163-182 src/Mailable.php1337-1350 src/Mailable.php1355-1468

Preparation Pipeline

The prepareMailableForDelivery() method (src/Mailable.php1337-1350) orchestrates the hydration of mailable content through a specific call sequence:


Sources: src/Mailable.php1337-1350 src/Mailable.php1355-1376 src/Mailable.php1381-1414 src/Mailable.php1419-1450 src/Mailable.php1455-1468


Defining Email Content

Mailables support two patterns for defining content: the legacy build() method and the modern method trio (envelope(), content(), attachments()). Both patterns can coexist, with the modern methods taking precedence during hydration.

The build() Method Pattern

The build() method is called during preparation (src/Mailable.php1339-1344) and allows configuring the mailable using fluent method calls:


The build() method is invoked via dependency injection if the container supports it, otherwise via direct call (src/Mailable.php1341-1343).

Sources: src/Mailable.php1339-1344

The envelope() Method Pattern

The envelope() method returns an Envelope object defining recipients and metadata. During hydration (src/Mailable.php1381-1414), the system:

  1. Calls the envelope() method if it exists
  2. Extracts the from address and applies it via $this->from() (src/Mailable.php1389-1391)
  3. Iterates through to, cc, bcc, replyTo arrays and applies each (src/Mailable.php1393-1397)
  4. Sets the subject if provided (src/Mailable.php1399-1401)
  5. Adds all tags and metadata (src/Mailable.php1403-1409)
  6. Executes callbacks on the Symfony message (src/Mailable.php1411-1413)

Sources: src/Mailable.php1381-1414

The content() Method Pattern

The content() method returns a Content object specifying which view to render. During hydration (src/Mailable.php1419-1450), the system:

  1. Calls the content() method if it exists
  2. Sets $this->view if $content->view is provided (src/Mailable.php1427-1429)
  3. Sets $this->view if $content->html is provided (src/Mailable.php1431-1433)
  4. Sets $this->textView if $content->text is provided (src/Mailable.php1435-1437)
  5. Sets $this->markdown if $content->markdown is provided (src/Mailable.php1439-1441)
  6. Sets $this->html via html() if $content->htmlString is provided (src/Mailable.php1443-1445)
  7. Merges view data from $content->with (src/Mailable.php1447-1449)

Sources: src/Mailable.php1419-1450

The attachments() Method Pattern

The attachments() method returns an array or single Attachment object. During hydration (src/Mailable.php1455-1468), the system:

  1. Calls the attachments() method if it exists
  2. Wraps single objects in an array
  3. Converts Attachable objects to Attachment objects
  4. Calls $this->attach() for each attachment

Sources: src/Mailable.php1455-1468

Method Precedence

Both patterns can coexist in a single mailable. The execution order is:

  1. build() method executes first (src/Mailable.php1339-1344)
  2. envelope() hydration executes second (src/Mailable.php1381-1414)
  3. content() hydration executes third (src/Mailable.php1419-1450)
  4. attachments() hydration executes last (src/Mailable.php1455-1468)

Later methods override earlier settings (e.g., envelope()->subject() overrides build()->subject()).

Sources: src/Mailable.php1337-1350


View Rendering Options

The buildView() method (src/Mailable.php256-281) determines which template format to render based on which properties are set. The system supports four content types with a specific precedence order.

View Resolution Flow


Sources: src/Mailable.php256-281

HTML String Rendering

When $this->html is set (src/Mailable.php758-760), the view builder returns an array with an HtmlString instance for HTML content and optional plain text (src/Mailable.php258-263):

The HtmlString wrapper prevents double-escaping during rendering.

Sources: src/Mailable.php258-263 src/Mailable.php755-760

Markdown Rendering

When $this->markdown is set (src/Mailable.php733-739), the view builder calls buildMarkdownView() (src/Mailable.php288-296) which returns closures for both HTML and text rendering:

  1. HTML closure: buildMarkdownHtml() (src/Mailable.php323-329) calls Markdown::render()
  2. Text closure: buildMarkdownText() (src/Mailable.php334-348) calls Markdown::renderText() or uses $this->textView

The Markdown instance is configured with the mailable's theme (src/Mailable.php353-363).

Sources: src/Mailable.php265-267 src/Mailable.php288-296 src/Mailable.php323-329 src/Mailable.php334-348 src/Mailable.php353-363

Blade Template Rendering

When $this->view is set (src/Mailable.php744-750), the view builder returns either:

Sources: src/Mailable.php269-278 src/Mailable.php744-750


View Data

The mailable system provides multiple mechanisms for passing data to templates. The buildViewData() method (src/Mailable.php303-318) assembles data from three sources with specific precedence.

View Data Assembly Pipeline


Sources: src/Mailable.php303-318

Data Source Priority

The three data sources are merged in this order (src/Mailable.php303-318):

  1. Base $viewData: Initialized to [] (src/Mailable.php106)
  2. Static callback result: If $viewDataCallback is set (src/Mailable.php158), it's invoked and merged (src/Mailable.php307-309)
  3. Public properties: Reflected public properties (excluding those declared in Mailable itself) are auto-merged (src/Mailable.php311-315)

Later sources override earlier ones (e.g., a public property $user overrides $viewData['user']).

Adding View Data

MethodSyntaxStorage LocationCode Reference
with()$this->with('key', $value) or $this->with(['key' => $value])$this->viewDatasrc/Mailable.php776-785
withXyz() magic$this->withUser($user) (automatically calls with('user', $user))$this->viewDatasrc/Mailable.php1503-1514
Public propertiespublic User $user; in class definitionProperty itselfsrc/Mailable.php311-315
Global callbackMailable::buildViewDataUsing(fn($m) => ['key' => 'val'])Static propertysrc/Mailable.php1493-1496

Sources: src/Mailable.php303-318 src/Mailable.php776-785 src/Mailable.php1493-1496 src/Mailable.php1503-1514


Recipient Configuration

The Mailable class provides fluent methods for configuring recipients. All recipients are stored internally as normalized arrays (src/Mailable.php600-623).

Recipient Methods


Sources: src/Mailable.php514-623

Address Normalization

The setAddress() method (src/Mailable.php600-623) processes recipients through several steps:

  1. Convert to array via addressesToArray() (src/Mailable.php628-637)
  2. Normalize each recipient via normalizeRecipient() (src/Mailable.php642-664)
  3. Append to the property array
  4. Deduplicate by address using Collection operations (src/Mailable.php615-620)

The normalizeRecipient() method handles multiple input formats:

Input FormatNormalized OutputCode Reference
String 'user@example.com'{email: 'user@example.com'}src/Mailable.php653-655
Array ['email' => '...', 'name' => '...']{email: '...', name: '...'}src/Mailable.php644-651
Symfony\Component\Mime\Address{email: getAddress(), name: getName()}src/Mailable.php656-658
Hypervel\Mail\Mailables\Address{email: address, name: name}src/Mailable.php659-661
Other objectsReturned as-issrc/Mailable.php663

Sources: src/Mailable.php600-664

Locale Preference

When calling to(), if the recipient implements HasLocalePreference, the mailable's locale is automatically set (src/Mailable.php532-534):

This enables automatic localization based on user preferences.

Sources: src/Mailable.php530-537


Sending Mailables

The Mailable class provides methods for both synchronous and asynchronous delivery.

Synchronous Sending

The send() method (src/Mailable.php163-182) performs immediate delivery:


The callback passed to Mailer::send() (src/Mailable.php172-180) executes a chain of builder methods:

  1. buildFrom() - Adds the from address (src/Mailable.php368-375)
  2. buildRecipients() - Adds to/cc/bcc/replyTo (src/Mailable.php380-389)
  3. buildSubject() - Sets subject or generates from class name (src/Mailable.php394-403)
  4. buildTags() - Adds TagHeader instances (src/Mailable.php448-457)
  5. buildMetadata() - Adds MetadataHeader instances (src/Mailable.php462-471)
  6. runCallbacks() - Executes stored callbacks on Symfony message (src/Mailable.php476-483)
  7. buildAttachments() - Attaches all files (src/Mailable.php408-443)

Sources: src/Mailable.php163-182 src/Mailable.php172-180 src/Mailable.php368-483

Asynchronous Sending (Queuing)

The queue() method (src/Mailable.php187-201) delegates to the queue system:


Sources: src/Mailable.php187-217

The newQueuedJob() method (src/Mailable.php222-230) creates a SendQueuedMailable instance and applies middleware:

  1. Retrieves SendQueuedMailable from the container (src/Mailable.php224-225)
  2. Applies middleware from middleware() method if it exists (src/Mailable.php227)
  3. Applies middleware from $this->middleware property if set (src/Mailable.php228)

Sources: src/Mailable.php222-230

Queue Properties

The mailable respects optional properties for queue configuration:

PropertyTypePurposeCode Reference
$connection?stringSpecifies which queue connection to usesrc/Mailable.php193 src/Mailable.php208
$queue?stringSpecifies which queue name to push tosrc/Mailable.php195 src/Mailable.php210
$delayDateTimeInterface|DateInterval|intSpecifies delivery delaysrc/Mailable.php189
$middlewarearrayArray of queue middleware classessrc/Mailable.php228

Sources: src/Mailable.php187-230


Rendering Without Sending

The render() method (src/Mailable.php237-249) generates the HTML output without sending:


This is useful for previewing emails or testing without sending. The method retrieves the Mailer from the container and delegates to Mailer::render() (src/Mailable.php242-247).

Sources: src/Mailable.php237-249


Additional Configuration Methods

Subject

The subject() method (src/Mailable.php714-719) sets the email subject. If no subject is set, buildSubject() generates one from the class name using Str::title(Str::snake(class_basename($this), ' ')) (src/Mailable.php399).

Sources: src/Mailable.php714-719 src/Mailable.php394-403

Priority

The priority() method (src/Mailable.php502-509) sets message priority (1 = highest, 5 = lowest) by adding a callback that calls $message->priority($level) on the Symfony message.

Sources: src/Mailable.php502-509

Locale

The locale() method (src/Mailable.php488-493) sets the locale for template rendering. This is automatically set when calling to() with a HasLocalePreference recipient (src/Mailable.php532-534).

Sources: src/Mailable.php488-493 src/Mailable.php532-534

Mailer Selection

The mailer() method (src/Mailable.php1473-1478) specifies which mailer configuration to use. During sending, if a Factory is provided, it resolves the named mailer (src/Mailable.php168-170).

Sources: src/Mailable.php1473-1478 src/Mailable.php168-170

Tags and Metadata

The tag() method (src/Mailable.php952-957) adds transport-specific tags (supported by SES, Mailgun, Postmark). The metadata() method (src/Mailable.php971-976) adds key-value metadata headers.

Both are applied during message construction via buildTags() (src/Mailable.php448-457) and buildMetadata() (src/Mailable.php462-471), which add TagHeader and MetadataHeader instances to the Symfony message.

Sources: src/Mailable.php952-957 src/Mailable.php971-976 src/Mailable.php448-471

Symfony Message Callbacks

The withSymfonyMessage() method (src/Mailable.php1483-1488) registers callbacks that receive the Symfony\Component\Mime\Email instance. These are executed during runCallbacks() (src/Mailable.php476-483).

Sources: src/Mailable.php1483-1488 src/Mailable.php476-483


Code Entity Map

This table maps conceptual mailable features to specific code entities:

FeaturePrimary Class/MethodFile Location
Base mailable classMailablesrc/Mailable.php42
Mailable preparationprepareMailableForDelivery()src/Mailable.php1337-1350
User-defined configurationbuild() methodUser class (called at src/Mailable.php1339-1344)
Envelope hydrationensureEnvelopeIsHydrated()src/Mailable.php1381-1414
Content hydrationensureContentIsHydrated()src/Mailable.php1419-1450
Attachment hydrationensureAttachmentsAreHydrated()src/Mailable.php1455-1468
View resolutionbuildView()src/Mailable.php256-281
View data assemblybuildViewData()src/Mailable.php303-318
Markdown renderingbuildMarkdownView()src/Mailable.php288-296
Synchronous sendsend()src/Mailable.php163-182
Asynchronous sendqueue(), later()src/Mailable.php187-217
Queue job creationnewQueuedJob()src/Mailable.php222-230
Queue job classSendQueuedMailableReferenced at src/Mailable.php225
Rendering onlyrender()src/Mailable.php237-249
Recipient normalizationsetAddress(), normalizeRecipient()src/Mailable.php600-664
Message constructionbuildFrom(), buildRecipients(), buildSubject(), etc.src/Mailable.php368-483

Sources: src/Mailable.php

Refresh this wiki

On this page