PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 2.11.0
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v2.11.0
2.11.0 2.10.0 2.10.01 2.9.1 2.9.0 2.8.1 2.8.0 2.7.7 2.7.5 2.7.0 2.6.01 2.6.0 2.5.0 2.4.01 trunk 1.0.90 1.0.91 1.0.92 1.0.93 1.0.94 1.0.95 1.0.96 1.0.97 1.0.98 1.0.99 All 78 releases
← All changes | app/Hooks/Handlers/NotificationEventHandler.php +148 -65 2.4.012.11.0 View file →
@@ -6,8 +6,9 @@
6 6 use FluentCommunity\App\Models\Feed;
7 7 use FluentCommunity\App\Models\Notification;
8 8 use FluentCommunity\App\Models\NotificationSubscriber;
9 9 use FluentCommunity\App\Models\SpaceUserPivot;
10 +use FluentCommunity\App\Services\FeedsHelper;
10 11 use FluentCommunity\Framework\Support\Arr;
11 12
12 13 class NotificationEventHandler
13 14 {
@@ -15,8 +16,9 @@
15 16 {
16 17 add_action('fluent_community/comment_added', [$this, 'handleNewCommentEvent'], 10, 2);
17 18 add_action('fluent_community/space_feed/created', [$this, 'handleNewSpaceFeed'], 10);
18 19 add_action('fluent_community/feed/react_added', [$this, 'handleNewFeedReact'], 10, 2);
20 + add_action('fluent_community/comment/react_added', [$this, 'handleNewCommentReact'], 10, 3);
19 21
20 22 add_action('fluent_community/space/member/role_updated', [$this, 'handleSpaceMemberRoleUpdated'], 10, 2);
21 23
22 24 /*
@@ -58,9 +60,9 @@
58 60
59 61 $notificationContent = \sprintf(
60 62 /* translators: %1$s is the user name, %2$s is the feed title and %3$3s is the space title */
61 63 __('%1$s posted %2$s in %3$s', 'fluent-community'),
62 - '<b class="fcom_nudn">' . esc_html($user->display_name) . '</b>',
64 + '<b class="fcom_nudn">' . esc_html($user->getPublicDisplayName()) . '</b>',
63 65 '<span class="fcom_nft">' . $feedTitle . '</span>',
64 66 '<b class="fcom_nst">' . esc_html($space->title) . '</b>'
65 67 );
66 68
@@ -85,9 +87,9 @@
85 87 if ($react->user_id == $feed->user_id) {
86 88 return;
87 89 }
88 90
89 - $feedTitle = $feed->getHumanExcerpt(60);
91 + $feedTitle = $feed->getHumanExcerpt(40);
90 92 $user = $react->user;
91 93
92 94 if ($feed->reactions_count > 1) {
93 95 // check if we have existing notification for this feed and user
@@ -97,10 +99,10 @@
97 99
98 100 if ($existingNotification) {
99 101 $notificationContent = \sprintf(
100 102 /* translators: %1$s is the user name, %2$s is the like count & %3$s is the feed title */
101 - __('%1$s and %2$s other people reacted to %3$s', 'fluent-community'),
102 - '<b class="fcom_nudn">' . esc_html($user->display_name) . '</b>',
103 + __('%1$s and %2$s other people reacted to your post %3$s', 'fluent-community'),
104 + '<b class="fcom_nudn">' . esc_html($user->getPublicDisplayName()) . '</b>',
103 105 '<b class="fcom_nrc">' . ($feed->reactions_count - 1) . '</b>',
104 106 '<span class="fcom_nft">' . $feedTitle . '</span>'
105 107 );
106 108
@@ -118,10 +120,10 @@
118 120 }
119 121
120 122 $notificationContent = \sprintf(
121 123 /* translators: %1$s is the user name, %2$s is the feed title */
122 - __('%1$s reacted to %2$s', 'fluent-community'),
123 - '<b class="fcom_nudn">' . esc_html($user->display_name) . '</b>',
124 + __('%1$s reacted to your post %2$s', 'fluent-community'),
125 + '<b class="fcom_nudn">' . esc_html($user->getPublicDisplayName()) . '</b>',
124 126 '<span class="fcom_nft">' . $feedTitle . '</span>'
125 127 );
126 128
127 129 $route = $feed->getJsRoute();
@@ -139,8 +141,62 @@
139 141
140 142 $notification->subscribe([$feed->user_id]);
141 143 }
142 144
145 + public function handleNewCommentReact($react, $comment, $feed)
146 + {
147 + if ($react->user_id == $comment->user_id) {
148 + return;
149 + }
150 +
151 + $commentExcerpt = $comment->getHumanExcerpt(40);
152 + $user = $react->user;
153 +
154 + if ($comment->reactions_count > 1) {
155 + $notificationContent = \sprintf(
156 + /* translators: %1$s is the user name, %2$s is the like count & %3$s is the comment excerpt */
157 + __('%1$s and %2$s other people reacted to your comment %3$s', 'fluent-community'),
158 + '<b class="fcom_nudn">' . esc_html($user->getPublicDisplayName()) . '</b>',
159 + '<b class="fcom_nrc">' . ($comment->reactions_count - 1) . '</b>',
160 + '<span class="fcom_nft">' . $commentExcerpt . '</span>'
161 + );
162 + } else {
163 + $notificationContent = \sprintf(
164 + /* translators: %1$s is the user name, %2$s is the comment excerpt */
165 + __('%1$s reacted to your comment %2$s', 'fluent-community'),
166 + '<b class="fcom_nudn">' . esc_html($user->getPublicDisplayName()) . '</b>',
167 + '<span class="fcom_nft">' . $commentExcerpt . '</span>'
168 + );
169 + }
170 +
171 + $existingNotification = Notification::where('feed_id', $feed->id)
172 + ->where('object_id', $comment->id)
173 + ->where('action', 'comment/react_added')
174 + ->first();
175 +
176 + if ($existingNotification) {
177 + $existingNotification->content = $notificationContent;
178 + $existingNotification->src_user_id = $user->ID;
179 + $existingNotification->save();
180 + NotificationSubscriber::where('object_id', $existingNotification->id)
181 + ->where('user_id', $comment->user_id)
182 + ->update(['is_read' => 0, 'updated_at' => current_time('mysql')]);
183 + return;
184 + }
185 +
186 + $notification = Notification::create([
187 + 'feed_id' => $feed->id,
188 + 'object_id' => $comment->id,
189 + 'src_user_id' => $user->ID,
190 + 'src_object_type' => 'comment',
191 + 'action' => 'comment/react_added',
192 + 'content' => $notificationContent,
193 + 'route' => $feed->getJsRoute(),
194 + ]);
195 +
196 + $notification->subscribe([$comment->user_id]);
197 + }
198 +
143 199 public function handleSpaceMemberRoleUpdated($space, $pivot)
144 200 {
145 201 $user = $pivot->user;
146 202
@@ -146,10 +202,10 @@
146 202
147 203 $notificationContent = \sprintf(
148 204 /* translators: %1$s is the role name, %2$s is the space title */
149 205 __('You have been added as %1$s in %2$s', 'fluent-community'),
150 - '<b>' . $pivot->role . '</b>',
151 - '<b>' . $space->title . '</b>'
206 + '<b>' . esc_html($pivot->role) . '</b>',
207 + '<b>' . esc_html($space->title) . '</b>'
152 208 );
153 209
154 210 $route = [
155 211 'name' => 'space_feeds',
@@ -171,18 +227,21 @@
171 227 }
172 228
173 229 protected function commentNotificationToAuthorFeed(Comment $comment, Feed $feed)
174 230 {
175 - if ($comment->user_id == $feed->user_id) {
231 + $authorId = FeedsHelper::getNotificationAuthorId($feed);
232 +
233 + if ($comment->user_id == $authorId) {
176 234 return;
177 235 }
178 236
179 - $mentionedUserIds = Arr::get($feed->meta, 'mentioned_user_ids', []);
180 - if (in_array($feed->user_id, $mentionedUserIds)) {
237 + // Skip a mentioned author here; notifyMentionedUsers() notifies them instead.
238 + $mentionedUserIds = Arr::get($comment->meta, 'mentioned_user_ids', []);
239 + if (in_array($authorId, $mentionedUserIds)) {
181 240 return;
182 241 }
183 242
184 - $commenter = '<b class="fcom_nudn">' . esc_html($comment->user->display_name) . '</b>';
243 + $commenter = '<b class="fcom_nudn">' . esc_html($comment->user->getPublicDisplayName()) . '</b>';
185 244 $feedTitle = $feed->getHumanExcerpt(60);
186 245
187 246 $exist = null;
188 247 if ($feed->comments_count > 1) {
@@ -188,15 +247,17 @@
188 247 if ($feed->comments_count > 1) {
189 248 // check if we have existing notification for this feed and user
190 249 $exist = Notification::where('feed_id', $feed->id)
191 250 ->where('action', 'comment_added')
251 + ->whereHas('subscribers', function ($q) use ($authorId) {
252 + $q->where('user_id', $authorId);
253 + })
192 254 ->first();
193 255
194 - $totalUsers = $feed->comments
195 - ->where('user_id', '!=', $feed->user_id)
196 - ->pluck('user_id')
197 - ->unique()
198 - ->count();
256 + $totalUsers = Comment::where('post_id', $feed->id)
257 + ->where('user_id', '!=', $authorId)
258 + ->distinct()
259 + ->count('user_id');
199 260
200 261 if ($feed->space_id) {
201 262 if ($totalUsers > 1) {
202 263 $notificationContent = \sprintf(
@@ -204,9 +265,9 @@
204 265 __('%1$s and %2$s other people commented on your post %3$s in %4$s', 'fluent-community'),
205 266 $commenter,
206 267 '<b class="fcom_nrc">' . ($totalUsers - 1) . '</b>',
207 268 '<span class="fcom_nft">' . $feedTitle . '</span>',
208 - '<b class="fcom_nst">' . $feed->space->title . '</b>'
269 + '<b class="fcom_nst">' . esc_html($feed->space->title) . '</b>'
209 270 );
210 271 } else {
211 272 $notificationContent = \sprintf(
212 273 /* translators: %1$s is the user name, %2$s is the feed title and %3$s space title*/
@@ -212,9 +273,9 @@
212 273 /* translators: %1$s is the user name, %2$s is the feed title and %3$s space title*/
213 274 __('%1$s commented on your post: %2$s in %3$s', 'fluent-community'),
214 275 $commenter,
215 276 '<span class="fcom_nft">' . $feedTitle . '</span>',
216 - '<b class="fcom_nst">' . $feed->space->title . '</b>'
277 + '<b class="fcom_nst">' . esc_html($feed->space->title) . '</b>'
217 278 );
218 279 }
219 280 } else {
220 281
@@ -241,9 +302,9 @@
241 302 /* translators: %1$s is the commenter name, %2$s is the feed title & %3$s is the space title */
242 303 __('%1$s commented on your post: %2$s in %3$s', 'fluent-community'),
243 304 $commenter,
244 305 '<span class="fcom_nft">' . $feedTitle . '</span>',
245 - '<b class="fcom_nst">' . $feed->space->title . '</b>'
306 + '<b class="fcom_nst">' . esc_html($feed->space->title) . '</b>'
246 307 );
247 308 } else {
248 309 $notificationContent = \sprintf(
249 310 /* translators: %1$s is the commenter name & %2$s is the feed title */
@@ -263,9 +324,9 @@
263 324 $exist->object_id = $comment->id;
264 325 $exist->save();
265 326
266 327 NotificationSubscriber::where('object_id', $exist->id)
267 - ->where('user_id', $feed->user_id)
328 + ->where('user_id', $authorId)
268 329 ->update([
269 330 'is_read' => 0,
270 331 'updated_at' => current_time('mysql')
271 332 ]);
@@ -270,9 +331,9 @@
270 331 'updated_at' => current_time('mysql')
271 332 ]);
272 333
273 334 do_action('fluent_community/notification/comment/notifed_to_author', [
274 - 'user_ids' => [$feed->user_id],
335 + 'user_ids' => [$authorId],
275 336 'notification' => $exist,
276 337 'key' => 'notifed_to_author',
277 338 'comment' => $comment,
278 339 'feed' => $feed,
@@ -293,12 +354,12 @@
293 354 ];
294 355
295 356 $notification = Notification::create($notification);
296 357
297 - $notification->subscribe([$feed->user_id]);
358 + $notification->subscribe([$authorId]);
298 359
299 360 do_action('fluent_community/notification/comment/notifed_to_author', [
300 - 'user_ids' => [$feed->user_id],
361 + 'user_ids' => [$authorId],
301 362 'notification' => $notification,
302 363 'comment' => $comment,
303 364 'key' => 'notifed_to_author',
304 365 'feed' => $feed,
@@ -307,10 +368,17 @@
307 368 }
308 369
309 370 protected function commentNotificationToFeedCommenters($comment, $feed)
310 371 {
372 + $mentionedUserIds = Arr::get($comment->meta, 'mentioned_user_ids', []);
373 +
374 + // Notify mentioned users for both top-level comments and replies.
375 + if ($mentionedUserIds) {
376 + $this->notifyMentionedUsers($comment, $feed, $mentionedUserIds);
377 + }
378 +
311 379 if ($comment->parent_id) {
312 - return $this->notifyForChildCommentReply($comment, $feed);
380 + return $this->notifyForChildCommentReply($comment, $feed, $mentionedUserIds);
313 381 }
314 382
315 383 $userIds = Comment::whereNotIn('user_id', [$feed->user_id, $comment->user_id])
316 384 ->where('post_id', $feed->id)
@@ -318,15 +386,13 @@
318 386 ->distinct()
319 387 ->pluck('user_id')
320 388 ->toArray();
321 389
322 - $mentionedUserIds = Arr::get($comment->meta, 'mentioned_user_ids', []);
323 -
324 390 if (!$userIds && !$mentionedUserIds) {
325 391 return;
326 392 }
327 393
328 - $commenter = '<b class="fcom_nudn">' . esc_html($comment->user->display_name) . '</b>';
394 + $commenter = '<b class="fcom_nudn">' . esc_html($comment->user->getPublicDisplayName()) . '</b>';
329 395 $feedTitle = '<span class="fcom_nft">' . $feed->getHumanExcerpt(60) . '</span>';
330 396
331 397 $route = $feed->getJsRoute();
332 398 $space = $feed->space;
@@ -331,13 +397,12 @@
331 397 $route = $feed->getJsRoute();
332 398 $space = $feed->space;
333 399
334 400 if ($feed->comments_count > 1) {
335 - $totalUsers = $feed->comments
401 + $totalUsers = Comment::where('post_id', $feed->id)
336 402 ->where('user_id', '!=', $comment->user_id)
337 - ->pluck('user_id')
338 - ->unique()
339 - ->count();
403 + ->distinct()
404 + ->count('user_id');
340 405
341 406 if ($feed->space_id) {
342 407 if ($totalUsers > 1) {
343 408 $notificationContent = \sprintf(
@@ -345,9 +410,9 @@
345 410 __('%1$s and %2$s other people also commented on %3$s in %4$s', 'fluent-community'),
346 411 $commenter,
347 412 '<b class="fcom_nrc">' . ($totalUsers - 1) . '</b>',
348 413 $feedTitle,
349 - '<b class="fcom_nst">' . $feed->space->title . '</b>'
414 + '<b class="fcom_nst">' . esc_html($feed->space->title) . '</b>'
350 415 );
351 416 } else {
352 417 $notificationContent = \sprintf(
353 418 /* translators: %1$s is the user name, %2$s is the feed title and %3$s space title*/
@@ -353,9 +418,9 @@
353 418 /* translators: %1$s is the user name, %2$s is the feed title and %3$s space title*/
354 419 __('%1$s also commented on %2$s in %3$s', 'fluent-community'),
355 420 $commenter,
356 421 $feedTitle,
357 - '<b class="fcom_nst">' . $feed->space->title . '</b>'
422 + '<b class="fcom_nst">' . esc_html($feed->space->title) . '</b>'
358 423 );
359 424 }
360 425 } else {
361 426 if ($totalUsers > 1) {
@@ -381,9 +446,9 @@
381 446 /* translators: %1$s is the commenter name, %2$s is the feed title & %3$s is the space title */
382 447 __('%1$s also commented on %2$s in %3$s', 'fluent-community'),
383 448 $commenter,
384 449 $feedTitle,
385 - '<b class="fcom_nst">' . $space->title . '</b>'
450 + '<b class="fcom_nst">' . esc_html($space->title) . '</b>'
386 451 );
387 452 } else {
388 453 $notificationContent = \sprintf(
389 454 /* translators: %1$s is the commenter name & %2$s is the feed title */
@@ -394,35 +459,8 @@
394 459 }
395 460 }
396 461
397 462 if ($mentionedUserIds) {
398 - $mentionNotification = Notification::create([
399 - 'feed_id' => $feed->id,
400 - 'object_id' => $comment->id,
401 - 'src_user_id' => $comment->user_id,
402 - 'src_object_type' => 'comment',
403 - 'action' => 'mention_added',
404 - 'content' => \sprintf(
405 - /* translators: %1$s is the commenter name & %2$s is the feed title */
406 - __('%1$s mentioned you in a comment at %2$s', 'fluent-community'),
407 - $commenter,
408 - $feedTitle,
409 - ),
410 - 'route' => $route,
411 - ]);
412 -
413 - $mentionNotification->subscribe($mentionedUserIds);
414 -
415 - do_action('fluent_community/notification/comment/notifed_to_mentions', [
416 - 'user_ids' => $mentionedUserIds,
417 - 'notification' => $mentionNotification,
418 - 'key' => 'notifed_to_mentions',
419 - 'comment' => $comment,
420 - 'feed' => $feed
421 - ]);
422 - }
423 -
424 - if ($mentionedUserIds) {
425 463 $userIds = array_values(array_diff($userIds, $mentionedUserIds));
426 464 }
427 465
428 466 if (!$userIds) {
@@ -488,10 +526,47 @@
488 526 'feed' => $feed
489 527 ]);
490 528 }
491 529
492 - protected function notifyForChildCommentReply($comment, $feed)
530 + protected function notifyMentionedUsers($comment, $feed, $mentionedUserIds)
493 531 {
532 + if (!$mentionedUserIds) {
533 + return;
534 + }
535 +
536 + $commenter = '<b class="fcom_nudn">' . esc_html($comment->user->getPublicDisplayName()) . '</b>';
537 + $feedTitle = '<span class="fcom_nft">' . $feed->getHumanExcerpt(60) . '</span>';
538 +
539 + $mentionNotification = Notification::create([
540 + 'feed_id' => $feed->id,
541 + 'object_id' => $comment->id,
542 + 'src_user_id' => $comment->user_id,
543 + 'src_object_type' => 'comment',
544 + 'action' => 'mention_added',
545 + 'content' => \sprintf(
546 + /* translators: %1$s is the commenter name & %2$s is the feed title */
547 + __('%1$s mentioned you in a comment at %2$s', 'fluent-community'),
548 + $commenter,
549 + $feedTitle,
550 + ),
551 + 'route' => $feed->getJsRoute(),
552 + ]);
553 +
554 + $mentionNotification->subscribe($mentionedUserIds);
555 +
556 + do_action('fluent_community/notification/comment/notifed_to_mentions', [
557 + 'user_ids' => $mentionedUserIds,
558 + 'notification' => $mentionNotification,
559 + 'key' => 'notifed_to_mentions',
560 + 'comment' => $comment,
561 + 'feed' => $feed
562 + ]);
563 +
564 + return $mentionNotification;
565 + }
566 +
567 + protected function notifyForChildCommentReply($comment, $feed, $mentionedUserIds = [])
568 + {
494 569 // This is a parent comment, so we need to notify the parent comment author & all child comment authors
495 570 $childCommentUserIds = Comment::where(function ($q) use ($comment) {
496 571 $q->where('parent_id', $comment->parent_id)
497 572 ->orWhere('id', $comment->parent_id);
@@ -502,16 +577,24 @@
502 577 ->get()
503 578 ->pluck('user_id')
504 579 ->toArray();
505 580
581 + // Mentioned users get a mention notification instead, so skip them here.
582 + if ($mentionedUserIds) {
583 + $childCommentUserIds = array_values(array_diff($childCommentUserIds, $mentionedUserIds));
584 + }
585 +
506 586 if (!$childCommentUserIds) {
507 587 return false;
508 588 }
509 589
510 - $commenter = '<b class="fcom_nudn">' . esc_html($comment->user->display_name) . '</b>';
590 + $commenter = '<b class="fcom_nudn">' . esc_html($comment->user->getPublicDisplayName()) . '</b>';
511 591
512 592 $existingNotification = Notification::where('object_id', $comment->parent_id)
513 593 ->where('action', 'child_comment_added')
594 + ->whereHas('subscribers', function ($q) use ($childCommentUserIds) {
595 + $q->whereIn('user_id', $childCommentUserIds);
596 + })
514 597 ->first();
515 598
516 599 if ($existingNotification) {
517 600 $newContent = \sprintf(
@@ -602,9 +685,9 @@
602 685
603 686 $notificationContent = \sprintf(
604 687 /* translators: %1$s is the user name, %2$s is the feed title */
605 688 __('%1$s mentioned you in a post: %2$s', 'fluent-community'),
606 - '<b class="fcom_nudn">' . esc_html($user->display_name) . '</b>',
689 + '<b class="fcom_nudn">' . esc_html($user->getPublicDisplayName()) . '</b>',
607 690 '<b class="fcom_nft">' . $feedTitle . '</b>'
608 691 );
609 692
610 693 $route = $feed->getJsRoute();