مقدمة إلى نظام الإشعارات Notifications في Laravel


محمد أحمد العيل

يضيف الإصدار 5.3 من Laravel نظاما للإشعارات Notifications يمكن من خلاله إخطار المستخدم بحدوث شيء ما. تُستخدَم الإشعارات، التي تكون عادة على هيئة بلاغات قصيرة، لإعلام مستخدم التطبيق بوقوع أمر ما؛ على سبيل المثال “صدور فاتورة”، “تسجيل مستخدم”، “إعادة تعيين كلمة السّر” أو “نشر درس”؛ حسب طبيعة التطبيق الذي تعمل عليه.

1.png

يتيح نظام الإشعارات في Laravel 5.3 وسائط عدّة (تُسمّى قنوات Channels) لتوصيل الإشعار: البريد الإلكتروني، الرسائل النصية القصيرة SMS (بالاعتماد على خدمة Nexmo) وخدمة Slack. يمكن أيضا تخزين الإشعارات في قاعدة البيانات من أجل عرضها في واجهة الوِب.

سنرى في هذا الدرس كيفية عمل الإشعارات، بأخذ مثال لإشعار يُرسَل إلى بريد المستخدم عند إضافة منشور جديد.

تهيئة المشروع

نبدأ أولا بتهيئة المشروع الذي سنعمل عليه. أنشئ مشروع Laravel 5.3 جديدا، إن لم يكن لديك واحد جاهز واضبط إعدادات قاعدة البيانات. نستخدم نفس الإعدادات المذكورة في فقرة تهيئة بيئة التطوير من درس أساسيات التخبئة في Laravel؛ مع التعديل عليها قليلا. سنضيف صنفا لبذر المستخدمين:

 
php artisan make:seeder UsersTableSeeder

ونعدّل صنف البذر على النحو التالي لإضافة مستخدمَيْن إلى قاعدة البيانات:

public function run()
{
    $user1 = [
      'name' => 'Med Ahmed Eyil',
      'email' => 'medeyil@laravel.com',
      'password' => Hash::make('1234'),
    ];
    $user2 = [
      'name' => 'Fatima Benziane',
      'email' => 'fbenziane@laravel.com',
      'password' => Hash::make('4567'),
    ];

    User::create($user1);
    User::create($user2);
}

ثم ننفّذ البذر:

php artisan db:seed

يصبح لدينا الآن نموذجان، واحد للمستخدمين وآخر للمنشورات.

ننتقل إلى ملف المسارات routes/web.php ونضيف المسار التالي:

Route::get('/notify/{user_id}/{post_id}', 'PostsController@notify');

يعني هذا أنه عند زيارة الرابط notify/user_id/post_id/ (حيث user_id وpost_id معرّفا المستخدم والمنشور على التوالي) سيطلُب Laravel تنفيذ الدالة notify في المتحكم PostsController. نعدّل المتحكّم PostsController لإضافة هذه الدالة:

public function notify($user_id,$post_id) {
    $user = User::find($user_id);
    $post = Post::find($post_id);

    // todo
}

سنعود لاحقا لإكمال الدالة notify التي تكتفي لحد الساعة بالعثور على المستخدم والمنشور الممررَيْن إليها في المعطيات.

الإشعارات

هدفنا هو التالي: يطلُب المتصفح الرابط notify/1/2/ (مثلا) فيُرسَل إشعار عبر البريد إلى المستخدم ذي المعرف 1 يخبره أن المنشور ذا المعرف 2 قد أُضيف إلى الموقع. سنحتاج لبلوغ هذا الهدف لإشعار “إضافة منشور”. ننفذ الأمر التالي لإنشاء هذا الإشعار:

php artisan make:notification NewPost

ستلاحظ بعد تنفيذ الأمر أعلاه ظهور مجلد جديد باسم Notifications (إن لم يكن موجودا سلفا) متفرع عن المجلد app وبداخله صنف باسم NewPost.php (نزعنا التعليقات للاختصار):

