Back to Blog 7 min read

Send Email With Attachment In Laravel

Sending emails in Laravel is a hot topic. Laravel made it easy to send emails just using by few commands and objects. It is not a complicated task to...

Sending emails in Laravel is a hot topic. Laravel made it easy to send emails just using by few commands and objects. It is not a complicated task to send emails; you also have many other easy ways to send emails. I am going to simplify each step for you and you will be able to do each functionality. Let's start building functionality to send mail with attachments.

Project Example Story

Before starting this project let's discuss what we gonna do to about this. For e.g, I am a CA and want to add some of my clients to my dashboard. For that, I'll create users and add them to my client list. When I'll add them then I would have their GST filed files. And these are the files I'll use to send them when I'll add each user.

Configuration the Send Email to send emails with attachments

So, In Laravel before doing email stuff, you have to set up the configuration which you can find in config/mail.php.

You will have a config directory in your application and in that directory you will havemail.php. In this file you will have an array of 'mailers' in which you have many sample configurations. It depends on you which one you want to use so, I'll use it as the default smtp.

And also you have options to do all these things in .env file

MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=fbbb2f239e90e2d7
MAIL_PASSWORD=36f5331e353bc7d
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=kum3et191@gmail.com
MAIL_FROM_NAME="Hiringo"


Now we are all set with the email configuration. Let's move next according to the example let's create a form to add users and by adding them we will send mail to them.

Setup Database

In the environment file, (.env) you also have to define the database name and then create a user table. I have used the breeze package to have this all stuff on the desk. But you can just create the user's table in which you have to create two columns name and email. That's it.

Create Form

You can create a simple form layout in which we will use some fields that are name,email just only for dummy results.

 
<form class="px-4" action="{{route('storeuser')}}" method="POST" enctype="multipart/form-data">
                            @csrf
                            <div class="grid gap-6 mb-6 lg:grid-cols-2">
                                <div>
                                    <label for="first_name"
                                        class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Client
                                        Name</label>
                                    <input type="text" id="first_name" name="name"
                                        class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                                        placeholder="John" required="">
                                </div>
                               
                            </div>
                            <div class="mb-6">
                                <label for="email"
                                    class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Email
                                    address</label>
                                <input type="email" id="email" name="email"
                                    class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
                                    placeholder="john.doe@company.com" required="">
                            </div>

                            <div class="mb-6">

                                <div class="flex justify-center items-center w-full">
                                    <label for="dropzone-file"
                                        class="flex flex-col justify-center items-center w-full h-64 bg-gray-50 rounded-lg border-2 border-gray-300 border-dashed cursor-pointer dark:hover:bg-bray-800 dark:bg-gray-700 hover:bg-gray-100 dark:border-gray-600 dark:hover:border-gray-500 dark:hover:bg-gray-600">
                                        <div class="flex flex-col justify-center items-center pt-5 pb-6">
                                            <svg class="mb-3 w-10 h-10 text-gray-400" fill="none" stroke="currentColor"
                                                viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                                    d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12">
                                                </path>
                                            </svg>
                                            <p class="mb-2 text-sm text-gray-500 dark:text-gray-400"><span
                                                    class="font-semibold">Click to upload</span> or drag and drop</p>
                                            <p class="text-xs text-gray-500 dark:text-gray-400">SVG, PNG, JPG or GIF
                                                (MAX. 800x400px)</p>
                                        </div>
                                        <input id="dropzone-file" type="file" name="file" class="hidden">
                                    </label>
                                </div>

                            </div>
                            <button type="submit"
                                class="text-white my-3 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">Submit</button>
                        </form>

Now we have a form and let's create routes to store this route and also to display the data. We don't need any route to display the data but for extra if you are practicing you can create.

Routes/web.php

Route::get('/create', function () {
    return view('create');
})->middleware(['auth'])->name('createuser');

Route::post('store',[UserController::class,'storeuser'])->name('storeuser');
Route::get('/users',[UserController::class,'show'])->name('dashboard');
require __DIR__.'/auth.php';

Make Email Class send emails with attachments

So, Now without this class, we can't move further we will create a controller after this. But before that, we have to create an email class so that we can write all the mail-sending functionality after that we will be able to render the email successfully. Let's make a mail by using the command below:

php artisan make:mail SendFile --markdown='emails.SendFile'

//Now you will have a Mail Folder in your app directory. Let's build a mail class


Mail/SendMail.php

<?php

namespace App\Mail;

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

class SendFile extends Mailable
{
    use Queueable, SerializesModels;
    public $file;
    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct($file)
    {
        $this->file = $file;
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->markdown('emails.SendFile')
            ->subject('Welcome to finance hub')
            ->attach(
                $this->file->getRealPath(),
                [
                    'as' =>  $this->file->getClientOriginalName(),
                    'mime' =>  $this->file->getClientMimeType(),
                ]
            );
    }
}


Create Controller

We have created the routes and Email to reach to the endpoint or to target. But we have a form now and let's create a controller to handle all the requests. Create a UserController by using the command below.

php artisan make:controller UserController

UserController.php

Http/Controller/UserController

<?php

namespace App\Http\Controllers;

use App\Mail\SendFile;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;

class UserController extends Controller
{
    public function show()
    {
        $users = User::all()->where('id', '!=', 1);
        return view('dashboard', compact('users'));
    }

    public function storeuser(Request $request)
    {
        $user = new User();
        $user->name = $request->name;
        $user->email = $request->email;
        $user->gstnumber = $request->gstnumber;
        $user->password = Hash::make($request->password);
        $file = $request->file('file');
        $filepath = $file->store('uploads');
        Mail::to($request->email)->send(new SendFile($file));
        $user->file = $filepath;
        $user->save();

        return redirect()->route('dashboard');
    }
}


I have stored the file from the request first and I have passed the file in the mail object. So, This was the whole process of sending an email with attachments.

Tips From Tutorial

  1. The tip is, when we do send emails in the build method then sometimes we want to change some data in our view template and also sometimes we pass dynamic data to the view template. So, then what we do is, we send variables In the build method using "with('data'=>$this->data)". But if you have defined this variable in your constructor with the public property public $file; then you don't need to pass it until you have set the property to protected or private you can access it directly into your view file {{$file->getRealPath()}}.

Will be back with amazing tips or tutorials, Thanks.