Mailer Service
Table of contents
- Overview
- Key Components
- A. MailerService
- B. AbstractMailer
- C. CustomMailer
- D. Templates and Layouts
- E. Logging
- F. Attachments
- G. Environment Configuration
- H. Example Use Case
- I. Notes
- Using sendTemplate() in Chappy.php
- Customizing sendTo() with Advanced Parameters
- Attachment Management
1. Overview Table of Contents
The Chappy.php E-mail system is a modular, extensible implementation built on Symfony Mailer. It allows developers to send fully styled, template-driven emails with optional layouts and attachments. Emails are logged for auditing, and inline CSS rendering is supported via CssToInlineStyles.
2. Key Components Table of Contents
A. MailerService
Central service that composes and sends emails.
Features:
- Send raw HTML or styled template-based emails
- Inline CSS support
- Optional plain text alternative
- Full logging of email attempts
- Attachment support
Paths Used:
- Layouts:
resources/views/emails/layouts/
- Templates:
resources/views/emails/
- Stylesheets:
resources/css/
B. AbstractMailer
Base class for creating structured mailers. Encapsulates logic for defining recipient, template, subject, and data payload.
Default behavior:
- Uses
MailerService::sendTemplate
- Layout:
default
- Style:
default
C. Custom Mailers (e.g. WelcomeMailer
)
Extend AbstractMailer
to create reusable mail definitions.
class WelcomeMailer extends AbstractMailer {
protected function getData(): array {
return ['user' => $this->user];
}
protected function getSubject(): string {
return 'Welcome to ' . env('SITE_TITLE');
}
protected function getTemplate(): string {
return 'welcome';
}
}
Built In Mailers
- AccountDeactivatedMailer - Notifies user when account is deactivated. More info in UserService section.
- PasswordResetMailer - Notifies user when password needs to be reset
- UpdatePasswordMailer - Notifies user when password is updated
- WelcomeMailer - Sent when user creates an account
Example Usage
WelcomeMailer::sendTo($user);
Build Your Own Mailer Run the following command:
php console make:mailer MyMailer
File will be generated at app\CustomMailers
. The modify the getData
, getSubject
, and getTemplate
functions.
D. Templates and Layouts
Making a template:
php console make:email
You can find the new template at resources/views/emails/
// Example: welcome.php (template)
<h1>Welcome, <?= $user->name ?>!</h1>
<p>Thank you for signing up.</p>
Making a layout
php console make:email-layout
// Example: default.php (layout)
<html>
<body>
<?= $content ?>
</body>
</html>
You can find the layout at resources/views/emails/layouts/
Adding Styles
php console make:styles
Your styles can be found at resources/css/
Optional .txt files with the same name as the template can be used for plain text versions.
E. Logging
Every email attempt (success or failure) is logged using the framework’s Logger class. Fields include:
- Status (success or failed)
- Timestamp
- Recipient
- Subject
- HTML body (escaped)
- Text body (if provided)
- Template name
- DSN transport
- Error message (if failed)
- Attachment metadata
- Logs use the error or info log levels.
F. Attachments
Use the Attachments
class to prepare data arrays.
Attachments::path($emailAttachment);
Attachments::content($emailAttachment);
Pass these into the sendTemplate()
method or buildAndSend()
.
G. Environment Configuration
Set the following in your .env file:
MAILER_DSN=smtp://user:pass@smtp.mailtrap.io:2525
MAIL_FROM_ADDRESS=noreply@example.com
H. Example Use Case
$user = Users::findById(1);
WelcomeMailer::sendTo($user);
This sends a templated welcome email using the default layout and style.
I. Notes
- HTML and text versions improve deliverability
- CSS is inlined to ensure better rendering across clients
- All template rendering uses output buffering and extract() for dynamic data injection
3. 📬 Using sendTemplate()
in Chappy.php Table of Contents
The MailerService::sendTemplate()
method allows you to send HTML (and optionally plain-text) emails using reusable templates, layouts, and CSS stylesheets. This method is powerful and flexible, supporting both embedded and path-based file attachments.
🧠 Basic Usage
$mail = new MailerService();
$user = Users::findById(1);
$mail->sendTemplate(
$user->email,
'Welcome Subject',
'welcome', // Template name (without extension)
['user' => $user], // Data passed to template
'default', // Layout name
[], // Attachments
MailerService::FRAMEWORK_LAYOUT_PATH,
MailerService::FRAMEWORK_TEMPLATE_PATH,
'default', // CSS filename (no extension)
MailerService::FRAMEWORK_STYLES_PATH
);
A. Test Case Examples
1. Basic HTML E-mail
Sends a raw HTML string without templates:
$mail->send($user->email, 'test_email_is_sent', '<p>Your account is ready!</p>');
2. HTML Template with Layout and Stylesheet
$mail->sendTemplate(
$user->email,
'test_email_template',
'welcome', // welcome.php under views/emails/
['user' => $user],
'default', // default.php under views/emails/layouts/
[],
MailerService::FRAMEWORK_LAYOUT_PATH,
MailerService::FRAMEWORK_TEMPLATE_PATH,
'default', // default.css under views/emails/styles/
MailerService::FRAMEWORK_STYLES_PATH
);
3. HTML + Text Email from Dual Template
Includes welcome_text.txt
if found in views/emails/
:
$mail->sendTemplate(
$user->email,
'test_email_text_template',
'welcome_text',
['user' => $user->username],
'default',
[],
MailerService::FRAMEWORK_LAYOUT_PATH,
MailerService::FRAMEWORK_TEMPLATE_PATH,
'default',
MailerService::FRAMEWORK_STYLES_PATH
);
B. Adding Attachments
1. Single Attachment
$attachment = EmailAttachments::findById(2);
$mail->sendTemplate(
$user->email,
'test_email_single_attachment_and_template',
'welcome',
['user' => $user->username],
'default',
Attachments::content($attachment),
...
);
2. Multiple Attachments (Content + Path)
$attachments = [
Attachments::content($attachment2),
Attachments::path($attachment1)
];
$mail->sendTemplate(
$user->email,
'test_email_multiple_attachments_and_template',
'welcome',
['user' => $user->username],
'default',
$attachments,
...
);
3. Text Template with Attachments
Combines .txt
content fallback and multiple files:
$mail->sendTemplate(
$user->email,
'test_email_text_template_with_attachments',
'welcome_text',
['user' => $user->username],
'default',
$attachments,
...
);
C. 🗂 Overriding Default Paths
To use custom layout, template, or styles from your own application:
Parameter | Default Constant | Custom Example |
---|---|---|
$layoutPath |
MailerService::FRAMEWORK_LAYOUT_PATH |
resources/views/emails/layouts/ |
$templatePath |
MailerService::FRAMEWORK_TEMPLATE_PATH |
resources/views/emails/ |
$stylesPath |
MailerService::FRAMEWORK_STYLES_PATH |
resources/css/ |
Pass custom paths manually to override framework defaults:
$mail->sendTemplate(
$to,
$subject,
$template,
$data,
'custom_layout',
[],
CHAPPY_BASE_PATH . '/resources/views/emails/layouts/',
CHAPPY_BASE_PATH . '/resources/views/emails/',
'custom_style',
CHAPPY_BASE_PATH . '/resources/css/'
);
🧭 Using Default Application Paths
If you want to use your own customized email templates, layouts, and styles located in:
resources/views/emails/layouts/
resources/views/emails/
resources/css/
You do not need to pass path parameters at all — just set them to null
, or omit them entirely:
$mail->sendTemplate(
$user->email,
'Welcome to Chappy.php!',
'welcome',
['user' => $user],
'default', // Layout name (e.g., default.php)
[], // No attachments
null, // Use default layout path: /resources/views/emails/layouts/
null, // Use default template path: /resources/views/emails/
'default', // CSS file: default.css
null // Use default style path: /resources/css/
);
These values are automatically resolved using:
- self::$layoutPath
- self::$templatePath
- self::$stylesPath
…which are set to point to your resources/
directory.
4. Customizing sendTo() with Advanced Parameters Table of Contents
By default, AbstractMailer::sendTo()
uses the base send()
method, which calls buildAndSend()
with default parameters. However, if your custom mailer requires attachments or custom layout/template/style paths, you can override sendTo()
directly.
🛠 Example: Overriding sendTo()
to Add Attachments
use App\Models\Users;
use Core\Models\EmailAttachments;
use Core\Lib\Mail\AbstractMailer;
use Core\Lib\Mail\Attachments;
class WelcomeMailer extends AbstractMailer
{
protected function getData(): array {
return ['user' => $this->user];
}
protected function getSubject(): string {
return 'Welcome to ' . env('SITE_TITLE');
}
protected function getTemplate(): string {
return 'welcome';
}
/**
* Override the static sendTo method to include custom build options.
*/
public static function sendTo(Users $user): bool {
$mailer = new static($user);
$attachment1 = EmailAttachments::findById(1);
$attachment2 = EmailAttachments::findById(2);
return $mailer->buildAndSend(
null, // layout (defaults to 'default')
[
Attachments::content($attachment1),
Attachments::path($attachment2)
],
null, // layout path (uses /resources/views/emails/layouts/)
null, // template path (uses /resources/views/emails/)
'default', // CSS filename
null // CSS path (uses /resources/css/)
);
}
}
🔍 Usage in Controller or Console
$user = Users::findById(1);
WelcomeMailer::sendTo($user); // Sends with attachments and full customization
✅ When Should You Override sendTo()
?
You should override sendTo() when:
- You want to embed logic unique to that mailer (e.g. attachments, path overrides)
- You need to inject data not handled by the getData() method
- You want to isolate one-off logic from your controller or service layer
📌 Reminder: buildAndSend()
Signature
protected function buildAndSend(
?string $layout = null,
array $attachments = [],
?string $layoutPath = null,
?string $templatePath = null,
?string $styles = null,
?string $stylesPath = null
): bool
🧼 Best Practice
If your attachments or logic are conditional, wrap them cleanly in the overridden sendTo()
to keep your mailer class readable.
5. Attachment Management Table of Contents
The admin dashboard allows administrators to upload, preview, update, and delete email attachments. These attachments can later be used with the framework’s MailerService::sendTemplate()
functionality. This section documents the related views and controller actions.
A. 📄 Attachments Listing
View: admindashboard.attachments
This page displays a table of all uploaded attachments, including:
- Original filename (with a link to the attachment details)
- Uploader username
- File size (formatted) -Action buttons: Edit / Delete
Add New Attachment: A button is available to navigate to the upload form:/admindashboard/editAttachments/new
B. 📋 Add or Edit Attachment
View: admindashboard.attachments_form
This form supports both creating and updating attachments:
- Description (WYSIWYG via TinyMCE)
- File Upload (only for new records)
- CSRF Protection enabled via
csrf()
- Save and Cancel buttons
C. 📁 Attachment Details
View: admindashboard.attachment_details
This view shows metadata and a preview link:
- Created and Updated timestamps (in human-readable format)
- File size and MIME type
- Uploader username
- Description (rich text rendered safely)
- Link to Preview the file:
/admindashboard/preview/:id
D. 🧪 Usage with MailerService
Once uploaded, attachments can be used in MailerService::sendTemplate()
:
$mailer->sendTemplate(
$to,
'Subject Line',
'template_name',
['user' => $user],
'default',
[
Attachments::content($attachment),
Attachments::path($attachment)
],
null, // layout path (null uses /resources/views/emails/layouts)
null, // template path (null uses /resources/views/emails/templates)
'default',
null // styles path
);
E. ✅ Additional Notes
- Uploaded files are stored and accessible only within admin.
- Attachments are associated with users via the
user_id
column. - File metadata such as MIME type and size are captured and stored during upload.
- Descriptions are HTML-safe and stored with support for rich formatting.
This section allows administrators to manage reusable file assets securely and efficiently for use in transactional emails.