commentNotificationToAuthorFeed($comment, $feed);
// now notify all users who commented on this feed
$this->commentNotificationToFeedCommenters($comment, $feed);
}
public function handleNewSpaceFeed($feed)
{
if (!$this->willCreateFeedCreatedNotification($feed)) {
return;
}
$user = $feed->user;
$space = $feed->space;
$this->maybeHasEveryoneTag($feed);
$userIds = SpaceUserPivot::where('space_id', $space->id)
->where('user_id', '!=', $user->ID)
->where('status', 'active')
->pluck('user_id')
->toArray();
if (!$userIds) {
return;
}
$feedTitle = $feed->getHumanExcerpt(60);
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the feed title and %3$3s is the space title */
__('%1$s posted %2$s in %3$s', 'fluent-community'),
'' . esc_html($user->display_name) . '',
'' . $feedTitle . '',
'' . esc_html($space->title) . ''
);
$route = $feed->getJsRoute();
$notification = [
'feed_id' => $feed->id,
'src_user_id' => $user->ID,
'src_object_type' => 'feed',
'action' => 'space_feed/created',
'content' => $notificationContent,
'route' => $route,
];
$notification = Notification::create($notification);
$notification->subscribe($userIds);
}
public function handleNewFeedReact($react, $feed)
{
if ($react->user_id == $feed->user_id) {
return;
}
$feedTitle = $feed->getHumanExcerpt(60);
$user = $react->user;
if ($feed->reactions_count > 1) {
// check if we have existing notification for this feed and user
$existingNotification = Notification::where('feed_id', $feed->id)
->where('action', 'feed/react_added')
->first();
if ($existingNotification) {
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the like count & %3$s is the feed title */
__('%1$s and %2$s other people reacted to %3$s', 'fluent-community'),
'' . esc_html($user->display_name) . '',
'' . ($feed->reactions_count - 1) . '',
'' . $feedTitle . ''
);
$existingNotification->content = $notificationContent;
$existingNotification->src_user_id = $user->ID;
$existingNotification->save();
NotificationSubscriber::where('object_id', $existingNotification->id)
->where('user_id', $feed->user_id)
->update([
'is_read' => 0,
'updated_at' => current_time('mysql')
]);
return;
}
}
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the feed title */
__('%1$s reacted to %2$s', 'fluent-community'),
'' . esc_html($user->display_name) . '',
'' . $feedTitle . ''
);
$route = $feed->getJsRoute();
$notification = [
'feed_id' => $feed->id,
'src_user_id' => $user->ID,
'src_object_type' => 'feed',
'action' => 'feed/react_added',
'content' => $notificationContent,
'route' => $route,
];
$notification = Notification::create($notification);
$notification->subscribe([$feed->user_id]);
}
public function handleSpaceMemberRoleUpdated($space, $pivot)
{
$user = $pivot->user;
$notificationContent = \sprintf(
/* translators: %1$s is the role name, %2$s is the space title */
__('You have been added as %1$s in %2$s', 'fluent-community'),
'' . $pivot->role . '',
'' . $space->title . ''
);
$route = [
'name' => 'space_feeds',
'params' => [
'space' => $space->slug
]
];
$notification = [
'object_id' => $space->id,
'src_user_id' => $user->ID,
'src_object_type' => 'space',
'action' => 'space/member/role_updated',
'content' => $notificationContent,
'route' => $route,
];
$notification = Notification::create($notification);
$notification->subscribe([$pivot->user_id]);
}
protected function commentNotificationToAuthorFeed(Comment $comment, Feed $feed)
{
if ($comment->user_id == $feed->user_id) {
return;
}
$mentionedUserIds = Arr::get($feed->meta, 'mentioned_user_ids', []);
if (in_array($feed->user_id, $mentionedUserIds)) {
return;
}
$commenter = '' . esc_html($comment->user->display_name) . '';
$feedTitle = $feed->getHumanExcerpt(60);
$exist = null;
if ($feed->comments_count > 1) {
// check if we have existing notification for this feed and user
$exist = Notification::where('feed_id', $feed->id)
->where('action', 'comment_added')
->first();
$totalUsers = $feed->comments
->where('user_id', '!=', $feed->user_id)
->pluck('user_id')
->unique()
->count();
if ($feed->space_id) {
if ($totalUsers > 1) {
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the people count, %3$s is the feed title and %4$s space title*/
__('%1$s and %2$s other people commented on your post %3$s in %4$s', 'fluent-community'),
$commenter,
'' . ($totalUsers - 1) . '',
'' . $feedTitle . '',
'' . $feed->space->title . ''
);
} else {
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the feed title and %3$s space title*/
__('%1$s commented on your post: %2$s in %3$s', 'fluent-community'),
$commenter,
'' . $feedTitle . '',
'' . $feed->space->title . ''
);
}
} else {
if ($totalUsers > 1) {
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the like count & %3$s is the feed title */
__('%1$s and %2$s other people commented on your post %3$s', 'fluent-community'),
$commenter,
'' . ($totalUsers - 1) . '',
'' . $feedTitle . ''
);
} else {
$notificationContent = \sprintf(
/* translators: %1$s is the user name & %2$s is the feed title */
__('%1$s commented on your post: %2$s', 'fluent-community'),
$commenter,
'' . $feedTitle . ''
);
}
}
} else {
if ($feed->space_id) {
$notificationContent = \sprintf(
/* translators: %1$s is the commenter name, %2$s is the feed title & %3$s is the space title */
__('%1$s commented on your post: %2$s in %3$s', 'fluent-community'),
$commenter,
'' . $feedTitle . '',
'' . $feed->space->title . ''
);
} else {
$notificationContent = \sprintf(
/* translators: %1$s is the commenter name & %2$s is the feed title */
__('%1$s commented on your post: %2$s', 'fluent-community'),
$commenter,
'' . $feedTitle . ''
);
}
}
$route = $feed->getJsRoute();
if ($exist) {
$exist->content = $notificationContent;
$exist->updated_at = current_time('mysql');
$exist->src_user_id = $comment->user->ID;
$exist->object_id = $comment->id;
$exist->save();
NotificationSubscriber::where('object_id', $exist->id)
->where('user_id', $feed->user_id)
->update([
'is_read' => 0,
'updated_at' => current_time('mysql')
]);
do_action('fluent_community/notification/comment/notifed_to_author', [
'user_ids' => [$feed->user_id],
'notification' => $exist,
'key' => 'notifed_to_author',
'comment' => $comment,
'feed' => $feed,
'created' => false
]);
return;
}
$notification = [
'feed_id' => $feed->id,
'object_id' => $comment->id,
'src_user_id' => $comment->user_id,
'src_object_type' => 'comment',
'action' => 'comment_added',
'content' => $notificationContent,
'route' => $route,
];
$notification = Notification::create($notification);
$notification->subscribe([$feed->user_id]);
do_action('fluent_community/notification/comment/notifed_to_author', [
'user_ids' => [$feed->user_id],
'notification' => $notification,
'comment' => $comment,
'key' => 'notifed_to_author',
'feed' => $feed,
'created' => true
]);
}
protected function commentNotificationToFeedCommenters($comment, $feed)
{
if ($comment->parent_id) {
return $this->notifyForChildCommentReply($comment, $feed);
}
$userIds = Comment::whereNotIn('user_id', [$feed->user_id, $comment->user_id])
->where('post_id', $feed->id)
->whereNull('parent_id')
->distinct()
->pluck('user_id')
->toArray();
$mentionedUserIds = Arr::get($comment->meta, 'mentioned_user_ids', []);
if (!$userIds && !$mentionedUserIds) {
return;
}
$commenter = '' . esc_html($comment->user->display_name) . '';
$feedTitle = '' . $feed->getHumanExcerpt(60) . '';
$route = $feed->getJsRoute();
$space = $feed->space;
if ($feed->comments_count > 1) {
$totalUsers = $feed->comments
->where('user_id', '!=', $comment->user_id)
->pluck('user_id')
->unique()
->count();
if ($feed->space_id) {
if ($totalUsers > 1) {
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the people count, %3$s is the feed title and %4$s space title*/
__('%1$s and %2$s other people also commented on %3$s in %4$s', 'fluent-community'),
$commenter,
'' . ($totalUsers - 1) . '',
$feedTitle,
'' . $feed->space->title . ''
);
} else {
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the feed title and %3$s space title*/
__('%1$s also commented on %2$s in %3$s', 'fluent-community'),
$commenter,
$feedTitle,
'' . $feed->space->title . ''
);
}
} else {
if ($totalUsers > 1) {
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the like count & %3$s is the feed title */
__('%1$s and %2$s other people also commented on %3$s', 'fluent-community'),
$commenter,
'' . ($totalUsers - 1) . '',
$feedTitle,
);
} else {
$notificationContent = \sprintf(
/* translators: %1$s is the user name & %2$s is the feed title */
__('%1$s also commented on %2$s', 'fluent-community'),
$commenter,
$feedTitle,
);
}
}
} else {
if ($feed->space_id) {
$notificationContent = \sprintf(
/* translators: %1$s is the commenter name, %2$s is the feed title & %3$s is the space title */
__('%1$s also commented on %2$s in %3$s', 'fluent-community'),
$commenter,
$feedTitle,
'' . $space->title . ''
);
} else {
$notificationContent = \sprintf(
/* translators: %1$s is the commenter name & %2$s is the feed title */
__('%1$s also commented on %2$s', 'fluent-community'),
$commenter,
$feedTitle,
);
}
}
if ($mentionedUserIds) {
$mentionNotification = Notification::create([
'feed_id' => $feed->id,
'object_id' => $comment->id,
'src_user_id' => $comment->user_id,
'src_object_type' => 'comment',
'action' => 'mention_added',
'content' => \sprintf(
/* translators: %1$s is the commenter name & %2$s is the feed title */
__('%1$s mentioned you in a comment at %2$s', 'fluent-community'),
$commenter,
$feedTitle,
),
'route' => $route,
]);
$mentionNotification->subscribe($mentionedUserIds);
do_action('fluent_community/notification/comment/notifed_to_mentions', [
'user_ids' => $mentionedUserIds,
'notification' => $mentionNotification,
'key' => 'notifed_to_mentions',
'comment' => $comment,
'feed' => $feed
]);
}
if ($mentionedUserIds) {
$userIds = array_values(array_diff($userIds, $mentionedUserIds));
}
if (!$userIds) {
return;
}
$existIds = Notification::where('feed_id', $feed->id)
->where('action', 'comment_added')
->whereDoesntHave('subscribers', function ($query) use ($feed, $comment) {
$query->whereIn('user_id', [$feed->user_id, $comment->user_id]);
})
->pluck('id')
->toArray();
$existingSubscriberUserIds = [];
if (!empty($existIds)) {
Notification::whereIn('id', $existIds)->update([
'content' => $notificationContent,
'updated_at' => current_time('mysql'),
'src_user_id' => $comment->user_id,
'object_id' => $comment->id
]);
$existingSubscriberUserIds = NotificationSubscriber::whereIn('object_id', $existIds)
->pluck('user_id')
->unique()
->toArray();
NotificationSubscriber::whereIn('object_id', $existIds)
->whereIn('user_id', $existingSubscriberUserIds)
->update([
'is_read' => 0,
'updated_at' => current_time('mysql')
]);
}
if (!empty($existingSubscriberUserIds)) {
$userIds = array_values(array_diff($userIds, $existingSubscriberUserIds));
}
$notification = [
'feed_id' => $feed->id,
'object_id' => $comment->id,
'src_user_id' => $comment->user_id,
'src_object_type' => 'comment',
'action' => 'comment_added',
'content' => $notificationContent,
'route' => $route,
];
foreach ($userIds as $userId) {
$createdNotification = Notification::create($notification);
$createdNotification->subscribe([$userId]);
}
$sendingUserIds = array_merge($userIds, $existingSubscriberUserIds);
do_action('fluent_community/notification/comment/notifed_to_other_users', [
'user_ids' => $sendingUserIds,
'key' => 'notifed_to_other_users',
'notification' => $notification,
'comment' => $comment,
'feed' => $feed
]);
}
protected function notifyForChildCommentReply($comment, $feed)
{
// This is a parent comment, so we need to notify the parent comment author & all child comment authors
$childCommentUserIds = Comment::where(function ($q) use ($comment) {
$q->where('parent_id', $comment->parent_id)
->orWhere('id', $comment->parent_id);
})
->whereNotIn('user_id', [$comment->user_id, $feed->user_id])
->select(['user_id'])
->distinct('user_id')
->get()
->pluck('user_id')
->toArray();
if (!$childCommentUserIds) {
return false;
}
$commenter = '' . esc_html($comment->user->display_name) . '';
$existingNotification = Notification::where('object_id', $comment->parent_id)
->where('action', 'child_comment_added')
->first();
if ($existingNotification) {
$newContent = \sprintf(
/* translators: %1$s is the commenter name, %2$s is the comment user count & %3$s feed excerpt */
__('%1$s and %2$s other people replied to your comment at %3$s', 'fluent-community'),
$commenter,
'' . count($childCommentUserIds) . '',
'' . $feed->getHumanExcerpt(60) . ''
);
$route = $existingNotification->route;
$route['query'] = [
'comment_id' => $comment->id
];
$existingNotification->content = $newContent;
$existingNotification->updated_at = current_time('mysql');
$existingNotification->src_user_id = $comment->user_id;
$existingNotification->route = $route;
$existingNotification->save();
NotificationSubscriber::where('object_id', $existingNotification->id)
->whereIn('user_id', $childCommentUserIds)
->update([
'is_read' => 0,
'updated_at' => current_time('mysql')
]);
do_action('fluent_community/notification/comment/notifed_to_thread_commetenter', [
'user_ids' => $childCommentUserIds,
'notification' => $existingNotification,
'key' => 'notifed_to_thread_commetenter',
'comment' => $comment,
'feed' => $feed
]);
return $existingNotification;
}
$notificationContent = \sprintf(
/* translators: %1$s is the commenter name & %2$s is the feed excerpt */
__('%1$s replied to your comment at %2$s', 'fluent-community'),
$commenter,
'' . $feed->getHumanExcerpt(60) . ''
);
$route = $feed->getJsRoute();
$route['query'] = [
'comment_id' => $comment->id
];
$notification = [
'feed_id' => $feed->id,
'object_id' => $comment->parent_id,
'src_user_id' => $comment->user_id,
'src_object_type' => 'comment',
'action' => 'child_comment_added',
'content' => $notificationContent,
'route' => $route,
];
$notification = Notification::create($notification);
$notification->subscribe($childCommentUserIds);
do_action('fluent_community/notification/comment/notifed_to_thread_commetenter', [
'user_ids' => $childCommentUserIds,
'notification' => $notification,
'key' => 'notifed_to_thread_commetenter',
'comment' => $comment,
'feed' => $feed
]);
return $notification;
}
public function maybeHandleMentionedUserIds($feed)
{
$mentionedUserIds = Arr::get($feed->meta, 'mentioned_user_ids', []);
if (!$mentionedUserIds) {
return;
}
do_action('fluent_community/feed_mentioned_user_ids', $feed, $mentionedUserIds);
$feedTitle = $feed->getHumanExcerpt(60);
$user = $feed->user;
$notificationContent = \sprintf(
/* translators: %1$s is the user name, %2$s is the feed title */
__('%1$s mentioned you in a post: %2$s', 'fluent-community'),
'' . esc_html($user->display_name) . '',
'' . $feedTitle . ''
);
$route = $feed->getJsRoute();
$notification = [
'feed_id' => $feed->id,
'src_user_id' => $user->ID,
'src_object_type' => 'feed',
'action' => 'feed/mentioned',
'content' => $notificationContent,
'route' => $route,
];
$notification = Notification::create($notification);
$notification->subscribe($mentionedUserIds);
}
private function maybeHasEveryoneTag(Feed $feed)
{
if (!$feed->space_id) {
return;
}
if (!$feed->isEnabledForEveryoneTag()) {
return;
}
// we have everyone
// check if current user is a moderator or admin
$user = $feed->user;
$spaceRole = $user->getSpaceRole($feed->space);
if (!in_array($spaceRole, ['admin', 'moderator'])) {
return;
}
do_action('fluent_community/feed/scheduling_everyone_tag', $feed);
// Let's schedule an email hook to send email to everyone for this post
// We are scheduling this after 5 minutes of the post publish for performance
as_schedule_single_action(time() + 300, 'fluent_community/email_notify_users_everyone_tag', [
$feed->id,
0
], 'fluent-community');
}
private function willCreateFeedCreatedNotification($feed)
{
// validate if the user is a moderator
if (!$feed->user) {
return;
}
if ($feed->user->isCommunityModerator()) {
return true;
}
if ($feed->space) {
$role = $feed->user->getSpaceRole($feed->space);
return in_array($role, ['admin', 'moderator']);
}
return false;
}
}