![Composing Emails Using Laravel Mailable Classes](https://webmobtuts.com/wp-content/uploads/2019/11/Composing-Emails-Using-Laravel-Mailable-Classes-800x400.jpg)
Laravel framework provides a clean way to send emails via it’s fluent api using laravel Mailable classes.
To send emails in laravel you may use the Mail facade but this can be cumbersome in large application as you have to repeat the same code again and again. Another approach is by using laravel mailables which considered a dedicated classes for composing and sending emails in more clean and abstracted way.
To start with creating mailable classes you can use the artisan command:
php artisan make:mail ProductApproved
This will create a Mail/ directory inside the app/ directory inside it the ProductApproved.php class. When opening the above class you may see this structure:
<?php namespace App\Mail; use Illuminate\Bus\Queueable; use Illuminate\Mail\Mailable; use Illuminate\Queue\SerializesModels; use Illuminate\Contracts\Queue\ShouldQueue; class ProductApproved 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'); } }
The most important method here is the build() method which compose and configure the mail message by rendering the email template. As shown above it just returns the mail template view, but you also call other methods such as setting the from using the from() method, setting the subject using subject() method and attach() method to attach files.
public function build() { return $this->from('example@example.com') ->view('view.name') ->text('view.name_text'); }
Â
View data
To send data to the email template you have two options, the first option by setting public properties in your mailable class. Once those properties defined you can access them in the email view like this:
class ProductApproved extends Mailable { use Queueable, SerializesModels; public $product; public function __construct(Product $product) { $this->product = $product; } public function build() { return $this->view('emails.products.approve'); } }
Then you can access $this->product in emails/products/approve.blade.php
<p> {{ $product->title }} has been approved </p>
The second option when sending data to the view is by using the with() method in the same way when using to send data in the normal view templates.
public function build() { return $this->view('emails.products.approved') ->with([ 'productTitle' => $this->product->title ]); }
<p> {{ $productTitle }} has been approved </p>
Email attachments
To send attachments along with your email message laravel provides a lot of methods. The first method is the attach($path) which takes the full path of the file you want to send.
public function build() { return $this->view('emails.products.approved') ->attach(public_path('uploads/products/' . $this->product->photo)); }
You may customize the file name and mime type of the file by adding a second argument to attach().
public function build() { return $this->view('emails.products.approved') ->attach(public_path('uploads/products/' . $this->product->photo, [ 'as' => 'photo.jpg', 'mime' => 'image/jpg', ] )); }
Also there is attachFromDisk() method which used send files located in filesystem.
return $this->view('email.products.approved') ->attachFromStorage('/path/to/file');
Sending the message
To send the email for example in your controller use the Mail facade to() method, passing in the user instance or collection of users. Then calling the send() method passing an instance of the mailable class we just created as shown:Â
<?php namespace App\Http\Controllers; use App\Mail\ProductApproved; use App\Product; use Illuminate\Http\Request; use Illuminate\Support\Facades\Mail; class ProductsController extends Controller { public function approve(Request $request, $id) { $product = Product::find($id); Mail::to($request->user())->send(new ProductApproved($product)); } }
The send() method accept an argument of type Illuminate\Mail\Mailable, in this case i passed an instance of the ProductApproved class, internally it calls the build() method which in turn return the view to be sent.