Bildiğiniz gibi Laravel bildirimler için Database, Broadcast, SMS ve Slack kanallarını halihazırda sunmakta. Biz de projelerimizi geliştirirken bunları sık sık kullanıyoruz. Ben kendi projelerimde en çok Database ve Broadcast kanallarını kullanıyorum. Ayrıca Laravel ihtiyaçlarımıza uygun kanal oluşturmaya da imkân tanıyor.
Ben projelerimi modüler olarak geliştirdiğim için bildirimleri de modüler olarak ayırmaya çalışıyorum. Bu nedenle Database bildirim kanalını her projede değiştirmek zorunda kalıyorum.
Bilindiği gibi Laravel notifications
tablosundaki type
alanında bizim bildirim sınıfının tam yolunu saklıyor. Örneğin MessageSentNotification
adında bir bildirimimiz varsa bu veritabanına type
alanında App\Notifications\User\Chat\MessageSentNotification
olarak kaydediliyor. User\Chat\
kısmı benim modüller yapıdan dolayı geldi. Eğer bildirim sınıflarınızı alt klasörlere taşımadıysanız sizde App\Notifications\MessageSentNotification
şeklinde görünür.
Hal böyle olunca eğer frontent tarafında bildirimlerinizi tiplerine göre farklı şekillerde göstermek isterseniz mecburen App\Notifications\User\Chat\MessageSentNotification
şeklinde kontrol etmeniz gerekir. Frontend ve backend tarafları farklı kişiler tarafından geliştiriliyorsa veya bir API ile bu bildirimleri de dışarı vermeniz gerekiyorsa backend mimarinizi açıkça ortaya koymuş olursunuz. Şimdi benim bu durumu atlatmak için izlediğim adımları görelim..
İlk olarak Illuminate\Notifications\Channels\DatabaseChannel
sınıfını App\Notification
aldında CustomDBChannel
adıyla kopyalayalım.
Not: Kodların uzamaması için açıklama satırlarını sildim.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
<?php namespace Illuminate\Notifications\Channels; use Illuminate\Notifications\Notification; use RuntimeException; class DatabaseChannel { public function send($notifiable, Notification $notification) { return $notifiable->routeNotificationFor('database', $notification)->create( $this->buildPayload($notifiable, $notification) ); } protected function getData($notifiable, Notification $notification) { if (method_exists($notification, 'toDatabase')) { return is_array($data = $notification->toDatabase($notifiable)) ? $data : $data->data; } if (method_exists($notification, 'toArray')) { return $notification->toArray($notifiable); } throw new RuntimeException('Notification is missing toDatabase / toArray method.'); } protected function buildPayload($notifiable, Notification $notification) { return [ 'id' => $notification->id, 'type' => get_class($notification), 'data' => $this->getData($notifiable, $notification), 'read_at' => null, ]; } } |
Ardından namespace hatası vermemesi için namespace Illuminate\Notifications\Channels;
yerine namespace App\Notifications;
yazalım.
Gördüğünüz gibi 'type' => get_class($notification),
satırında type
atamasını bizim müdahale edemeyeceğimiz şekilde kendisi yapıyor. Biz burayı değiştirip aşağıdaki gibi yapalım.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?php namespace App\Notifications; use Illuminate\Notifications\Notification; use RuntimeException; class CustomDBChannel { // ... diğer kodlar.. protected function buildPayload($notifiable, Notification $notification) { $type = get_class($notification); if(property_exists($notification, 'type') && $notification->type !== null){ $type = $notification->type; } return [ 'id' => $notification->id, 'type' => $type, 'data' => $this->getData($notifiable, $notification), 'read_at' => null, ]; } } |
Bu değişilikle eğer varsa MessageSentNotification
sınıfındaki $type
değerini al, yoksa kendi bildiğin gibi yap demiş oluyoruz.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
<?php namespace App\Notifications\User\Chat; use App\Models\Chat\Message; use App\Notifications\CustomDBChannel; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Notification; class MessageSentNotification extends Notification { use Queueable; public Message $message; public ?string $type = "MessageSent"; public function __construct(Message $message) { $this->message = $message; } public function via($notifiable) { return [CustomDBChannel::class]; // return ['database']; } public function toArray($notifiable) { return [ 'message' => $this->message->message, ]; } } |
Bildirim sınıfında ise 2 işlem yapmamız gerekiyor. İlk olarak $type
adında property tanımlayıp değerini veritabanında görmek istediğimiz gibi yapmalıyız. Ardından via
içindeki return ['database'];
kısmını return [CustomDBChannel::class];
ile değiştirmemiz gerekiyor. Gerekli use App\Notifications\CustomDBChannel;
tanımlamasını da yukarıya ekledikten sonra artık bildirim veritabanına kaydedilirse type
sütununda App\Notifications\User\Chat\MessageSentNotification
yerine MessageSent
görünecektir.
Bu değişiklik sayesinde bildirim tiplerini istediğimiz gibi kaydetme imkânımız oldu.
Bildirimler hakkında farklı bilgiler edinmek isterseniz Laravel’de Event ve Notification Arasındaki Fark Nedir? yazımı okuyabilirsiniz.
Herhangi bir sorunuz olursa yorum yoluyla ulaşabilirsiniz.
Faydalı olması dileğiyle..
İlk Yorumu Siz Yapın