في بعض الأحيان يجب إشعار المستخدمين بحدوث تغييرات على حسابهم بالموقع، مثل إشعارهم بتحديث حالة طلبات الشراء، إشعار الإداريين بوجود تسجيل جديد على الموقع، إشعار المستخدمين بأنه تم الإجابة على أحد الأسئلة في المنتديات .... وغيرها، وكما نعلم أن لارافيل توفر mailables لإرسال رسائل البريد الإلكتروني بتنسيقات Markup، إلا أنه في الإشعارات notification تكون الرسالة مختصره وتؤدي غرض الإشعار فقط.
توفر لارافيل مجموعة من الخيارات لإرسال الإشعارات، وهي:
Mail : إشعارات بإرسال رسائل من خلال البريد الإلكتروني.
SMS: إشعارات من خلال إرسال الرسائل النصية.
Database: حيث يتم حفظ الإشعار في قواعد البيانات، وعندما يسجل المستخدم الدخول لحسابة سوف تظهر له الإشعارات.
Slack: إرسال الإشعارات من خلال Slack Channel.
في هذه المقال سيتم التطرق إلى إرسال الإشعارات بإستخدام (Mail, Database).
إستخدام الإشعارات في لارافيل سهل جدا، حيث يتم إنشاء كلاس للإشعارات، وفي هذا الكلاس يمكن لنا تحديد channels ووصف الإشعار
لإنشاء إشعار
php artisan make:notification NewUser
بعد تنفيذ الأمر سيتم إنشاء كلاس بإسم NewUser في المسار app/Notifications/NewUser.php بحيث يحتوي على ثلاث دوال:
class NewUser extends Notification { use Queueable; public function __construct(){} public function via($notifiable) { return ['mail']; } public function toMail($notifiable) { return (new MailMessage) ->line('The introduction to the notification.') ->action('Notification Action', url('/')) ->line('Thank you for using our application!'); } public function toArray($notifiable) { return [ // ]; } }
من خلال الدالة via نستطيع تحديد channel التي نريد إستخدامها لإرسال الإشعارات، وكما نرى أنه بشكل إفتراضي تم تحديد النوع بـ email، وبما أن النوع email بالتالي فإن دالة الإرسال يجب أن يكون إسمها toMail كما نرى بالأعلى، ولو كان النوع Database يجب تغيير إسم دالة الإرسال إلى toDatase
من أجل إستخدام laravel Notification في User Model يجب إستخدام illuminate\Notifications\Notifiable trait من خلال إضافة use Notifiable إلى الـ model
namespace App\Models; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class User extends Authenticatable { use HasFactory, Notifiable; }
مع الإنتباه إلى أن لارافيل بالوضع الإفتراضي تقوم بإضافة Notifiable إلى User model بشكل إفتراضي، لكن إذا أردنا أن يتم إستخدامة في models أخرى مثل Admin, Customer يجب تعريف Notifiable trait بداخل الـ model.
بعد إضافة الـ trait لإستخدامه عند تسجيل مستخدم جديد
use App\Notifications\NewUser; $user->notify(new NewUser());
كما يمكن التعديل على نص الرسالة بالشكل الذي نراه مناسبا
public function toMail($notifiable) { return (new MailMessage) ->line('Welcome to our application, you now can use our application.') ->action('Visit Your Account', url('/')) ->line('Thank you for using our application!'); }
لإستخدام Database Notification يجب إنشاء جول لذلك، ويتم ذلك من خلال الأمر
php artisan notifications:table
حيث يتم إنشاء ملف migration بإسم notifications
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(); }); }
من ثم ننفذ الأمر migrate
php artisan migrate
حيث يتم إنشاء جدول بإسم notification
كما قلنا سابقا، أنه في كلاس NeuUser تم تحديد نوع الدالة via بـ email لأننا كنا نرسل الإشعارات بإستخدام البريد الإلكتروني، لكن هنا سوف نستخدم قواعد البيانات بالتالي يجب إضافة database إلى الدالة via.
كذلك يجب تعديل إضافة دالة toDatabase أو إستخدام دالة toArray وكلتا الدالتين يجب أن ترجعا مصفوفة PHP وهذه المصفوفة هي ما سيتم تخزينة في قاعدة البيانات، وبما أن الكلاس NewUser بالوضع الإفتراضي يحتوي على دالة toArray بالتالي يمكن إستخدامها بعد عمل التعديلات عليها بما يناسب الإشعار الذي نريد إرسالة.
<?php namespace App\Notifications; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class NewUser extends Notification { use Queueable; public function __construct(){} public function via($notifiable) { return ['mail','database']; } public function toMail($notifiable) { return (new MailMessage) ->line('The introduction to the notification.') ->action('Notification Action', url('/')) ->line('Thank you for using our application!'); } public function toArray($notifiable) { return [ 'message' => 'Account registered successfully.' ]; } }
الأن عند تسجيل مستخدم جديد، سوف يتم إرسال إشعار بواسطة البريد الإلكتروني وكذلك، إشعار في قاعدة البيانات
توفر لارافيل مجموعة من الدوال للوصول إلى الإشعارات، وبما أن user model لدينا يستخدم Notifiable trait والذي يحتوي على Eloquent Relationship والتي ترجع الإشعارات للمستخدم
للحصول على الإشعارات لمستخدم معين
$user = auth()->user(); foreach ($user->unreadNotifications as $notification){ return $notification; }
هنا سيتم إرجال الإشعارات التي تتبع للمستخدم الذي قام بتسجيل الدخول.
{ "id": "e61e6eec-722f-4fb4-ba7e-9972aeced2c9", "type": "App\\Notifications\\NewUser", "notifiable_type": "App\\Models\\User", "notifiable_id": 3, "data": { "message": "Account registered successfully." }, "read_at": null, "created_at": "2021-04-08T12:02:01.000000Z", "updated_at": "2021-04-08T12:02:01.000000Z" }
لتعديل حقل read_at وجعل الإشعار مقروء، بكل بساطة نستخدم دالة markAsRead
$user->unreadNotifications->markAsRead();
ولحذف الإشعار
$user->notifications()->delete();
هذه كانت محاولة لتبسيط مفهوم وإستخدام الإشعارات، للمزيد يمكنكم قراءة التوثيق الرسمي لموقع لارافيل.
في مقال سابق تحدثنا عن أهمية Queue، وكما نعلم أن بعض الإشعارات تستغرق بعض الوقت، خاصه في الإشعارات التي تستخدم API خارجي، ولتحسين أداء وسرعة الموقع يجب تقليل وقت التنفيذ والإستجابة، ولعمل Queue للإشعارات:-
يجب وضع إعدادات Notification والتي يمكن الإطلاع عليها من خلال هذه المقال.
تطبيق ShouldQueue interface على الكلاس NewUser
class NewUser extends Notification implements ShouldQueue { }
وإذا كنا نريد أن يكون هناك تأخير في إرسال الإشعار، يمكننا إستخدام دالة delay
$delay = now()->addMinutes(10); $user->notify((new NewUser($user))->delay($delay));
ويمكننا إنشاء مصفوفة من delay لكل channel
$user->notify((new NewUser($user))->delay([ 'mail' => now()->addMinutes(5), 'sms' => now()->addMinutes(10), ]));
هذه كانت محاولة لتبسيط مفهوم وإستخدام الإشعارات، للمزيد يمكنكم قراءة التوثيق الرسمي لموقع لارافيل.
Sherif Essam
شكرا جدا علي المحتوي الجميل ده ربنا يزيدك بالعلم ويوفقك