最近开发站内信功能,由于是半路接入的,本来可以用laravel 自带的 notifications 一套开发, 但由于 App 直接接口已经固定是自增id,无法调整notification 的uuid,且mysql 无法再创建一个自增主键, 由于时间关系,,没法再写一套这个站内信,只能用重写方法,来兼容 app 接口。
查阅资料,Laravel是从toDatabase() 方法返回的数组将被json编码并保存到 data 列中。没办法直接改。 一个解决方法是创建一个新的通道类,扩展 Laravel 的类并覆盖send方法,然后将新类注入到容器中, 而不是 Laravel的原生类中,现在让我们看看如何做到这一点。
php artisan make:channel DatabaseChannel
<?php
namespace App\Channels;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Redis;
use Illuminate\Notifications\Channels\DatabaseChannel as IlluminateDatabaseChannel;
class DatabaseChannel extends IlluminateDatabaseChannel
{
/**
* Send the given notification.
*
* @param mixed $notifiable
* @param \Illuminate\Notifications\Notification $notification
* @return \Illuminate\Database\Eloquent\Model
*/
public function send($notifiable, Notification $notification)
{
//通过redis 实现自增
$incrId = Redis::connection()->incr('notifications');
return $notifiable->routeNotificationFor('database')->create([
'id' => $notification->id,
'type' => get_class($notification),
'auto_id'=> $notification->auto_id ?? null,
'data' => $this->getData($notifiable, $notification),
'read_at' => null,
]);
}
}
注意要保存的列中添加了“auto_id”,设置 auto_id 就像向要发送的特定通知类添加属性一样简单。 现在我们需要注入这个类而不是原生的那个,我们可以在任何服务提供者的引导方法中这么做, 我刚刚在App\Providers\AppServiceProvider中这么做了, 你可以为此创建一个服务提供者,但我认为现在这是好的。
use App\Channels\DatabaseChannel;
use Illuminate\Notifications\Channels\DatabaseChannel as IlluminateDatabaseChannel;
.
.
.
/**
* Bootstrap any application services.
*/
public function boot()
{
$this->app->instance(IlluminateDatabaseChannel::class, new DatabaseChannel);
}
重写在你需要通知的类
use App\Channels\DatabaseChannel;
.
.
.
public function via($notifiable)
{
return [DatabaseChannel::class];
}
最后不要忘记加上迁移文件
php artisan make:migration add_auto_id_column_to_notifications_table --table=notifications
public function up()
{
Schema::table('notifications', function (Blueprint $table) {
$table->integer('auto_id')->unsigned()->after('type')->nullable();
});
}
public function down()
{
Schema::table('notifications', function (Blueprint $table) {
$table->dropDolumn('auto_id');
});
}
php artisan migrate
总结:给 API 提供接口一定要先想好。不然后续修改兼容真的是难受。🤷🏼♂️🤷🏼♂️🤷🏼♂️
原文: http://yiqiao.me/articles/35/override-larravel-notification-to-implement-custom-fields
版权声明: 自由转载-非商用-非衍生-保持署名 (创意共享3.0许可证)