重写 Laravel Notification 实现自定义字段

重写 Laravel Notification 实现自定义字段

Laravel 1 month ago 63 0

最近开发站内信功能,由于是半路接入的,本来可以用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许可证)