In this article, we're going to explore the Mail API in the Laravel web framework. Laravel takes advantage of the popular SwiftMailer library, which is easy to use and comes with a variety of email drivers to choose from. In the latter stages of the article, we'll go through an in-depth demonstration of the concepts discussed in the first half of the article.
Setting Up the Prerequisites
Laravel implements a wrapper on top of the SwiftMailer library that makes email management very easy to configure and use at the same time. You can find the default mail settings at config/mail.php
.
<?php return [ /* |-------------------------------------------------------------------------- | Mail Driver |-------------------------------------------------------------------------- | | Laravel supports both SMTP and PHP's "mail" function as drivers for the | sending of e-mail. You may specify which one you're using throughout | your application here. By default, Laravel is setup for SMTP mail. | | Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses", | "sparkpost", "log", "array" | */ 'driver' => env('MAIL_DRIVER', 'sendmail'), /* |-------------------------------------------------------------------------- | SMTP Host Address |-------------------------------------------------------------------------- | | Here you may provide the host address of the SMTP server used by your | applications. A default option is provided that is compatible with | the Mailgun mail service which will provide reliable deliveries. | */ 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), /* |-------------------------------------------------------------------------- | SMTP Host Port |-------------------------------------------------------------------------- | | This is the SMTP port used by your application to deliver e-mails to | users of the application. Like the host we have set this value to | stay compatible with the Mailgun e-mail application by default. | */ 'port' => env('MAIL_PORT', 587), /* |-------------------------------------------------------------------------- | Global "From" Address |-------------------------------------------------------------------------- | | You may wish for all e-mails sent by your application to be sent from | the same address. Here, you may specify a name and address that is | used globally for all e-mails that are sent by your application. | */ 'from' => [ 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), 'name' => env('MAIL_FROM_NAME', 'Example'), ], /* |-------------------------------------------------------------------------- | E-Mail Encryption Protocol |-------------------------------------------------------------------------- | | Here you may specify the encryption protocol that should be used when | the application send e-mail messages. A sensible default using the | transport layer security protocol should provide great security. | */ 'encryption' => env('MAIL_ENCRYPTION', 'tls'), /* |-------------------------------------------------------------------------- | SMTP Server Username |-------------------------------------------------------------------------- | | If your SMTP server requires a username for authentication, you should | set it here. This will get used to authenticate with your server on | connection. You may also set the "password" value below this one. | */ 'username' => env('MAIL_USERNAME'), 'password' => env('MAIL_PASSWORD'), /* |-------------------------------------------------------------------------- | Sendmail System Path |-------------------------------------------------------------------------- | | When using the "sendmail" driver to send e-mails, we will need to know | the path to where Sendmail lives on this server. A default path has | been provided here, which will work well on most of your systems. | */ 'sendmail' => '/usr/sbin/sendmail -bs', /* |-------------------------------------------------------------------------- | Markdown Mail Settings |-------------------------------------------------------------------------- | | If you are using Markdown based email rendering, you may configure your | theme and component paths here, allowing you to customize the design | of the emails. Or, you may simply stick with the Laravel defaults! | */ 'markdown' => [ 'theme' => 'default', 'paths' => [ resource_path('views/vendor/mail'), ], ], ];
When it comes to sending mails, Laravel supports different drivers to choose from. As you can see, the default MAIL_DRIVER
is set to smtp
.
If you are going to use the smtp
driver to send mails then you're also required to set other related settings like MAIL_HOST
, MAIL_PORT
, MAIL_ENCRYPTION
, MAIL_USERNAME
, and MAIL_PASSWORD
.
On the other hand, if you are going to use the sendmail
driver, then you want to make sure that the sendmail
system path is set to the correct value in the config/mail.php
file.
You can also set the from
address that will be used while sending mails under the from
key. And finally, if you want to use Markdown-based email rendering, you can set those settings under the markdown
key.
The cherry on the top is that you could also use third-party email service providers like Mailgun, Mandrill, SES, and SparkPost. If you are using one of those services, you need to make sure that you set the corresponding settings in the config/services.php
file.
So that was a basic introduction to the mail API related settings in Laravel. From the next section onwards, we'll go through a custom example that shows you how to send emails.
Create the Mailable Class
In this section, we'll create the mailable class, which will be used to send emails. The mailable class is responsible for sending emails using a mailer that's configured in the config/mail.php
file. In fact, Laravel already provides an artisan command that allows us to create a base template.
php artisan make:mail DemoEmail
That should create a blank email template at app/Mail/DemoEmail.php
, as shown in the following snippet.
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; class DemoEmail extends Mailable { use Queueable, SerializesModels; /** * Create a new message instance. * * @return void */ public function __construct() { // } /** * Build the message. * * @return $this */ public function build() { return $this->view('view.name'); } }
Let's replace the contents of that file with the following.
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; class DemoEmail extends Mailable { use Queueable, SerializesModels; /** * The demo object instance. * * @var Demo */ public $demo; /** * Create a new message instance. * * @return void */ public function __construct($demo) { $this->demo = $demo; } /** * Build the message. * * @return $this */ public function build() { return $this->from('sender@example.com') ->view('mails.demo') ->text('mails.demo_plain') ->with( [ 'testVarOne' => '1', 'testVarTwo' => '2', ]) ->attach(public_path('/images').'/demo.jpg', [ 'as' => 'demo.jpg', 'mime' => 'image/jpeg', ]); } }
There are two important methods the mailable class generally implements—__construct
and build
. The __construct
method is used to initialize objects that you're supposed to use in the email template. On the other hand, the build
method is used to initialize more email-specific values like from, view template, attachments and similar.
In our case, we've passed the $demo
object as a constructor argument, and it's assigned to the demo
public property.
In the build
method, we've initialized an email-specific configuration.
- The
from
is used to set an email address that'll be used as a from address. - Using the
view
method, you can set the email template that will be used while sending an email using this mailable. In our case, we've set it tomails.demo
, and it means that you need to create a view template file atresources/views/mails/demo.blade.php
. - Next, the
text
method is used to set up the plain text version of an email template. - As we've just discussed, the
__construct
method is used to set up objects that'll be used in the email template, you can also use thewith
method that allows you to set the view data of a message. - Next, we've used the
attach
method to attach an image with a message.
Of course, we need to create email templates that we're supposed to use while sending emails. Go ahead and create a file resources/views/mails/demo.blade.php
as shown in the following snippet.
Hello <i></i>, <p>This is a demo email for testing purposes! Also, it's the HTML version.</p> <p><u>Demo object values:</u></p> <div> <p><b>Demo One:</b> </p> <p><b>Demo Two:</b> </p> </div> <p><u>Values passed by With method:</u></p> <div> <p><b>testVarOne:</b> </p> <p><b>testVarTwo:</b> </p> </div> Thank You, <br/> <i></i>
Also, let's create the plain text version of that file at resources/views/mails/demo_plain.blade.php
.
Hello , This is a demo email for testing purposes! Also, it's the HTML version. Demo object values: Demo One: Demo Two: Values passed by With method: testVarOne: testVarOne: Thank You,
So that was the mailable class at your disposal, and we've not done yet as we need to use the Mail
facade to actually send mails. In the very next section, we'll explore how you can use the Mail
Facade to send emails using the DemoEmail
Mailable class that was just created in this section.
Wrapping Up
In this section, we'll create an example to demonstrate how you can use the Mailable
class that was created in the last section.
Let's create a controller file at app/Http/Controllers/MailController.php
with the following contents.
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\Mail\DemoEmail; use Illuminate\Support\Facades\Mail; class MailController extends Controller { public function send() { $objDemo = new \stdClass(); $objDemo->demo_one = 'Demo One Value'; $objDemo->demo_two = 'Demo Two Value'; $objDemo->sender = 'SenderUserName'; $objDemo->receiver = 'ReceiverUserName'; Mail::to("receiver@example.com")->send(new DemoEmail($objDemo)); } }
It's important to note that we've included the Illuminate\Support\Facades\Mail
Facade that will be used to send an email. In the send
method, the following statement is responsible for sending an email by initialising the App\Mail\DemoEmail
Mailable in the first place.
Mail::to("receiver@example.com")->send(new DemoEmail($objDemo));
The to
method of the Illuminate\Support\Facades\Mail
Facade returns an instance of the \Illuminate\Mail\PendingMail
class, which already contains an appropriate mailer configured in the config/mail.php
file.
And finally, we use the send
method of the \Illuminate\Mail\PendingMail
class that sends an actual email.
To test it, let's add an associated route in the routes/web.php
file.
// Email related routes Route::get('mail/send', 'MailController@send');
And with that in place, you can run the http://ift.tt/2BSrKyg URL to see if it works as expected.
On the other hand, if you want to test your email templates quickly, without sending actual emails, there's a provision in Laravel that allows you to log all outgoing emails.
To achieve that, you need to set the value of MAIL_DRIVER
to log
in the config/mail.php
file. Next, you could run the aforementioned URL and inspect the log file to check if the email template was logged there.
If everything goes fine, you should see an email being logged to the storage/logs/laravel.log
file.
That's pretty much it as far as the mail feature is concerned in Laravel, and that concludes this article as well.
Conclusion
Today, we went through the mail API that comes built into Laravel, and it also supports a variety of drivers as well.
Starting with basic concepts, we implemented the mailable class that is an essential element in the mail API in Laravel as we moved on. At the end, we also tested the mailable class by creating a custom controller to see if it actually works.
If you're just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study in Envato Market.
I would love to know your feedback in the form of queries and comments using the feed below!
No comments:
Post a Comment