Reputation: 1951
How can I send a plain text email in Laravel 8 without using a blade?
All our email messages and templates are stored in a database, so using a blade is not applicable to us. I just want to pass in text to send.
Thanks.
Upvotes: 4
Views: 6333
Reputation: 1951
This is what I ended up doing, and I think it's a good solution.
I created a generic Mailable class called app\Mail\Message.php.
<?php
namespace App\Mail;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
class Message extends Mailable {
use Queueable, SerializesModels;
private $theSubject;
private $htmlBody;
private $fromAddress;
private $theAttachments;
private $replyToEmail;
public function __construct($subject, $htmlBody, $fromAddress, $replyTo=null, $attachments=null) {
$this->theSubject = $subject;
$this->htmlBody = $htmlBody;
$this->fromAddress = $fromAddress;
$this->theAttachments = $attachments;
$this->replyToEmail = $replyTo;
}
public function getBody() {
return $this->htmlBody;
}
public function build() {
$this->subject($this->theSubject);
$this->from($this->fromAddress);
$this->html($this->htmlBody);
if ($this->replyToEmail != null) {
$this->replyTo($this->replyToEmail);
}
// more info here: https://laravel.com/docs/8.x/mail#attachments
if ($this->theAttachments != null) {
foreach($this->theAttachments as $attachment) {
if (is_array($attachment)) {
$this->attach($attachment[0], [ // $attachment[0] = temp file path
'as' => (isset($attachment[1]) ? $attachment[1]:null), // $attachment[1] = filename
'mime' => (isset($attachment[2]) ? $attachment[2]:null), // $attachment[2] = mime type
]);
} else {
$this->attach($attachment); // $attachment = temp file path
}
}
}
return $this;
}
}
To send an email, I do this:
$message = new Message($subject, $fullBody, $fromAddress, $replyTo, $attachments);
Mail::to($address)->send($message);
To test sending email, I do this:
Mail::fake();
Mail::assertNothingSent();
// do something that sends an email...
Mail::assertSent(Message::class, function($email) {
$token = // get something that should be found in the body
$email->build();
$allGood = true;
$allGood &= $email->subject === 'Password Recovery';
$allGood &= str_contains($email->getBody(), $token);
return $allGood;
});
Upvotes: 2
Reputation: 868
I think you might be better of creating a Notification class that sends via mail. You can generate a notification with
php artisan make:notification OrderShipped
And by default its via
method will send by mail, and will use Laravels default mail templates. In the toMail you can send whatever is needed. Then for your tests you can do:
public function testUserGetNotifiedIfOrderShipped())
{
Notification::fake();
// Hit some endpoints thats will send notification
// Assert Admin gets notification
Notification::assertSentTo(User::first(), OrderShipped::class);
}
Upvotes: 0
Reputation: 398
Mail::raw('This is a simple text', function ($m) {
$m->to('[email protected]')->subject('Email Subject');
});
Don't forget to include
use Mail;
Upvotes: 5