Laravel——訊息通知

劍歌丶君發表於2018-05-26

有的時候,在做一些業務的時候,可能會遇到這麼個需求。那就是,別人評論了你的某個東西,或者是關注你,再或者是收藏了你的文章,那麼作者,應該是需要被通知一下,以展現一下作者該有的成果,也可以滿足一下作者小小的虛榮心嘛。

Laravel其實內部就自帶訊息通知的。接下來就看看是怎麼使用的。

建立訊息notifications表,並且給使用者增添欄位notification_count

訊息表,毋庸置疑是給用來記錄訊息內容的——是誰在哪篇文章哪個時間評論了哪個作者的,對吧。那麼notifiation_count是記錄使用者有幾條訊息是未讀的對吧。 下面操作。

  1. 跑命令自動生成notification遷移表命令
php artisan notification:table
複製程式碼

會生成 database/migrations/{$timestamp}_create_notifications_table.php 遷移檔案,再執行下面命令將表新增到資料庫裡。

php artisan migrate
複製程式碼
  1. users表新增欄位,用來跟蹤使用者未讀的訊息,到時候就可以判斷是否大於0,來是否顯示出來。跑命令
php artisan make:migration add_notification_count_to_users_table --table=users
複製程式碼

這樣在databasemigration下就會生成這個遷移檔案。進行新增想要的欄位

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class AddNotificationCountToUsersTable extends Migration
{
    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');
        });
    }
}
複製程式碼

應用到資料庫修改,跑遷移命令,那麼users表裡就會增加一條notification_count欄位

php artisan migrate
複製程式碼

生成通知類

  1. 首先,跑以下命令自動在app\Notifications裡建立通知類。
php artisan make:notification TopicReplied
複製程式碼
  1. 修改檔案以下 app/Notifications/TopicReplied.php
<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use App\Models\Reply;

class TopicReplied extends Notification
{
    use Queueable;

    public $reply;

    public function __construct(Reply $reply)
    {
        // 注入回覆實體,方便 toDatabase 方法中的使用
        $this->reply = $reply;
    }

    public function via($notifiable)
    {
        // 開啟通知的頻道,因為是涉及資料庫的通知,這裡寫database
        return ['database'];
    }

    public function toDatabase($notifiable)
    {
        $topic = $this->reply->topic;
        //讓其跳到評論對應的地方
        $link =  $topic->link(['#reply' . $this->reply->id]);

        // 存入資料庫裡的資料
        return [
            'reply_id' => $this->reply->id,
            'reply_content' => $this->reply->content,
            'user_id' => $this->reply->user->id,
            'user_name' => $this->reply->user->name,
            'user_avatar' => $this->reply->user->avatar,
            'topic_link' => $link,
            'topic_id' => $topic->id,
            'topic_title' => $topic->title,
        ];
    }
}
複製程式碼

最後的toDatabase方法接收$notifiable的例項引數並返回一個陣列。 返回的陣列會以json格式儲存到notification表裡的data欄位中。

重寫User模型的notify方法。

預設的User模型裡用了trait——Notifiable的,它包含著一個可以用來發通知的一個方法notify(),該方法接收一個通知的例項作為引數。雖然notify()方法已經封裝的很方便了,但是我們想要每次呼叫的時候,讓欄位notification_count自動加一,這樣就能跟蹤使用者未讀通知了。

開啟 app/Models/User.php

<?php
.
.
.
use Auth
class User extends Authenticatable {
    use notifiable {
        notify as protected laravelNotify;
    }
    
    public function notify($instance) {
        // 如果不是當前使用者,就不必通知了
        if($this->id == Auth::id()) {
            return;
        }
        $this->increment('notification_count');
        $this->laravelNotify($instance);
    }
}
複製程式碼

這裡就對notify方法進行了巧妙的重寫,這樣,每次呼叫的時候,notification_count會自動 + 1。

觸發通知

那麼觸發的話,肯定就是在比如別的使用者評論了作者的某篇文章,也就是replyController裡進行store方法儲存的時候,觸發。

    public function store(Reply $reply) 
    {
        .
        .
        $topic = $reply->topic;
        $topic->increment('reply_count', 1);
        
        // 通知作者話題被回覆了
        $topic->user->notify(new TopicReplied($reply));
    }
複製程式碼

將通知的資料進行獲取並渲染

  1. 編寫訊息通知的路由
Route::resource('notifications', 'NotificationsController', ['only' => ['index']]);
複製程式碼
  1. 新建NotificationsController的控制器,為了方便對通知的管理,這裡就新建控制器,跑命令自動生成。
php artisan make:controller NotificatioonsController
複製程式碼
  1. 在控制器裡寫邏輯程式碼
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Auth;

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'));
    }
}
複製程式碼
  1. 這裡面值得注意的是,$notifications裡迴圈出來的資料,渲染的時候需要加上$notification->data然後在後面繼續跟上想要的資料。
<div class="infos">
        <div class="media-heading">
            <a href="{{ route('users.show', $notification->data['user_id']) }}">{{ $notification->data['user_name'] }}</a>
            評論了
            <a href="{{ $notification->data['topic_link'] }}">{{ $notification->data['topic_title'] }}</a>

            {{-- 回覆刪除按鈕 --}}
            <span class="meta pull-right" title="{{ $notification->created_at }}">
                <span class="glyphicon glyphicon-clock" aria-hidden="true"></span>
                {{ $notification->created_at->diffForHumans() }}
            </span>
        </div>
        <div class="reply-content">
            {!! $notification->data['reply_content'] !!}
        </div>
    </div>
複製程式碼

以上就是通知訊息的基本過程啦~~ 參考書籍《Laravel 教程 - Web 開發實戰進階 ( Laravel 5.5 )》,想學的小夥伴可以看看~

相關文章