<?php

namespace App\Notifications;

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

class NewPost 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', 'https://laravel.com')
                    ->line('Thank you for using our application!');
    }

    public function toArray($notifiable)
    {
        return [
        ];
    }
}

يمدّد الصنف NewPost الصنفَ Notification الذي يحوي التعليمات الضرورية للتعامل مع الإشعارات. تظهر الدالة المشيّدة Constructor وثلاث دوال أخرى:

  • via: تعرّف القنوات التي نريد إرسال الإشعارات عبرها. توجد قناة البريد mail مبدئيا. تمكن إضافة قناة أخرى من تلك المتوفرة. يستخدم Laravel جميع القنوات المذكورة في المصفوفة المرجَعة، بمعنى؛ إن حددت مثلا القناتين mail وdatabase في المصفوفة فإن الإشعار سيُرسَل عبر البريد ويُخزَّن أيضا في قاعدة البيانات.
  • toMail: هذه الدالة خاصّة بالتعامل مع قناة البريد الإلكتروني. تنشئ الدالة toMail كائنا من صنف MailMessage لتخصيص بريد إلكتروني. سنعود لهذا الصنف بعد قليل.
  • toArray: إن حدّدت قناة للإشعارات في الدالة via دون أن تنشئ دالة خاصّة للتعامل معها فسيستدعي Laravel الدالة toArray. تجدر الإشارة إلى أن الدوال المخصّصة للتعامل مع قنوات الإشعارات تبدأ بـto متبوعة باسم القناة. مثلا toMail للبريد الإلكتروني (تأتي مبدئيا) وtoDatabase لتخصيص الإشعار عبر قناة قاعدة البيانات.

نعدّل الصنف NewPost قليلا بحيث نمرّر للمشيّد معطى من نوع Post (نزعنا أجزاء الصنف التي لم يطرأ عليها تعديل):

<?php

// استدعاء الأصناف، أضفنا إليه الصنف Post
use App\Post;

class NewPost extends Notification
{

    // أضفنا خاصيّة post إلى الصنف
    protected $post;

    public function __construct(Post $post)
    {
        $this->post = $post;
    }

// بقية شفرة الصّنف
}

نعود إلى الدالة notify في المتحكم ونعدّلها لتصبح على النحو التالي:

public function notify($user_id,$post_id) {
    $user = User::find($user_id);
    $post = Post::find($post_id);

    $user->notify(new NewPost($post));
}

لا تنس استدعاء الصنف NewPost في المتحكم:

 
use App\Notifications\NewPost;

استدعينا الدالة notify من الكائن user$ ومررنا إليها صنفا جديدا من الإشعار NewPost.

سنحتاج قبل تجربة إرسال الإشعار إلى ضبط البريد الإلكتروني في ملف النظام env.. ستجد في الملف عند فتحه الإعدادات التالية:

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

يقترح Laravel مبدئيا موقع https://mailtrap.io الذي يوفر خدمة لمحاكاة إرسال بريد إلكتروني وعرضه. نحصُل بالتسجيل في الموقع على صندوق بريد للاختبار. ندخل إلى صندوق البريد (Demo inbox).

01_mailtrap_credentials.png

ننسخ قيم Username وPassword ونضيفها إلى الإعدادات في ملف env. على النحو التالي:

MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME="be7c7d3972da27"
MAIL_PASSWORD="5f445b7bdca027"
MAIL_ENCRYPTION=null

يمكننا الآن اختبار الإشعار بتشغيل خادوم التطبيق والذهاب إلى المسار http://localhost:8000/notify/1/2. إن نظرت في صندوق البريد على موقع mailtrap فستجد رسالة جديدة:

02_email_notification.png

لاحظ العنوان البريدي الذي يُوجّه إليه الإشعار medeyil@laravel.com. إن عدلت المسار الذي تطلُبه إلى التالي http://localhost:8000/notify/2/2 ونظرت في الإشعار الذي يصل إلى البريد فستجد أن المرسَل إليه To تبدّل إلى fbenziane@laravel.com الذي هو بريد المستخدم ذي المعرف 2.

