handle notification preferences
I have the event NewCommentWasAddedToPost
And this listener NotifyMentionedUsers
A user has the following notifications preferences
$user->preferences()->comment_on_my_post = ['database']
For example, when user B adds a comment to user A's post, then A will receive a database notification )
$user->preferences()->comment_on_participated_post = ['database']
For example, when user A adds a comment on B's post, and C also comments on the same post, then user A will receive a database notification
$user->preferences()->mentioned_in_comment = ['database']
When the name of A is mentioned on a comment, then A will receive a database notification.
As you understand, there are cases that a user receives two notifications for the same comment.
For example, if A creates a post, and B comments on that post and also mention A's name
Then A will receive a notification because
- another user commented on the post
- the name was mentioned in the comment
Whereas, I want to do something like
class NotifyMentionedUsers
{
public function handle(NewCommentWasAddedToPost $event)
{
$mentionedUsers = User::query()
->whereIn('id', $event->comment->mentionedUsers())
->where('id', '!=', $event->comment->owner->id)
->get();
$mentionedUsers->each(function($user) use($event) {
$user->notify(new YouHaveBeenMentionedInAComment($comment));
});
}
}
class YouHaveBeenMentionedInAComment
{
public function __construct(public $comment){}
public function handle($notifiable)
{
$postParticipantIds = $event->comment
->post->comments()
->pluck('user_id');
$preferences = $notifable->preferences();
if($notifiable->is($comment->post->owner))
{
// therefore, if the post owner has enabled database notifications when a another user comments on the post, then the post owner will not receive database notification because was mentioned in that comment
return array_diff(
$preferences()->mentioned_in_comment,
$preferences->comment_on_my_post
);
// if the notifiable has chosen to receive notifications when another user comments on the same post, then the notifiable will not receive notification because was mentioned in the comment
}elseif ($postParticipantIds->contains($notifiable->id))
{
return array_diff(
$preferences()->mentioned_in_comment,
$preferences->comment_on_participated_post
);
}else{
return $notifiable->mentioned_in_comment;
}
}
P.S new channels might be added, and in my mind it makes more sense this logic to be handled in the via method in the notification.
Is there a better way to approach this ? or I should at least extract a class and put all the conditions in so
public function via($notifiable)
{
return CommentNotifications->getChannels($notifiable, $event);
}
Please or to participate in this conversation.