Introduction
The article is using Laravel 10.x. There could be errors in lower versions.
.env and configuration
Before getting started, .env
config need to be changed.
.env
MAIL_MAILER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=465
MAIL_USERNAME=mygoogle@gmail.com
MAIL_PASSWORD=mygooglepassword
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=mygoogle@gmail.com
MAIL_FROM_NAME="${APP_NAME}"
The mail system uses data in .env
on default.
The configuration file will be config/mail.php
.
Generate Mailable
php artisan make:mail Invoice
If you run above command, a class
would be created extended by Mailable
.
The file is in app/mail/Invoice.php
.
Example Code
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
use Illuminate\Queue\SerializesModels;
class Invoice extends Mailable
{
use Queueable, SerializesModels;
public $name;
public $attachemnts;
/**
* Create a new message instance.
*/
public function __construct($name, $attachemnts)
{
$this->name = $name;
$this->attachemnts = $attachemnts;
}
/**
* Get the message envelope.
*/
public function envelope(): Envelope
{
return new Envelope(
subject: 'Demo Mail',
);
}
/**
* Get the message content definition.
*/
public function content(): Content
{
return new Content(
view: 'emails.demoMail',
);
}
/**
* Get the attachments for the message.
*
* @return array
*/
public function attachments(): array
{
$result = array();
if ($this->attachemnts) {
foreach ($this->attachments as $attachment)
{
array_push($result, Attachment::fromPath(public_path('storage') . '/' . $attachment->name),);
}
}
return $result;
}
}
For explanation, change code like above.
Methods
Following methods are key configuration that you should know.
Name | Description |
---|---|
Envelope | Defines subject, email and repliers |
Content | Defines the blade template for content of email |
Attachment | Add attachments to email |
Envelope
The envelope()
method defines sender configurations like from
, replyTo
and subject
, and it returns Envelope
class.
Property
Name | Descirption |
---|---|
from | Set sender. It will be set data in .env on default |
replyTo | Set additional to. It takes array. |
subject | Set title of email |
tags | Add tags. It takes array. |
metadata | Add metatags. It takes array. |
How to use
return new Envelope(
from: new Address('abc@example.com', 'Xyz'),
replyTo: [
new Address('xyz@example.com', 'Xyz'),
],
subject: 'Invoice for #123123',
tags: ['invoice'],
metadata: [
'invoiceId' => $this->invoice->id,
],
);
The Address
class should be used in order to from
and element in replyTo
,
replyTo
global
The replyTo
can be set globally in config/mail.php
'reply_to' => ['address' => 'example@example.com', 'name' => 'App Name'],
Content
The content()
method renders view with some data. The content()
method returns Content
class
How to use
public function content(): Content
{
return new Content(
markdown: 'emails.invoice',
with: [
'today' => date('Y/m/d')
]
);
}
Property
Name | Description |
---|---|
view | Load blade template as html from path |
markdown | Load blade template as Markdown from path |
with | Allows to use more variables not only in class variables |
Views (Template)
php mail supports html
, plain text
and markdown
file with blade
template.
The Path
is passed to view
, replaced /
to .
. It uses /rosources
on default, so resousces
is not required in string.
For example, the path is emails.invoice
if the template file is in resources/views/emails
and name is invoice.blade.php
.
Markdown
@component('mail::message')
Hello {{$name}}
Here is inovice:
Thanks,<br>
{{ config('app.name') }}
@endcomponent
The components like Button, panel and table can be used.
<x-mail::button :url="$url" color="success">
Button
</x-mail::button>
<x-mail::table>
| Col1 | Col2 | Price |
| ----- | :-----------: | ----: |
| Row 1 | Centered | $10 |
| Row 2 | Right-Aligned | $20 |
</x-mail::table>
<x-mail::panel>
Panel content
</x-mail::panel>
Attachments
The attachments()
method adds attachments, returned an array to email. It returns array of Attachment
class
public function attachments(): array
{
$result = array();
if ($this->attachemnts) {
foreach ($this->attachments as $attachment)
{
array_push($result, Attachment::fromPath(public_path('storage') . '/' . $attachment->name),);
}
}
return $result;
}
The Attachment
class provides three methods.
Name | Description |
---|---|
fromPath() | from path |
fromStorage() | from filesystem disks |
fromStorageDisk() | from specific storage disk |
Click the link to see more detail about filesysstem
in Laravel
Name / MIME
The file Name and Mime type for attachments can be modified by using as
and withMime
Methods.
Attachment::fromPath('/path/to/file')
->as('name.pdf')
->withMime('application/pdf'),
Click the link to see about mime type.
Controller
If you don't have controller, run the below command to create a mail controller
php artisan make:controller EmailController
Before using Mail, Import Mail
at the top.
public function sendEmail(Request $request)
{
$request->validate([
'email' => 'required|string|email|max:255',
'name' => 'required|string|max:255'
]);
// send email
Mail::to($request->email)->send(new InvoiceMail(
$request->name,
[],
));
return response()->json([
'message' => 'Successfully sent',
]);
}
Add email to send in to()
method.
The Send()
method should take Mailable class along with parameter.
Add CC
The header
allows to add CC, but cc can be added for each controller.
Mail::to($request->email)
->cc($moreUsers)
->bcc($evenMoreUsers)
->send(new InvoiceMail(
$request->name,
[],
));
Send many messages at the same time
Use queue
method instead of send
.
The queue
allows to add mail job into queue
.
If you would like to make Mailable class always in queue
, implement ShouldQueue
.
class InvoiceMail extends Mailable implements ShouldQueue
{
//
}