binarcode/laravel-mailator
Composer 安装命令:
composer require binarcode/laravel-mailator
包简介
Laravel email scheduler
README 文档
README
Laravel Mailator provides a featherweight system for configure email scheduler and email templates based on application events.
Installation
You can install the package via composer:
composer require binarcode/laravel-mailator
Publish
Publish migrations: php artisan vendor:publish --tag=mailator-migrations
Publish config: php artisan vendor:publish --tag=mailator-config
Usage
It has mainly 2 directions of usage:
-
Schedule emails sending (or actions triggering)
-
Email Templates & Placeholders
Scheduler
To set up a mail to be sent after or before an event, you can do this by using the Scheduler facade.
Here is an example of how to send the invoice reminder email 3 days before the $invoice->due_date:
use Binarcode\LaravelMailator\Tests\Fixtures\InvoiceReminderMailable; use Binarcode\LaravelMailator\Tests\Fixtures\SerializedConditionCondition; Binarcode\LaravelMailator\Scheduler::init('Invoice reminder.') ->mailable(new InvoiceReminderMailable($invoice)) ->recipients('foo@binarcode.com', 'baz@binarcode.com') ->constraint(new SerializedConditionCondition($invoice)) ->days(3) ->before($invoice->due_date) ->save();
Let's explain what each line means.
Mailable
This should be an instance of laravel Mailable.
Recipients
This should be a list or valid emails where the email will be sent.
It could be an array of emails as well.
Weeks
This should be a number of weeks the email should be delayed.
Days
This should be a number of days the email should be delayed.
Hours
Instead of days() you can use hours() as well.
Minutes
If your scheduler run by minute, you can also use minutes() to delay the email.
Before
The before constraint accept a CarbonInterface and indicates from when scheduler should start run the mail or action. For instance:
->days(1) ->before(Carbon::make('2021-02-06'))
says, send this email 1 day before 02 June 2021, so basically the email will be scheduled for 01 June 2021.
After
The after constraint accept a CarbonInterface as well. The difference, is that it inform scheduler to send it after the specified timestamp. Say we want to send a survey email 1 week after the order is placed:
->weeks(1) ->after($order->created_at)
Precision
Hour Precision
The precision method provides fine-grained control over when emails are sent using MailatorSchedule. It allows you to specify specific hours or intervals within a 24-hour period. Here's an example of how to use the precision method:
->many() ->precision([3-4])
This will schedule the email dispatch between '03:00:00' AM and '04:59:59' AM.
or
->once() ->precision([1])
This will schedule the email dispatch between '01:00:00' AM and '01:59:59'.
You can continue this pattern to specify the desired hour(s) within the range of 1 to 24.
Important: When using the precision feature in the Mailator scheduler, it is recommended to set the scheduler to run at intervals that are less than an hour. You can choose intervals such as every 5 minutes, 10 minutes, 30 minutes, or any other desired duration.
Constraint
The constraint() method accept an instance of Binarcode\LaravelMailator\Constraints\SendScheduleConstraint. Each constraint will be called when the scheduler will try to send the email. If all constraints return true, the email will be sent.
The constraint() method could be called many times, and each constraint will be stored.
Since each constraint will be serialized, it's very indicated to use Illuminate\Queue\SerializesModels trait, so the serialized models will be loaded properly, and the data stored in your storage system will be much less.
Let's assume we have this BeforeInvoiceExpiresConstraint constraint:
class BeforeInvoiceExpiresConstraint implements SendScheduleConstraint { public function canSend(MailatorSchedule $mailatorSchedule, Collection $log): bool { // your conditions return true; } }
Constraintable
Instead of defining the constraint from the mail definition, sometimes it could be more readable if you define it directly into the mailable class:
use Binarcode\LaravelMailator\Constraints\Constraintable; class InvoiceReminderMailable extends Mailable implements Constraintable { public function constraints(): array { return [ new DynamicContraint ]; } }
Action
Using Scheduler you can even define your custom action:
$scheduler = Scheduler::init('Invoice reminder.') ->days(1) ->before(now()->addWeek()) ->actionClass(CustomAction::class) ->save();
The CustomAction should implement the Binarcode\LaravelMailator\Actions\Action class.
Target
You can link the scheduler with any entity like this:
Scheduler::init('Invoice reminder.') ->mailable(new InvoiceReminderMailable()) ->days(1) ->target($invoice) ->save();
and then in the Invoice model you can get all emails related to it:
// app/Models/Invoice.php public function schedulers() { return $this->morphMany(Binarcode\LaravelMailator\Models\MailatorSchedule::class, 'targetable'); } ...
Mailator provides the Binarcode\LaravelMailator\Models\Concerns\HasMailatorSchedulers trait you can put in your Invoice model, so the relations will be loaded.
Daily
By default, scheduler run the action, or send the email only once. You can change that, and use a daily reminder till the constraint returns a truth condition:
use Binarcode\LaravelMailator\Scheduler; // 2021-20-06 - 20 June 2021 $expirationDate = $invoice->expire_at; Scheduler::init('Invoice reminder') ->mailable(new InvoiceReminderMailable()) ->daily() ->weeks(1) ->before($expirationDate)
This scheduler will send the InvoiceReminderMailable email daily starting with 13 June 2021 (one week before the expiration date).
How to stop the email sending if the invoice was paid meanwhile? Simply adding a constraint that will do not send it:
->constraint(new InvoicePaidConstraint($invoice))
and the constraint handle method could be something like this:
class InvoicePaidConstraint implements SendScheduleConstraint { use SerializesModels; public function __construct( private Invoice $invoice ) { } public function canSend(MailatorSchedule $schedule, Collection $logs): bool { return is_null($this->invoice->paid_at); } }
Stop conditions
There are few ways email stop to be sent.
The first condition, is that if for some reason sending email fails 3 times, the MailatorSchedule will be marked as completed_at. Number of times could be configured in the config file mailator.scheduler.mark_complete_after_fails_count.
Any successfully sent mail, that should be sent only once, will be marked as completed_at.
Stopable
You can configure your scheduler to be marked as completed_at if in the you custom constraint returns a falsy condition. Back to our InvoiceReminderMailable, say the invoice expires on 20 June, we send the first reminder on 13 June, then the second reminder on 14 June, if the client pay the invoice on 14 June the InvoicePaidConstraint will return a falsy value, so there is no reason to try to send the invoice reminder on 15 June again. So the system could mark this scheduler as completed_at.
To do so, you can use the stopable() method.
Unique
You can configure your scheduler to store a unique relationship with the target class for mailable by specifying:
->unique()
ie:
Scheduler::init() ->mailable(new InvoiceReminderMailable()) ->target($user) ->unique() ->save(); Scheduler::init() ->mailable(new InvoiceReminderMailable()) ->target($user) ->unique() ->save();
This will store a single scheduler for the $user.
Events
Mailator has few events you can use.
If your mailable class extends the Binarcode\LaravelMailator\Contracts\Beforable, you will be able to inject the before method, that will be called right before the sending the email.
If your mailable class extends the Binarcode\LaravelMailator\Contracts\Afterable, you will be able to inject the after method, that will be called right after the mail has being sent.
And latest, after each mail has being sent, mailator will fire the Binarcode\LaravelMailator\Events\ScheduleMailSentEvent event, so you can listen for it.
Run
Now you have to run a scheduler command in your Kernel, and call:
Binarcode\LaravelMailator\Scheduler::run();
Package provides the Binarcode\LaravelMailator\Console\MailatorSchedulerCommand command you can put in your Console Kernel:
$schedule->command(MailatorSchedulerCommand::class)->everyThirtyMinutes();
Templating
To create an email template:
$template = Binarcode\LaravelMailator\Models\MailTemplate::create([ 'name' => 'Welcome Email.', 'from_email' => 'from@bar.com', 'from_name' => 'From Bar', 'subject' => 'Welcome to Mailator.', 'html' => '<h1>Welcome to the party!</h1>', ]);
Adding some placeholders with description to this template:
$template->placeholders()->create( [ 'name' => '::name::', 'description' => 'Name', ], );
To use the template, you simply have to add the WithMailTemplate trait to your mailable.
This will enforce you to implement the getReplacers method, this should return an array of replacers to your template.
The array may contain instances of Binarcode\LaravelMailator\Replacers\Replacer or even Closure instances.
Mailator shipes with a builtin replacer ModelAttributesReplacer, it will automaticaly replace attributes from the
model you provide to placeholders.
The last step is how to say to your mailable what template to use. This could be done into the build method as shown bellow:
class WelcomeMailatorMailable extends Mailable { use Binarcode\LaravelMailator\Support\WithMailTemplate; private Model $user; public function __construct(Model $user) { $this->user = $user; } public function build() { return $this->template(MailTemplate::firstWhere('name', 'Welcome Email.')); } public function getReplacers(): array { return [ Binarcode\LaravelMailator\Replacers\ModelAttributesReplacer::makeWithModel($this->user), function($html) { // } ]; } }
Testing
composer test
Changelog
Please see CHANGELOG for more information what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security
If you discover any security related issues, please email eduard.lupacescu@binarcode.com or message me on twitter instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
binarcode/laravel-mailator 适用场景与选型建议
binarcode/laravel-mailator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 304.24k 次下载、GitHub Stars 达 251, 最近一次更新时间为 2020 年 02 月 07 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「binarcode」 「laravel-mailator」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 binarcode/laravel-mailator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 binarcode/laravel-mailator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 binarcode/laravel-mailator 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Lightweight package to log slack exceptions.
A Laravel wrapper for the Segment API and events tracking.
Just another multi tenant support package for Laravel.
Lightweight Laravel API.
A realtime chat implementation for laravel nova.
统计信息
- 总下载量: 304.24k
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 251
- 点击次数: 28
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2020-02-07
