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