03_email_notification.png

هل تساءلت كيف يعرف نظام الإشعارات البريد الإلكتروني الذي يجب إرسال الإشعار إليه، أي البريد الإلكتروني الخاصّ بالمستخدِم؟

تخصيص الإشعار عبر البريد الإلكتروني

يمكن تطبيق الإشعارات على أي نموذج Eloquent في النظام، بشرط أن يستخدم النموذجُ السّمةَ Trait المسمّاة Notifiable. إن نظرنا إلى النموذج User الذي يأتي مبدئيا مع المشروع فسنلاحظ التالي:

 
use Illuminate\Notifications\Notifiable;

و

use Notifiable;

يتيح استخدام هذه السمة في النموذج إمكانية استدعاء الدالة notify:

$user->notify(new NewPost($post));

التي تأخذ معطى عبارة عن كائن من صنف Notification.

بالنسبة لكيفية معرفة نظام الإشعارات ببريد المستخدم فالإجابة هي أن كل قناة إشعار تتطلّب وجود خاصيّات Properties معيّنة في النموذج الذي يستدعي الدالة notify. في حالة قناة البريد الإلكتروني فإن الخاصيّة المنتظرة هي - منطقيا - عنوان البريد email.

بالعودة إلى الصنف NewPost لاحظ دالة التعامل مع البريد الإلكتروني:

public function toMail($notifiable)
{
    return (new MailMessage)
                ->line('The introduction to the notification.')
                ->action('Notification Action', 'https://laravel.com')
                ->line('Thank you for using our application!');
}

ترجع هذه الدالة كائنا من صنف MailMessage. إن تنبهت جيدا فستدرك أن العبارات الواردة في الشفرة أعلاه هي نفسها الموجودة في البريد المرسَل إلى المستخدم:

  • الدالة line تدرج فقرة في بريد الإشعار.
  • الدالة action تدرج زرًّا وتحدّد النص الذي يظهر على الزرّ ورابط الصفحة التي تزورها عند النقر على هذا الزرّ.

توجد دوال أخرى لتخصيص الإشعار أكثر:

  • subject لتخصيص موضوع البريد الإلكتروني.
  • from لتحديد بريد المرسِل.
  • attach لإضافة ملف مرفَق.
  • priority لتحديد الأولوية (1 تعني أولوية قصوى).

نخصّص في ما يلي البريد السّابق:

public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject('New post: '. $this->post->title)
                ->line('Don\'t miss our new post ' .$this->post->title)
                ->action('View the post', 'https://laravel.com')
                ->line('Thank you for your visit!')
                ->from('hsoub@academy.com');
}

نحصل بزيارة الرابط http://localhost:8000/notify/1/2 على النتيجة أدناه.

04_email_notification.png

بالنسبة لاسم التطبيق الذي يظهر في الإشعار فيمكن تعديله عن طريق التعليمة name في ملف الإعداد config/app.php. تأخذ التعليمة مبدئيا القيمة Laravel.

إن أردت تخصيصا أكبر للبريد ومظهره فيمكنك ذلك بنشر قالب Blade الخاص بالبريد الإلكتروني للإشعار ومن ثم تخصيصه. نفذ الأمر التالي لنشر القالب:

 
php artisan vendor:publish --tag=laravel-notifications

ستجد القالب على المسار resources/views/vendor/notifications/email.blade.php؛ حيث يمكنك التعديل عليه بما تراه مناسبا.



1 شخص أعجب بهذا


تفاعل الأعضاء


لا توجد أيّة تعليقات بعد



يجب أن تكون عضوًا لدينا لتتمكّن من التعليق

انشاء حساب جديد

يستغرق التسجيل بضع ثوان فقط


سجّل حسابًا جديدًا

تسجيل الدخول

تملك حسابا مسجّلا بالفعل؟


سجّل دخولك الآن