PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / 1.0.91
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses v1.0.91
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 1.1.0 All 77 releases
fluent-community / app / Hooks / Handlers / NotificationEventHandler.php

NotificationEventHandler.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses 1.0.91, at app/Hooks/Handlers/NotificationEventHandler.php

621 lines 21.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\App\Hooks\Handlers;
4
5 use FluentCommunity\App\Functions\Utility;
6 use FluentCommunity\App\Models\Comment;
7 use FluentCommunity\App\Models\Feed;
8 use FluentCommunity\App\Models\Notification;
9 use FluentCommunity\App\Models\NotificationSubscriber;
10 use FluentCommunity\App\Models\SpaceUserPivot;
11 use FluentCommunity\App\Services\Helper;
12 use FluentCommunity\Framework\Support\Arr;
13
14 class NotificationEventHandler
15 {
16 public function register()
17 {
18 add_action('fluent_community/comment_added', [$this, 'handleNewCommentEvent'], 10, 3);
19 add_action('fluent_community/space_feed/created', [$this, 'handleNewSpaceFeed'], 10);
20 add_action('fluent_community/feed/react_added', [$this, 'handleNewFeedReact'], 10, 2);
21
22 add_action('fluent_community/space/member/role_updated', [$this, 'handleSpaceMemberRoleUpdated'], 10, 2);
23
24 /*
25 * Mentions handler
26 */
27 add_action('fluent_community/feed_mentioned', [$this, 'handleFeedMentions'], 10, 2);
28
29 }
30
31 public function handleNewCommentEvent($comment, $feed, $mentionedUsers = null)
32 {
33 $this->commentNotificationToAuthorFeed($comment, $feed, $mentionedUsers);
34
35 // now notify all users who commented on this feed
36 $this->commentNotificationToFeedCommenters($comment, $feed, $mentionedUsers);
37 }
38
39 public function handleNewSpaceFeed($feed)
40 {
41 if (!$this->willCreateFeedCreatedNotification($feed)) {
42 return;
43 }
44
45 $user = $feed->user;
46 $space = $feed->space;
47
48 $this->maybeHasEveryoneTag($feed);
49
50 $userIds = SpaceUserPivot::where('space_id', $space->id)
51 ->where('user_id', '!=', $user->ID)
52 ->where('status', 'active')
53 ->pluck('user_id')
54 ->toArray();
55
56 if (!$userIds) {
57 return;
58 }
59
60 $feedTitle = $feed->getHumanExcerpt(60);
61
62 $notificationContent = \sprintf(
63 /* translators: %1$s is the user name, %2$s is the feed title and %3$3s is the space title */
64 __('%1$s posted %2$s in %3$s', 'fluent-community'),
65 '<b class="fcom_nudn">' . $user->display_name . '</b>',
66 '<span class="fcom_nft">' . $feedTitle . '</span>',
67 '<b class="fcom_nst">' . $space->title . '</b>'
68 );
69
70 $route = [
71 'name' => 'space_feed',
72 'params' => [
73 'space' => $space->slug,
74 'feed_slug' => $feed->slug
75 ]
76 ];
77
78 $notification = [
79 'feed_id' => $feed->id,
80 'src_user_id' => $user->ID,
81 'src_object_type' => 'feed',
82 'action' => 'space_feed/created',
83 'content' => $notificationContent,
84 'route' => $route,
85 ];
86
87 $notification = Notification::create($notification);
88
89 $notification->subscribe($userIds);
90 }
91
92 public function handleNewFeedReact($react, $feed)
93 {
94 if ($react->user_id == $feed->user_id) {
95 return;
96 }
97
98 $feedTitle = $feed->getHumanExcerpt(60);
99 $user = $react->user;
100
101 if ($feed->reactions_count > 1) {
102 // check if we have existing notification for this feed and user
103 $existingNotification = Notification::where('feed_id', $feed->id)
104 ->where('action', 'feed/react_added')
105 ->first();
106
107 if ($existingNotification) {
108 $notificationContent = \sprintf(
109 /* translators: %1$s is the user name, %2$s is the like count & %3$s is the feed title */
110 __('%1$s and %2$s other people loved %3$s', 'fluent-community'),
111 '<b class="fcom_nudn">' . $user->display_name . '</b>',
112 '<b class="fcom_nrc">' . ($feed->reactions_count - 1) . '</b>',
113 '<span class="fcom_nft">' . $feedTitle . '</span>'
114 );
115
116 $existingNotification->content = $notificationContent;
117 $existingNotification->src_user_id = $user->ID;
118 $existingNotification->save();
119 NotificationSubscriber::where('object_id', $existingNotification->id)
120 ->where('user_id', $feed->user_id)
121 ->update([
122 'is_read' => 0,
123 'updated_at' => current_time('mysql')
124 ]);
125 return;
126 }
127 }
128
129 $notificationContent = \sprintf(
130 /* translators: %1$s is the user name, %2$s is the feed title */
131 __('%1$s loved %2$s', 'fluent-community'),
132 '<b class="fcom_nudn">' . $user->display_name . '</b>',
133 '<span class="fcom_nft">' . $feedTitle . '</span>'
134 );
135
136 if ($feed->space_id) {
137 $space = $feed->space;
138 $route = [
139 'name' => 'space_feed',
140 'params' => [
141 'space' => $space->slug,
142 'feed_slug' => $feed->slug
143 ]
144 ];
145 } else {
146 $route = [
147 'name' => 'single_feed',
148 'params' => [
149 'feed_slug' => $feed->slug
150 ]
151 ];
152 }
153
154 $notification = [
155 'feed_id' => $feed->id,
156 'src_user_id' => $user->ID,
157 'src_object_type' => 'feed',
158 'action' => 'feed/react_added',
159 'content' => $notificationContent,
160 'route' => $route,
161 ];
162
163 $notification = Notification::create($notification);
164
165 $notification->subscribe([$feed->user_id]);
166 }
167
168 public function handleSpaceMemberRoleUpdated($space, $pivot)
169 {
170 $user = $pivot->user;
171
172 $notificationContent = \sprintf(
173 /* translators: %1$s is the role name, %2$s is the space title */
174 __('You have been added as %1$s in %2$s', 'fluent-community'),
175 '<b>' . $pivot->role . '</b>',
176 '<b>' . $space->title . '</b>'
177 );
178
179 $route = [
180 'name' => 'space_feeds',
181 'params' => [
182 'space' => $space->slug
183 ]
184 ];
185
186 $notification = [
187 'object_id' => $space->id,
188 'src_user_id' => $user->ID,
189 'src_object_type' => 'space',
190 'action' => 'space/member/role_updated',
191 'content' => $notificationContent,
192 'route' => $route,
193 ];
194 $notification = Notification::create($notification);
195 $notification->subscribe([$pivot->user_id]);
196 }
197
198 protected function commentNotificationToAuthorFeed(Comment $comment, Feed $feed, $mentionUsers = null)
199 {
200 if ($comment->user_id == $feed->user_id) {
201 return;
202 }
203
204 if ($mentionUsers) {
205 $mentionedUserIds = $mentionUsers->pluck('ID')->toArray();
206 if (in_array($feed->user_id, $mentionedUserIds)) {
207 return;
208 }
209 }
210
211 $commenter = '<b class="fcom_nudn">' . $comment->user->display_name . '</b>';
212 $feedTitle = $feed->getHumanExcerpt(60);
213
214 $exist = null;
215 if ($feed->comments_count > 1) {
216 // check if we have existing notification for this feed and user
217 $exist = Notification::where('feed_id', $feed->id)
218 ->where('action', 'comment_added')
219 ->first();
220
221 $totalUsers = $feed->comments->pluck('user_id')->unique()->count();
222
223 if ($totalUsers > 1) {
224 $commenter .= ' and ' . ($totalUsers - 1) . ' other people';
225 }
226
227 if ($feed->space_id) {
228 $notificationContent = \sprintf(
229 /* translators: %1$s is the user name, %2$s is the people count, %3$s is the feed title and %4$s space title*/
230 __('%1$s and %2$s other people commented on your post %3$s in %4$s', 'fluent-community'),
231 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
232 '<b class="fcom_nrc">' . ($totalUsers - 1) . '</b>',
233 '<span class="fcom_nft">' . $feedTitle . '</span>',
234 '<b class="fcom_nst">' . $feed->space->title . '</b>'
235 );
236 } else {
237 $notificationContent = \sprintf(
238 /* translators: %1$s is the user name, %2$s is the like count & %3$s is the feed title */
239 __('%1$s and %2$s other people commented on your post %3$s', 'fluent-community'),
240 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
241 '<b class="fcom_nrc">' . ($totalUsers - 1) . '</b>',
242 '<span class="fcom_nft">' . $feedTitle . '</span>'
243 );
244 }
245 } else {
246 if ($feed->space_id) {
247 $notificationContent = \sprintf(
248 /* translators: %1$s is the commenter name, %2$s is the feed title & %3$s is the space title */
249 __('%1$s commented on your post: %2$s in %3$s', 'fluent-community'),
250 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
251 '<span class="fcom_nft">' . $feedTitle . '</span>',
252 '<b class="fcom_nst">' . $feed->space->title . '</b>'
253 );
254 } else {
255 $notificationContent = \sprintf(
256 /* translators: %1$s is the commenter name & %2$s is the feed title */
257 __('%1$s commented on your post: %2$s', 'fluent-community'),
258 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
259 '<span class="fcom_nft">' . $feedTitle . '</span>'
260 );
261 }
262 }
263
264 if ($feed->space_id) {
265 $route = [
266 'name' => 'space_feed',
267 'params' => [
268 'space' => $feed->space->slug,
269 'feed_slug' => $feed->slug
270 ]
271 ];
272 } else {
273 $route = [
274 'name' => 'single_feed',
275 'params' => [
276 'feed_slug' => $feed->slug
277 ]
278 ];
279 }
280
281 if ($exist) {
282 $exist->content = $notificationContent;
283 $exist->updated_at = current_time('mysql');
284 $exist->src_user_id = $comment->user->ID;
285 $exist->object_id = $comment->id;
286 $exist->save();
287
288 NotificationSubscriber::where('object_id', $exist->id)
289 ->where('user_id', $feed->user_id)
290 ->update([
291 'is_read' => 0,
292 'updated_at' => current_time('mysql')
293 ]);
294 return;
295 }
296
297 $notification = [
298 'feed_id' => $feed->id,
299 'object_id' => $comment->id,
300 'src_user_id' => $comment->user_id,
301 'src_object_type' => 'comment',
302 'action' => 'comment_added',
303 'content' => $notificationContent,
304 'route' => $route,
305 ];
306
307 $notification = Notification::create($notification);
308
309 $notification->subscribe([$feed->user_id]);
310 }
311
312 protected function commentNotificationToFeedCommenters($comment, $feed, $mentionedUsers = null)
313 {
314 if ($comment->parent_id) {
315 return $this->notifyForChildCommentReply($comment, $feed);
316 }
317
318 $comments = Comment::whereNotIn('user_id', [$feed->user_id, $comment->user_id])
319 ->select(['user_id'])
320 ->where('post_id', $feed->id)
321 ->whereNull('parent_id')
322 ->distinct('user_id')
323 ->get();
324
325 $userIds = $comments->pluck('user_id')->toArray();
326
327 $mentionedUserIds = [];
328
329 if ($mentionedUsers) {
330 $mentionedUserIds = $mentionedUsers->pluck('ID')->toArray();
331 }
332
333 if (!$userIds && !$mentionedUserIds) {
334 return;
335 }
336
337 $feedTitle = $feed->getHumanExcerpt(60);
338
339 $route = [
340 'name' => 'single_feed',
341 'params' => [
342 'feed_slug' => $feed->slug
343 ],
344 'query' => [
345 'comment_id' => $comment->id
346 ]
347 ];
348
349 if ($feed->space_id) {
350 $space = $feed->space;
351 $notificationContent = \sprintf(
352 /* translators: %1$s is the commenter name, %2$s is the feed title & %3$s is the space title */
353 __('%1$s also commented on %2$s in %3$s', 'fluent-community'),
354 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
355 '<span class="fcom_nft">' . $feedTitle . '</span>',
356 '<b class="fcom_nst">' . $space->title . '</b>'
357 );
358
359 $route = [
360 'name' => 'space_feed',
361 'params' => [
362 'space' => $space->slug,
363 'feed_slug' => $feed->slug
364 ],
365 'query' => [
366 'comment_id' => $comment->id
367 ]
368 ];
369 } else {
370 $notificationContent = \sprintf(
371 /* translators: %1$s is the commenter name & %2$s is the feed title */
372 __('%1$s also commented on %2$s', 'fluent-community'),
373 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
374 '<span class="fcom_nft">' . $feedTitle . '</span>'
375 );
376 }
377
378 if ($mentionedUserIds) {
379 $mentionNotification = Notification::create([
380 'feed_id' => $feed->id,
381 'object_id' => $comment->id,
382 'src_user_id' => $comment->user_id,
383 'src_object_type' => 'comment',
384 'action' => 'mention_added',
385 'content' => \sprintf(
386 // translators: %1$s is the commenter name & %2$s is the feed title
387 __('%1$s mentioned you in a comment at %2$s', 'fluent-community'),
388 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
389 '<b class="fcom_nft">' . $feedTitle . '</b>'
390 ),
391 'route' => $route,
392 ]);
393
394 $mentionNotification->subscribe($mentionedUserIds);
395 }
396
397 if ($mentionedUserIds) {
398 $userIds = array_values(array_diff($userIds, $mentionedUserIds));
399 }
400
401 if (!$userIds) {
402 return;
403 }
404
405 $notification = [
406 'feed_id' => $feed->id,
407 'object_id' => $comment->id,
408 'src_user_id' => $comment->user_id,
409 'src_object_type' => 'comment',
410 'action' => 'comment_added',
411 'content' => $notificationContent,
412 'route' => $route,
413 ];
414 $notification = Notification::create($notification);
415 $notification->subscribe($userIds);
416 }
417
418 protected function notifyForChildCommentReply($comment, $feed)
419 {
420 // This is a parent comment, so we need to notify the parent comment author & all child comment authors
421 $childCommentUserIds = Comment::where('parent_id', $comment->parent_id)
422 ->whereNotIn('user_id', [$comment->user_id, $feed->user_id])
423 ->select(['user_id'])
424 ->distinct('user_id')
425 ->get()
426 ->pluck('user_id')
427 ->toArray();
428
429 if (!$childCommentUserIds) {
430 return false;
431 }
432
433 $existingNotification = Notification::where('object_id', $comment->parent_id)
434 ->where('action', 'child_comment_added')
435 ->first();
436
437 if ($existingNotification) {
438 $newContent = \sprintf(
439 /* translators: %1$s is the commenter name, %2$s is the comment user count & %3$s feed excerpt */
440 __('%1$s and %2$s other people replied your comment at %3$s', 'fluent-community'),
441 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
442 '<b class="fcom_nrc">' . count($childCommentUserIds) . '</b>',
443 '<b class="fcom_nft">' . $feed->getHumanExcerpt(60) . '</b>'
444 );
445
446 $route = $existingNotification->route;
447 $route['query'] = [
448 'comment_id' => $comment->id
449 ];
450
451 $existingNotification->content = $newContent;
452 $existingNotification->updated_at = current_time('mysql');
453 $existingNotification->src_user_id = $comment->user_id;
454 $existingNotification->route = $route;
455 $existingNotification->save();
456
457 NotificationSubscriber::where('object_id', $existingNotification->id)
458 ->whereIn('user_id', $childCommentUserIds)
459 ->update([
460 'is_read' => 0,
461 'updated_at' => current_time('mysql')
462 ]);
463
464 return $existingNotification;
465 }
466
467 $notificationContent = \sprintf(
468 /* translators: %1$s is the commenter name & %2$s is the feed excerpt */
469 __('%1$s replied your comment at %2$s', 'fluent-community'),
470 '<b class="fcom_nudn">' . $comment->user->display_name . '</b>',
471 '<b class="fcom_nft">' . $feed->getHumanExcerpt(60) . '</b>'
472 );
473
474 $route = [
475 'name' => 'single_feed',
476 'params' => [
477 'feed_slug' => $feed->slug
478 ],
479 'query' => [
480 'comment_id' => $comment->id
481 ]
482 ];
483
484 if ($feed->space_id) {
485 $space = $feed->space;
486
487 $route = [
488 'name' => 'space_feed',
489 'params' => [
490 'space' => $space->slug,
491 'feed_slug' => $feed->slug
492 ],
493 'query' => [
494 'comment_id' => $comment->id
495 ]
496 ];
497 }
498
499 $notification = [
500 'feed_id' => $feed->id,
501 'object_id' => $comment->parent_id,
502 'src_user_id' => $comment->user_id,
503 'src_object_type' => 'comment',
504 'action' => 'child_comment_added',
505 'content' => $notificationContent,
506 'route' => $route,
507 ];
508
509 $notification = Notification::create($notification);
510 $notification->subscribe($childCommentUserIds);
511 return $notification;
512 }
513
514 public function handleFeedMentions($feed, $mentionedUsers)
515 {
516 $feedTitle = $feed->getHumanExcerpt(60);
517 $user = $feed->user;
518
519 $notificationContent = \sprintf(
520 /* translators: %1$s is the user name, %2$s is the feed title */
521 __('%1$s mentioned you in a post: %2$s', 'fluent-community'),
522 '<b class="fcom_nudn">' . sanitize_text_field($user->display_name) . '</b>',
523 '<b class="fcom_nft">' . $feedTitle . '</b>'
524 );
525
526 if ($feed->space_id) {
527 $space = $feed->space;
528 $route = [
529 'name' => 'space_feed',
530 'params' => [
531 'space' => $space->slug,
532 'feed_slug' => $feed->slug
533 ]
534 ];
535 } else {
536 $route = [
537 'name' => 'single_feed',
538 'params' => [
539 'feed_slug' => $feed->slug
540 ]
541 ];
542 }
543
544 $notification = [
545 'feed_id' => $feed->id,
546 'src_user_id' => $user->ID,
547 'src_object_type' => 'feed',
548 'action' => 'feed/mentioned',
549 'content' => $notificationContent,
550 'route' => $route,
551 ];
552
553 $notification = Notification::create($notification);
554
555 $userIds = $mentionedUsers->pluck('ID')->toArray();
556
557 $notification->subscribe($userIds);
558 }
559
560 private function maybeHasEveryoneTag(Feed $feed)
561 {
562 if (!$feed->space_id) {
563 return;
564 }
565
566 $message = $feed->message;
567 $pattern = '/(?<!\S)@everyone(?!\S)/';
568
569 // match if the message contains @everyone
570
571 if (!preg_match($pattern, $message)) {
572 return;
573 }
574
575 // we have everyone
576 // check if current user is a moderator or admin
577 $user = $feed->user;
578
579 $spaceRole = $user->getSpaceRole($feed->space);
580
581 if (!in_array($spaceRole, ['admin', 'moderator'])) {
582 return;
583 }
584
585 $notificationSettings = Utility::getEmailNotificationSettings();
586
587 if (Arr::get($notificationSettings, 'mention_mail') === 'yes') {
588
589 do_action('fluent_community/feed/scheduling_everyone_tag', $feed);
590
591 // Let's schedule an email hook to send email to everyone for this post
592 // We are scheduling this after 5 minutes of the post publish for performance
593 as_schedule_single_action(time() + 300, 'fluent_community/email_notify_users_everyone_tag', [
594 $feed->id,
595 0
596 ], 'fluent-community');
597 }
598
599
600 }
601
602 private function willCreateFeedCreatedNotification($feed)
603 {
604 // validate if the user is a moderator
605 if (!$feed->user) {
606 return;
607 }
608
609 if ($feed->user->isCommunityModerator()) {
610 return true;
611 }
612
613 if ($feed->space) {
614 $role = $feed->user->getSpaceRole($feed->space);
615 return in_array($role, ['admin', 'moderator']);
616 }
617
618 return false;
619 }
620 }
621