Laravel المتقدم
الإشعارات والبث المتقدم
الإشعارات والبث المتقدم
يوفر نظام الإشعارات في Laravel واجهة برمجة تطبيقات موحدة لإرسال الإشعارات عبر قنوات متعددة. بالاشتراك مع البث، يمكنك إنشاء تطبيقات تفاعلية في الوقت الفعلي تبقي المستخدمين على اطلاع من خلال قنوات الاتصال المفضلة لديهم.
القنوات المتاحة: قاعدة البيانات، البريد الإلكتروني، البث، الرسائل النصية القصيرة (Vonage/Twilio)، Slack، Discord، والقنوات المخصصة. يمكنك إرسال إشعار واحد إلى قنوات متعددة في وقت واحد.
قنوات الإشعارات المخصصة
إنشاء قنوات مخصصة يسمح لك بإرسال إشعارات من خلال أي خدمة:
<?php
// app/Notifications/Channels/WhatsAppChannel.php
namespace App\Notifications\Channels;
use Illuminate\Notifications\Notification;
class WhatsAppChannel
{
public function send($notifiable, Notification $notification)
{
// احصل على الرسالة من الإشعار
$message = $notification->toWhatsApp($notifiable);
// الإرسال عبر WhatsApp API
$phoneNumber = $notifiable->routeNotificationFor('whatsapp', $notification);
Http::post('https://api.whatsapp.com/send', [
'phone' => $phoneNumber,
'message' => $message->content,
'media_url' => $message->mediaUrl ?? null,
]);
}
}
// إنشاء إشعار
class OrderShipped extends Notification
{
protected $order;
public function __construct($order)
{
$this->order = $order;
}
public function via($notifiable)
{
return ['whatsapp', 'database', 'mail'];
}
public function toWhatsApp($notifiable)
{
return (object) [
'content' => "تم شحن طلبك رقم #{$this->order->id}!",
'mediaUrl' => $this->order->tracking_image_url,
];
}
public function toDatabase($notifiable)
{
return [
'order_id' => $this->order->id,
'tracking_number' => $this->order->tracking_number,
'message' => 'تم شحن طلبك',
];
}
}
// نموذج المستخدم
public function routeNotificationForWhatsApp($notification)
{
return $this->whatsapp_number;
}
// إرسال الإشعار
$user->notify(new OrderShipped($order));
إشعارات قاعدة البيانات
تخزين الإشعارات في قاعدة البيانات لمراكز الإشعارات داخل التطبيق:
<?php
// Migration: php artisan notifications:table
// php artisan migrate
// إشعار مع قناة قاعدة البيانات
class CommentReceived extends Notification
{
protected $comment;
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'comment_id' => $this->comment->id,
'post_id' => $this->comment->post_id,
'author' => $this->comment->author->name,
'message' => $this->comment->author->name . ' علق على منشورك',
'action_url' => route('posts.show', $this->comment->post_id),
];
}
}
// استرداد الإشعارات في Controller
class NotificationController extends Controller
{
public function index()
{
$notifications = auth()->user()
->notifications()
->paginate(20);
return view('notifications.index', compact('notifications'));
}
public function unread()
{
$unreadNotifications = auth()->user()
->unreadNotifications()
->get();
return response()->json($unreadNotifications);
}
public function markAsRead($id)
{
$notification = auth()->user()
->notifications()
->findOrFail($id);
$notification->markAsRead();
return redirect($notification->data['action_url']);
}
public function markAllAsRead()
{
auth()->user()->unreadNotifications->markAsRead();
return response()->json(['message' => 'تم وضع علامة مقروء على جميع الإشعارات']);
}
}
واجهة مركز الإشعارات: اعرض عدد الإشعارات غير المقروءة في التنقل الخاص بك باستخدام `auth()->user()->unreadNotifications->count()`. استخدم التحديثات في الوقت الفعلي مع البث لإظهار الإشعارات الجديدة على الفور.
إشعارات البث
إرسال إشعارات في الوقت الفعلي باستخدام Laravel Echo و WebSockets:
<?php
// تثبيت دعم البث
// composer require pusher/pusher-php-server
// npm install --save-dev laravel-echo pusher-js
// config/broadcasting.php
'connections' => [
'pusher' => [
'driver' => 'pusher',
'key' => env('PUSHER_APP_KEY'),
'secret' => env('PUSHER_APP_SECRET'),
'app_id' => env('PUSHER_APP_ID'),
'options' => [
'cluster' => env('PUSHER_APP_CLUSTER'),
'encrypted' => true,
],
],
],
// إشعار مع قناة البث
class NewMessage extends Notification implements ShouldBroadcast
{
use Queueable;
protected $message;
public function via($notifiable)
{
return ['database', 'broadcast'];
}
public function toDatabase($notifiable)
{
return [
'message_id' => $this->message->id,
'sender' => $this->message->sender->name,
'preview' => Str::limit($this->message->content, 50),
];
}
public function toBroadcast($notifiable)
{
return new BroadcastMessage([
'message_id' => $this->message->id,
'sender' => [
'id' => $this->message->sender->id,
'name' => $this->message->sender->name,
'avatar' => $this->message->sender->avatar_url,
],
'content' => $this->message->content,
'created_at' => $this->message->created_at->toISOString(),
]);
}
public function broadcastType()
{
return 'message.new';
}
}
// الواجهة الأمامية مع Laravel Echo (resources/js/bootstrap.js)
import Echo from 'laravel-echo';
import Pusher from 'pusher-js';
window.Pusher = Pusher;
window.Echo = new Echo({
broadcaster: 'pusher',
key: import.meta.env.VITE_PUSHER_APP_KEY,
cluster: import.meta.env.VITE_PUSHER_APP_CLUSTER,
forceTLS: true
});
// الاستماع للإشعارات
Echo.private(`App.Models.User.${userId}`)
.notification((notification) => {
console.log('إشعار جديد:', notification);
// إظهار إشعار منبثق
showNotification(notification.sender.name, notification.content);
// تحديث عدد غير المقروء
updateUnreadCount();
// تشغيل صوت الإشعار
playNotificationSound();
});
تنسيق الإشعارات المتقدم
<?php
// إشعارات بريد إلكتروني غنية مع إجراءات
class InvoicePaid extends Notification
{
use Queueable;
protected $invoice;
public function toMail($notifiable)
{
return (new MailMessage)
->subject('تم دفع الفاتورة')
->greeting('مرحبًا '.$notifiable->name.',')
->line('تم دفع فاتورتك رقم #'.$this->invoice->id.'.')
->lineIf($this->invoice->hasDiscount(), 'تم تطبيق خصم بقيمة $'.$this->invoice->discount.'.')
->action('عرض الفاتورة', url('/invoices/'.$this->invoice->id))
->line('شكرًا لك على تعاملك معنا!')
->attach(storage_path('invoices/'.$this->invoice->pdf_file), [
'as' => 'invoice.pdf',
'mime' => 'application/pdf',
]);
}
}
// قنوات مشروطة بناءً على تفضيلات المستخدم
class SystemAlert extends Notification
{
public function via($notifiable)
{
$channels = ['database'];
if ($notifiable->prefers_email) {
$channels[] = 'mail';
}
if ($notifiable->prefers_sms) {
$channels[] = 'vonage';
}
if ($notifiable->is_online) {
$channels[] = 'broadcast';
}
return $channels;
}
}
// إشعارات محدودة المعدل (منع البريد العشوائي)
class RateLimitedNotification extends Notification
{
public function shouldSend($notifiable, $channel)
{
// إرسال بريد إلكتروني مرة واحدة فقط في الساعة
if ($channel === 'mail') {
return Cache::add(
'notification:'.$notifiable->id.':'.$channel,
true,
now()->addHour()
);
}
return true;
}
}
أمان البث: استخدم دائمًا القنوات الخاصة أو قنوات الحضور للإشعارات الخاصة بالمستخدم. لا تبث أبدًا معلومات حساسة على القنوات العامة. نفذ تفويضًا مناسبًا في مسارات البث الخاصة بك.
الإشعارات حسب الطلب
إرسال إشعارات إلى غير المستخدمين (الضيوف، الأطراف الخارجية):
<?php
use Illuminate\Support\Facades\Notification;
// الإرسال إلى عنوان بريد إلكتروني بدون نموذج مستخدم
Notification::route('mail', 'guest@example.com')
->route('vonage', '5555555555')
->notify(new OrderConfirmation($order));
// الإرسال إلى مستلمين متعددين
Notification::route('mail', [
'support@example.com',
'admin@example.com',
])->notify(new SystemAlert($issue));
// مع Slack webhook
Notification::route('slack', env('SLACK_WEBHOOK_URL'))
->notify(new DeploymentCompleted($deployment));
// فئة إشعار مخصصة حسب الطلب
class GuestPasswordReset extends Notification
{
protected $token;
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
$email = $notifiable->routes['mail'];
return (new MailMessage)
->subject('طلب إعادة تعيين كلمة المرور')
->line('لقد طلبت إعادة تعيين كلمة المرور.')
->action('إعادة تعيين كلمة المرور', url('reset-password/'.$this->token))
->line('إذا لم تطلب ذلك، يرجى تجاهل هذا البريد الإلكتروني.');
}
}
تمرين 1: ابنِ مركز إشعارات مع شارات غير مقروءة، ووظيفة وضع علامة مقروء، وتحديثات في الوقت الفعلي باستخدام البث. قم بتضمين التصفية حسب نوع الإشعار وزر "وضع علامة مقروء على الكل".
تمرين 2: أنشئ قناة إشعار Telegram مخصصة. نفذ فئة TelegramChannel التي ترسل الرسائل عبر Telegram Bot API. أرسل تحديثات الطلب من خلال كل من البريد الإلكتروني و Telegram.
تمرين 3: نفذ نظام تفضيلات الإشعارات حيث يمكن للمستخدمين اختيار القنوات التي يريدون تلقي الإشعارات عليها. أنشئ صفحة إعدادات مع مفاتيح تبديل للبريد الإلكتروني والرسائل النصية القصيرة والإشعارات الفورية لأنواع الأحداث المختلفة.