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/ActivityMonitorHandler.php +49 -8 1.0.932.11.0 View file →
@@ -1,11 +1,13 @@
1 1 <?php
2 2
3 3 namespace FluentCommunity\App\Hooks\Handlers;
4 4
5 +use FluentCommunity\App\Functions\Utility;
5 6 use FluentCommunity\App\Models\Activity;
6 7 use FluentCommunity\App\Models\XProfile;
7 8 use FluentCommunity\App\Services\Helper;
9 +use FluentCommunity\Framework\Support\Arr;
8 10
9 11 class ActivityMonitorHandler
10 12 {
11 13 public function register()
@@ -12,14 +14,18 @@
12 14 {
13 15 add_action('fluent_community/comment_added', [$this, 'handleNewCommentEvent'], 10, 2);
14 16 add_action('fluent_community/feed/created', [$this, 'handleFeedCreated'], 10, 1);
15 17
16 - add_action('fluent_communit/track_activity', [$this, 'trackActivity'], 10);
18 + add_action('fluent_community/track_activity', [$this, 'trackActivity'], 10);
17 19
18 20 add_action('profile_update', function ($userId) {
21 + if (Utility::getPrivacySetting('enable_user_sync') === 'no') {
22 + return;
23 + }
24 +
19 25 $user = get_user_by('ID', $userId);
20 26 $xprofile = XProfile::where('user_id', $userId)->first();
21 - if (!$xprofile) {
27 + if (!$user || !$xprofile) {
22 28 return;
23 29 }
24 30 $firstName = $user->first_name;
25 31 $lastName = $user->last_name;
@@ -29,17 +35,43 @@
29 35 $xprofile->save();
30 36 }
31 37 });
32 38
39 + add_action('wp_ajax_fluent_community_renew_nonce', [$this, 'renewNonce']);
40 +
41 + // Logged-out: without this, WP returns "0"/200 and the SPA loops on a stale nonce.
42 + add_action('wp_ajax_nopriv_fluent_community_renew_nonce', function () {
43 + wp_send_json(['message' => __('Your session has expired. Please log in again.', 'fluent-community')], 401);
44 + });
33 45 }
34 46
47 + public function renewNonce()
48 + {
49 + $ajax_nonce = Arr::get($_REQUEST, 'ajax_nonce'); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
35 50
51 + if (!wp_verify_nonce($ajax_nonce, 'fluent_community_ajax_nonce')) {
52 + wp_send_json(['message' => __('Invalid nonce', 'fluent-community')], 400);
53 + }
54 +
55 + $currentProfile = Helper::getCurrentProfile();
56 + if (!$currentProfile) {
57 + wp_send_json(['message' => __('Invalid user', 'fluent-community')], 401);
58 + }
59 +
60 + wp_send_json([
61 + 'rest_nonce' => wp_create_nonce('wp_rest'),
62 + 'ajax_nonce' => wp_create_nonce('fluent_community_ajax_nonce'),
63 + ], 200);
64 + }
65 +
66 +
36 67 public function handleNewCommentEvent($comment, $feed)
37 68 {
38 69 $isPublic = 1;
70 + $space = $feed->space_id ? $feed->space : null;
39 71
40 - if ($feed->space_id) {
41 - $isPublic = $feed->space->privacy == 'public';
72 + if ($space) {
73 + $isPublic = $space->privacy == 'public';
42 74 }
43 75
44 76 $data = [
45 77 'user_id' => $comment->user_id,
@@ -51,17 +83,18 @@
51 83 ];
52 84
53 85 Activity::create($data);
54 86
55 - do_action('fluent_communit/track_activity');
87 + do_action('fluent_community/track_activity');
56 88 }
57 89
58 90 public function handleFeedCreated($feed)
59 91 {
60 92 $isPublic = 1;
93 + $space = $feed->space_id ? $feed->space : null;
61 94
62 - if ($feed->space_id) {
63 - $isPublic = $feed->space->privacy == 'public';
95 + if ($space) {
96 + $isPublic = $space->privacy == 'public';
64 97 }
65 98
66 99 $data = [
67 100 'user_id' => $feed->user_id,
@@ -72,9 +105,9 @@
72 105 ];
73 106
74 107 Activity::create($data);
75 108
76 - do_action('fluent_communit/track_activity');
109 + do_action('fluent_community/track_activity');
77 110 }
78 111
79 112 public function trackActivity()
80 113 {
@@ -80,8 +113,16 @@
80 113 {
81 114 $currentProfile = Helper::getCurrentProfile();
82 115
83 116 if (!$currentProfile) {
117 + return false;
118 + }
119 +
120 + // Debounce: skip the write if last_activity was updated within the last 5 minutes.
121 + // The ticker polls every ~45-75s per session; without this each poll issues an
122 + // xprofile UPDATE, saturating the DB at scale.
123 + $throttleSeconds = apply_filters('fluent_community/track_activity_throttle_seconds', 300);
124 + if ($currentProfile->last_activity && (current_time('timestamp') - strtotime($currentProfile->last_activity)) < $throttleSeconds) {
84 125 return false;
85 126 }
86 127
87 128 $currentProfile->last_activity = current_time('mysql');