Laravel 通知


创建通知

php artisan make:notification PrivateMessage

这条命令会在 app/Notifications 目录下生成一个新的通知类PrivateMessage。每个通知类都包含一个 via 方法以及一个或多个消息构建的方法(比如 toMail 或者 toDatabase),它们会针对指定的渠道把通知转换为对应的消息。

<?php

namespace AppNotifications;

use IlluminateBusQueueable;
use IlluminateContractsQueueShouldQueue;
use IlluminateNotificationsMessagesMailMessage;
use IlluminateNotificationsNotification;

class PrivateMessage extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return IlluminateNotificationsMessagesMailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

PrivateMessage

参考 Laravel 5.7 - New Notification System Tutorial for Beginner

可以在PrivateMessage的构造函数中,传入参数值。

修改如下:

<?php

namespace AppNotifications;

use IlluminateBusQueueable;
use IlluminateContractsQueueShouldQueue;
use IlluminateNotificationsMessagesMailMessage;
use IlluminateNotificationsNotification;

class PrivateMessage extends Notification
{
    use Queueable;
    private $details;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct($details)
    {
        //
        $this->details = $details;
    }

    /**
     * Get the notification's delivery channels.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['mail', 'database'];
    }

    /**
     * Get the mail representation of the notification.
     *
     * @param mixed $notifiable
     * @return IlluminateNotificationsMessagesMailMessage
     */
    public function toMail($notifiable)
    {
//        return (new MailMessage)
//            ->line('The introduction to the notification.')
//            ->action('Notification Action', url('/'))
//            ->line('Thank you for using our application!');
        return (new MailMessage)
            ->greeting($this->details['greeting'])
            ->line($this->details['body'])
            ->action($this->details['actionText'], $this->details['actionURL'])
            ->line($this->details['thanks']);
    }

    /**
     * Get the array representation of the notification.
     *
     * @param mixed $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }

    /**
     * Get the array representation of the notification.
     * @param $notifiable
     * @return array
     */
    public function toDatabase($notifiable)
    {
        return [
            'order_id' => $this->details['order_id']
        ];
    }
}

因为需要toDatabase,那么需要建立一张表格来存储通知的数据:

php artisan notifications:table

php artisan migrate

自动生成的数据库迁移文件如下:

<?php

use IlluminateDatabaseMigrationsMigration;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateSupportFacadesSchema;

class CreateNotificationsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('notifications', function (Blueprint $table) {
            $table->uuid('id')->primary();
            $table->string('type');
            $table->morphs('notifiable');
            $table->text('data');
            $table->timestamp('read_at')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('notifications');
    }
}

注意:toArray方法或toDatabase方法中返回的值,会被自动转换为JSON格式然后存储到data字段中。【注意toArray方法和toDatabase方法的区别】

toArray 方法可以同时被 database 和 broadcast 渠道调用,如果你希望 database 和 broacast 两个渠道有不同的数组展现方式,你需要定义 toDatabase 或者 toBroadcast 以取代定义 toArray 方法。


如果需要通过控制器方式触发,可以新建一个控制器然后添加方法,并在route中添加一个路由,访问路由链接触发控制器中该发送通知的方法即可:

控制器:

<?php

namespace AppHttpControllers;

use IlluminateHttpRequest;
use AppUser;
use Notification;
use AppNotificationsMyFirstNotification;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * Show the application dashboard.
     *
     * @return IlluminateContractsSupportRenderable
     */
    public function index()
    {
        return view('home');
    }

    public function sendNotification()
    {
        $user = User::first();

        $details = [
            'greeting' => 'Hi Artisan',
            'body' => 'This is my first notification from ItSolutionStuff.com',
            'thanks' => 'Thank you for using ItSolutionStuff.com tuto!',
            'actionText' => 'View My Site',
            'actionURL' => url('/'),
            'order_id' => 101
        ];

        Notification::send($user, new MyFirstNotification($details));

        dd('done');
    }

}
路由:
Route::get('随便写一个你觉得可以的链接', 'HomeController@index');
比如:Route::get('notify/index', 'HomeController@index');

一会访问链接触发Home控制器的index方法就可以了;

因为User模型中实现了IlluminateNotificationsNotifiable 这个trait,所以:

Notification::send($user, new MyFirstNotification($details));

也可以改成:

$user->notify(new MyFirstNotification($details));

如果需要通过其他方式通知,可以修改via方法:

public function via($notifiable)
{
    return ['mail', 'database','slack'];
}

并添加对应的方法 toDatabase

/**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toDatabase($notifiable)
    {
        return [
            'order_id' => $this->details['order_id']
        ];
    }

toSlack

public function toSlack($notifiable)
    {
        $message = "Famous Hello World!";

        return (new SlackMessage)
                ->from('Ghost', ':ghost:')
                ->to('#channel-name')
                ->content('Fix service request by '.$message);
    }

或者:

Slack的可以参考 Laravel Notifications – The Ultimate Guide

/**
 * Get the Slack representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return SlackMessage
 */
public function toSlack($notifiable)
{
    return (new SlackMessage)
        ->content('Account Registered successfully.');
}


via方法也可以参考 官方文档

public function via($notifiable)
{
    return $notifiable->prefers_sms ? ['nexmo'] : ['mail'];
}


而,为什么toMail方法会自动发送到对应的用户的邮箱上,它是如何找到用户的邮箱的 而如果我们要发送的用户的邮箱在数据库的其他字段中的时候,怎么办?

只需要在User类下重写routeNotificationForMail方法即可:

 /**
     * Route notifications for the mail channel.
     *
     * @param  IlluminateNotificationsNotification  $notification
     * @return array|string
     */
    public function routeNotificationForMail($notification)
    {
        // Return email address only...
        return $this->email_address;

        // Return name and email address...
        return [$this->email_address => $this->name];
    }


这样通知系统就找email_address字段的值了。

原理如下图:user实现了notifiable trait,下有RoutesNOtifications trait,其中包含一个routeNotificationFor方法;

批注 2020-03-29 150101

更多可以查看:

扒一扒 laravel的消息通知(上)

Laravel 论坛系统之消息通知功能

Laravel + 微信小程序 websocket 搭建广播消息系统

消息通知

消息通知系统记录

Laravel技巧集锦(38):显示私信列表和标记已读私信

Laravel——消息通知

使用 Laravel Notifynder 扩展轻松实现 Laravel 应用的消息通知功能

博客社区系统

原文地址:https://www.cnblogs.com/dzkjz/p/12592209.html