This package allows you to store and send e-mails using the database.
This package requires Laravel 10 or 11.
Require the package using composer.
composer require stackkit/laravel-database-emails
Publish the configuration files.
php artisan vendor:publish --tag=database-emails-config
php artisan vendor:publish --tag=database-emails-migrations
Create the database table required for this package.
php artisan migrate
Add the e-mail cronjob to your scheduler
protected function schedule(Schedule $schedule)
{
$schedule->command('email:send')->everyMinute()->withoutOverlapping(5);
}
E-mails are composed the same way mailables are created.
use Stackkit\LaravelDatabaseEmails\Email;
use Illuminate\Mail\Mailables\Content;
use Stackkit\LaravelDatabaseEmails\Attachment;
use Illuminate\Mail\Mailables\Envelope;
Email::compose()
->content(fn (Content $content) => $content
->view('tests::dummy')
->with(['name' => 'John Doe'])
)
->envelope(fn (Envelope $envelope) => $envelope
->subject('Hello')
->from('johndoe@example.com', 'John Doe')
->to('janedoe@example.com', 'Jane Doe')
)
->attachments([
Attachment::fromStorageDisk('s3', '/invoices/john-doe/march-2024.pdf'),
])
->send();
])
Email::compose()
->user($user)
->send();
By default, the name
column will be used to set the recipient's name. If you wish to use something different, you should implement the preferredEmailName
method in your model.
class User extends Model
{
public function preferredEmailName(): string
{
return $this->first_name;
}
}
By default, the email
column will be used to set the recipient's e-mail address. If you wish to use something different, you should implement the preferredEmailAddress
method in your model.
class User extends Model
{
public function preferredEmailAddress(): string
{
return $this->work_email;
}
}
By default, the app locale will be used. If you wish to use something different, you should implement the preferredEmailLocale
method in your model.
class User extends Model implements HasLocalePreference
{
public function preferredLocale(): string
{
return $this->locale;
}
}
You may also pass a mailable to the e-mail composer.
Email::compose()
->mailable(new OrderShipped())
->send();
To start attaching files to your e-mails, you may use the attachments
method like you normally would in Laravel.
However, you will have to use this package's Attachment
class.
use Stackkit\LaravelDatabaseEmails\Attachment;
Email::compose()
->attachments([
Attachment::fromPath(__DIR__.'/files/pdf-sample.pdf'),
Attachment::fromPath(__DIR__.'/files/my-file.txt')->as('Test123 file'),
Attachment::fromStorageDisk('my-custom-disk', 'test.txt'),
])
->send();
[!NOTE]
Attachment::fromData()
andAttachment::fromStorage()
are not supported as they work with raw data.
You may attach a model to an e-mail. This can be useful to attach a user or another model that belongs to the e-mail.
Email::compose()
->model(User::find(1));
You may schedule an e-mail by calling later
instead of send
. You must provide a Carbon instance or a strtotime valid date.
Email::compose()
->later('+2 hours');
[!IMPORTANT] When queueing mail using the
queue
function, it is no longer necessary to schedule theemail:send
command.
Email::compose()->queue();
// On a specific connection
Email::compose()->queue(connection: 'sqs');
// On a specific queue
Email::compose()->queue(queue: 'email-queue');
// Delay (send mail in 10 minutes)
Email::compose()->queue(delay: now()->addMinutes(10));
If you need more flexibility, you may also pass your own job class:
Email::compose()->queue(jobClass: CustomSendEmailJob::class);
It could look like this:
<?php
namespace App\Jobs;
use Illuminate\Contracts\Queue\ShouldQueue;
use Stackkit\LaravelDatabaseEmails\SendEmailJob;
class CustomSendEmailJob extends SendEmailJob implements ShouldQueue
{
// Define custom retries, backoff, etc...
}
When enabled, all newly created e-mails will be sent to the specified test e-mail address. This is turned off by default.
DB_EMAILS_TESTING_ENABLED=true
DB_EMAILS_TESTING_EMAIL=your-test-recipient@example.com
To configure how many e-mails should be sent each command.
DB_EMAILS_LIMIT=20
Useful during development when Laravel Scheduler is not running
To enable, set the following environment variable:
DB_EMAILS_IMMEDIATELY=true
use Stackkit\LaravelDatabaseEmails\Email;
$schedule->command('model:prune', [
'--model' => [Email::class],
])->daily();
By default, e-mails are pruned when they are older than 6 months.
You may change that by adding the following to the AppServiceProvider.php:
use Stackkit\LaravelDatabaseEmails\Email;
public function register(): void
{
Email::pruneWhen(function (Email $email) {
return $email->where(...);
});
}