簡介
Laravel 自帶了一套訊息通知系統,還支援多種通知頻道,包括資料庫、郵件、簡訊等。
此處我們詳細說明資料庫通知頻道
建立通知類
Laravel 中一條通知就是一個類,(通常在 app/Notifications 檔案裡),命令如下:
php artisan make:notification TopicReplied
每個通知類都包含一個 via 方法 以及多個訊息構造方法( 如toMail或toDatabase )
via() 決定了通知在哪個頻道上傳送,如在資料庫作為通知:
public function via($notifiable)
{
// 開啟通知的頻道
return ['database'];
}
而toDatabase($notifiable)方法會返回一個陣列將被轉化為json格式並儲存到 notifications 資料表中的data欄位中。
資料庫通知
資料庫通知頻道會在一張資料表裡儲存所有資訊,包含了比如通知型別、JSON 格式資料等描述通知的資訊。
可以查詢此表的內容在應用介面上展示通知。
1.首先建立生成遷移表
php artisan notifications:table
會生成 database/migrations/{$timestamp}_create_notifications_table.php 遷移檔案
2.生成資料表
php artisan migrate
3.記錄未讀通知
在users表中新增 notification_count 欄位,用來跟蹤使用者有多少通知
php artisan make:migration add_notification_count_to_users_table --table=users
開啟生成的檔案,修改如下:
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->integer('notification_count')->unsigned()->default(0);
});
}
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('notification_count');
});
}
應用資料庫修改
php artisan migrate
傳送通知
1.讀取通知說明
在User模型類使用了Notifiable trait,而Notifiable中又引入了 HasDatabaseNotifications trait。
HasDatabaseNotifications中有3個函式,分別是 獲取所有通知、獲取未讀通知 和 已讀通知。
trait HasDatabaseNotifications
{
public function notifications()
{
return $this->morphMany(DatabaseNotification::class, 'notifiable')
->orderBy('created_at', 'desc');
}
public function readNotifications()
{
return $this->notifications()
->whereNotNull('read_at');
}
public function unreadNotifications()
{
return $this->notifications()
->whereNull('read_at');
}
}
由上可見,HasDatabaseNotifications 通過 關聯DatabaseNotification類讀取通知,在DatabaseNotification類中定義了$table = 'notifications' 。
此外 獲取未讀通知 unreadNotifications 方法 是根據 read_at 欄位作為判斷條件。
還有 DatabaseNotification 模型類中 定義了 標記訊息已讀的方法 markAsRead 和 標記訊息未讀的方法markAsUnread 。
2.觸發通知說明
Notifiable中引用了RoutesNotifications trait ,而RoutesNotifications定義了 notify($instance) 方法用來傳送通知
3.相關程式碼
app/Observers/ReplyObserver.php:
use App\Notifications\TopicReplied;
class ReplyObserver
{
public function created(Reply $reply)
{
$topic = $reply->topic;
$topic->increment('reply_count', 1);
// 通知作者話題被回覆了
$topic->user->notify(new TopicReplied($reply));
}
}
app/Models/User.php
use Auth;
class User extends Authenticatable
{
use Notifiable {
notify as protected laravelNotify; // 把系統的notify方法重新命名為laravelNotify
}
// 對notify()方法的重寫
public function notify($instance)
{
// 如果要通知的人是當前使用者,就不必通知了!
if ($this->id == Auth::id()) {
return;
}
$this->increment('notification_count');
$this->laravelNotify($instance);
}
}
相關檢視
生成控制器
php artisan make:controller NotificationsController
修改路由
Route::resource('notifications', 'NotificationsController', ['only' => ['index']]);
通知檢視
class NotificationsController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
// 獲取登入使用者的所有通知
$notifications = Auth::user()->notifications()->paginate(20);
return view('notifications.index', compact('notifications'));
}
}
標記通知為已讀
在 app/Models/User.php 中新增
public function markAsRead()
{
$this->notification_count = 0;
$this->save();
$this->unreadNotifications->markAsRead();
}
修改NotificationsController中index()新增
// 標記為已讀,未讀數量清零
Auth::user()->markAsRead();
本作品採用《CC 協議》,轉載必須註明作者和本文連結