Laravel

Laravel 5.6 Mails

March 1, 2018

author:

Laravel 5.6 Mails

Laravel has a clean and straightforward API to send emails. This framework provides ready to use drivers for SMTP, Mailgun, Amazon SES, SparkPost, Php’s mail and sendmail functions. This helps us get a kick start to configure, template and send emails both locally and on the cloud.

# Generate Mailables

Each type of mail sent by the Laravel application is represented as a Mailable class. app/Mail directory contains these classes which are created when we create our first mailable class:

php artisan make:mail UserRegistered
# app/Mail/UserRegistered.php

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class UserRegistered extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        //
    }
}

# Configure Mailable

build() method in the mailable class is used to store all the configurations. It contains all the delivery and presentation logic.

# Configure Sender

The first step for sending mails to anybody is to set up the sender, i.e., from whom the email is to be delivered. We can set this in the build() method :

# app/Mail/UserRegistered.php
...
public function build()
{
    //configure sender
    return $this->from('mail@hashvel.com');
}

# Configure Global Sender Address

Many a times, an application may use same from address throughout its mailing process, in such cases, we can set the default sender address separately instead of calling it on every mail class. We can make this tweak in config/mail.php file. The address specified in this file is set as default, meaning it is used if no other from address is defined by the developer.

# config/mail.php
...
'from' => [
    'address' => env('MAIL_FROM_ADDRESS', 'mail@hashvel.com'),
    'name' => env('MAIL_FROM_NAME', 'Hashvel Internet'),
],
...

We can also do the exact same thing by setting this values on .env file:

# .env
...
MAIL_FROM_ADDRESS=mail@hashvel.com
MAIL_FROM_NAME=Hashvel-Internet

# Configure View

For the sake of proper layout, Laravel allows us to store e-mail messages in views. For modularity, we can go ahead and create a separate folder or mails in resources/views namespace. View method can be used within build method of Mailable class to specify the blade template to be used for rendering mail content.

# app/Mail/UserRegistered.php
...
public function build()
{
    //configure view
    return $this->from('mail@hashvel.com')
        ->view('emails.welcome');
}

# Configure Plain Text Mail

Laravel also allows to define plain-text version of the emails. text() method can be utilized for this
Laravel also allows defining plain-text version of the emails. text() method can be utilized for this purpose. It works similar to view() a method which accepts template name that stores content to be sent over mail. This method supports both HTML and plain-text versions of the email.

# app/Mail/UserRegistered.php
...
public function build()
{
    //plain text
    return $this->from('mail@hashvel.com')
        ->view('emails.welcome')
        ->text('emails.plain.welcome');
}

# Pass Data

While mailing, most of the times we may want to make the dynamic template and pass some fruitful data to the view layout before sending out mails. There are two ways of doing this:

• The Public Properties:

To automatically send data to layout view, we can define a public property in the Mailable class. For instance, we can pass the required data to in Mailable class’s constructor and set this data on the public properties.

# app/Mail/UserRegistered.php

<?php
...
use App\User;

class UserRegistered extends Mailable
{
    use Queueable, SerializesModels;
    public $user;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    
    public function __construct()
    {
        $this->user = $user;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('emails.welcome');
    }
}

Next, we can access this public property from Blade template like any other data as:

<div>
    Welcome {{ $user->name }}!
</div>

• The with() Method:

The with() method is typically used when we want to customize the data format before sending it to the template. We can manually tweak the data and send it via with method. Also, if we don’t intend to make the data automatically available in the layout view, we can make the data private or protected to make it secure and pass it through the constructor. While achieving this, we need to then pass such data in an array via with data.

# app/Mail/UserRegistered.php
...
public function build()
{
    return $this->view('emails.welcome')
        ->with([
            'name' => $this->user->name,
        ]);
}

We can retrieve such data in the same way though,

<div>
    Welcome {{ $user->name }}!
</div>

# Mail Attachments

Laravel also supports configuring mail attachments. We can use attach() method with Mailable class’s build() method. As an argument, it accepts the full path of the file.

# app/Mail/UserRegistered.php
...
public function build()
{
    return $this->view('emails.welcome')
        ->attach('/file/path/here');
}

# Preview Mailables In Browser

Testing a mail design template can be really tricky. Primitively, the developer had to actually send the mail to some email address to verify the email designs. But Laravel now allows us to test this in the browser itself. This feature is a significant relief for developers. We can directly return any Mailable from routes or controller using . As and when a Mailable is returned, it will be rendered on the browser, supporting to preview the design quickly without any need to send to the actual email address.

Route::get('/success', function () {
    return new App\Mail\UserRegistered();
});

# Send Mail

Sending a mail is straightforward in Laravel. We use the method on the Mail facade for this business. This method accepts email address and user instance. After passing this required arguments, we can chain send method to this call like:

# app/Http/Controllers/UserController.php
...
use App\User;
use App\Mail\UserRegistered;
use Illuminate\Support\Facades\Mail;
...
public function register(Request $request){
    $user = $this->user->create([
        'name' => $request->get('name'),
        'email' => $request->get('email'),
        'password' => bcrypt($request->get('password'))
    ]);
    Mail::to($request->user())->send(new UserRegistered($user));
}

Laravel also supports optional parameters like cc and bcc which can be chained with to method call:

public function register(Request $request){
    $user = $this->user->create([
        'name' => $request->get('name'),
        'email' => $request->get('email'),
        'password' => bcrypt($request->get('password'))
    ]);
    Mail::to($request->user())
    ->cc($moreUsers)
    ->bcc($evenMoreUsers)
    ->send(new UserRegistered($user));
}

Conclusion:

In this post we took a detailed look at Laravel Mails. We discussed every aspect of Laravel mail starting with its easy of operations to configuring laravel components and testing in browser to finally sending it.

Questions & Comments:

Thank you for reading. If you have got any suggestions or questions share them in the comment section below.

Leave a comment

Your email address will not be published. Required fields are marked *