PluginProbe
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses / trunk
FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses vtrunk
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 / Modules / PushNotification / PushNotificationModule.php

PushNotificationModule.php in FluentCommunity – Ultra-Fast High-Performance Social Network, Community, LMS & Online Courses trunk, at Modules/PushNotification/PushNotificationModule.php

213 lines 8.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentCommunity\Modules\PushNotification;
4
5 use FluentCommunity\App\Functions\Utility;
6 use FluentCommunity\App\Services\Helper;
7 use FluentCommunity\App\Services\NotificationPref;
8 use FluentCommunity\Framework\Support\Arr;
9
10 class PushNotificationModule
11 {
12 const SETUP_NOT_INSTALLED = 'not_installed';
13 const SETUP_INACTIVE = 'inactive';
14 const SETUP_DISABLED = 'disabled';
15 const SETUP_INCOMPLETE = 'incomplete';
16 const SETUP_READY = 'ready';
17
18 const PROMPT_PLACEMENTS = ['feed_sidebar','profile_notification_prefs','profile_sidebar','notification_popover'];
19
20 const COMMENT_ACTIONS = [
21 'fluent_community/notification/comment/notifed_to_author',
22 'fluent_community/notification/comment/notifed_to_mentions',
23 'fluent_community/notification/comment/notifed_to_thread_commetenter',
24 'fluent_community/notification/comment/notifed_to_other_users'
25 ];
26
27 const PUSHED_ACTIONS = ['comment_added', 'child_comment_added', 'mention_added'];
28
29 public static function isFluentNotifyActive()
30 {
31 return self::getSetupState() === self::SETUP_READY;
32 }
33
34 /**
35 * Which step of the FluentNotify setup is still outstanding, so the settings
36 * screen can say what to do rather than only that something is missing.
37 *
38 * @return string One of the SETUP_* constants.
39 */
40 public static function getSetupState()
41 {
42 if (!defined('FLUENT_NOTIFY_PLUGIN_VERSION')) {
43 // The files can be there while the plugin is deactivated, which needs
44 // activating rather than another download.
45 if (file_exists(WP_PLUGIN_DIR . '/fluent-notify/fluent-notify.php')) {
46 return self::SETUP_INACTIVE;
47 }
48
49 return self::SETUP_NOT_INSTALLED;
50 }
51
52 if (!\FluentNotify\App\Services\Helper::isEnabled()) {
53 return self::SETUP_DISABLED;
54 }
55
56 if (!\FluentNotify\App\Services\Helper::isConfigComplete()) {
57 return self::SETUP_INCOMPLETE;
58 }
59
60 return self::SETUP_READY;
61 }
62
63 public static function getSettingsUrl()
64 {
65 // FluentNotify picks hash or history routing at runtime; the fragment is
66 // ignored under history routing, which lands on its dashboard instead.
67 return admin_url('admin.php?page=fluent-notify#/settings');
68 }
69
70 public static function isAvailable()
71 {
72 $pushEnabledInCommunity = Arr::get(Utility::getPushNotificationSettings(), 'push_enabled') === 'yes';
73
74 return self::isFluentNotifyActive() && $pushEnabledInCommunity;
75 }
76
77 public static function getPushedCommentIds($userId, $commentIds)
78 {
79 if (!$userId || !$commentIds || !class_exists('\FluentNotify\App\Models\NotificationLog')) {
80 return [];
81 }
82
83 $pushed = \FluentNotify\App\Models\NotificationLog::query()
84 ->join('fn_subscriptions', 'fn_subscriptions.id', '=', 'fn_notifications.subscription_id')
85 ->where('fn_subscriptions.user_id', $userId)
86 ->where('fn_notifications.source', 'community_comment')
87 ->whereIn('fn_notifications.source_id', $commentIds)
88 ->whereNotIn('fn_notifications.status', ['fcm_failed', 'fcm_skipped'])
89 ->pluck('fn_notifications.source_id')
90 ->toArray();
91
92 return array_values(array_unique(array_map('intval', $pushed)));
93 }
94
95 public function register()
96 {
97 if (!self::isAvailable()) return;
98
99 foreach (self::COMMENT_ACTIONS as $action) {
100 add_action($action, [$this, 'handleCommentNotification'], 10, 1);
101 }
102
103 // let's load the assets
104 add_filter('fluent_community/portal_data_vars', function ($vars) {
105 if (!is_user_logged_in()) {
106 return $vars;
107 }
108
109 $vars['js_files']['push_notification'] = [
110 'url' => \FluentNotify\App\Vite::getStaticSrcUrl('push_notification.js'),
111 'deps' => [],
112 ];
113 $vars['js_vars']['fluentNotifyPublic'] = \FluentNotify\App\Services\Helper::getPublicConfig();
114
115 return $vars;
116 });
117
118 add_filter('fluent_community/portal_vars', function ($vars) {
119 if (!is_user_logged_in()) {
120 return $vars;
121 }
122
123 $vars['has_push_notification'] = true;
124 $vars['push_prompt_placements'] = Arr::get(Utility::getPushNotificationSettings(), 'prompt_placements');
125
126 return $vars;
127 });
128
129 }
130
131 public function handleCommentNotification($eventData)
132 {
133 $key = Arr::get($eventData, 'key');
134 $comment = Arr::get($eventData, 'comment');
135 $feed = Arr::get($eventData, 'feed');
136
137 if (!$feed || !$comment) return;
138
139 // Hook event key => notification event in NotificationPref::NOTIFICATION_EVENTS.
140 $hookToEvent = [
141 'notifed_to_author' => 'comment',
142 'notifed_to_thread_commetenter' => 'reply',
143 'notifed_to_mentions' => 'mention',
144 'notifed_to_other_users' => 'co_comment'
145 ];
146
147 $userIds = NotificationPref::filterPushUserIds(
148 Arr::get($eventData, 'user_ids', []),
149 Arr::get($hookToEvent, $key, '')
150 );
151
152 if (!$userIds) return;
153
154 $xprofile = $comment->xprofile;
155
156 $notification = Arr::get($eventData, 'notification');
157 $content = Helper::getHumanExcerpt($comment->message_rendered ?: $comment->message, 100);
158 if (!$content) {
159 // The co-comment hook passes the notification as an array, the others as a model.
160 $fallback = is_array($notification) ? Arr::get($notification, 'content') : $notification->content;
161 $content = Helper::getHumanExcerpt($fallback, 100);
162 }
163
164 $commenter = $xprofile ? $xprofile->display_name : '' . __('Someone', 'fluent-community');
165 $feedTitle = $feed->title ? $feed->title : __('post', 'fluent-community');
166
167 // get the first name only
168 $commenterParts = explode(' ', $commenter);
169 if (count($commenterParts) > 0) {
170 $commenter = $commenterParts[0];
171 }
172
173 $title = '';
174 switch ($key):
175 case 'notifed_to_author':
176 /* translators: %1$s is the commenter name, %2$s is the post title */
177 $title = \sprintf(__('New comment by %1$s on: %2$s', 'fluent-community'), $commenter, $feedTitle);
178 break;
179 case 'notifed_to_mentions':
180 /* translators: %1$s is the commenter name, %2$s is the post title */
181 $title = \sprintf(__('%1$s mentioned you on: %2$s', 'fluent-community'), $commenter, $feedTitle);
182 break;
183 case 'notifed_to_other_users':
184 /* translators: %1$s is the commenter name, %2$s is the post title */
185 $title = \sprintf(__('%1$s also commented on: %2$s', 'fluent-community'), $commenter, $feedTitle);
186 break;
187 case 'notifed_to_thread_commetenter':
188 /* translators: %1$s is the commenter name, %2$s is the post title */
189 $title = \sprintf(__('%1$s replied to a comment on: %2$s', 'fluent-community'), $commenter, $feedTitle);
190 break;
191 default:
192 /* translators: %1$s is the commenter name, %2$s is the post title */
193 $content = \sprintf(__('Comment by %1$s on %2$s', 'fluent-community'), $commenter, $feedTitle);
194 endswitch;
195
196 $actionUrl = add_query_arg([
197 'comment_id' => $comment->id,
198 'fcom_pn' => 'true',
199 'feed_id' => $feed->id,
200 ], $feed->getPermalink());
201
202 do_action('fluent_notify/schedule_notifications', $userIds, [
203 'user_ids' => $userIds,
204 'title' => $title,
205 'message' => $content,
206 'action_url' => $actionUrl,
207 'icon' => $xprofile->avatar,
208 'source' => 'community_comment',
209 'source_id' => $comment->id,
210 ]);
211 }
212 }
213