PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.0.0
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.0.0
2.0.15 2.0.12 2.0.10 2.0.4 2.0.1 2.0.0 1.95.3 1.95.2 1.95 1.91.6 trunk 1.11 1.12 1.13 1.20 1.21 1.22 1.23 1.30 1.31 1.32 1.35 1.40 1.41 1.45 All 41 releases
fluent-boards / app / Services / NotificationService.php

NotificationService.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.0.0, at app/Services/NotificationService.php

350 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentBoards\App\Services;
4
5 use FluentBoards\App\Models\Meta;
6 use FluentBoards\App\Models\Notification;
7 use FluentBoards\App\Models\NotificationUser;
8 use FluentBoards\App\Models\Relation;
9 use FluentBoards\App\Models\Task;
10 use FluentBoards\App\Models\User;
11
12 class NotificationService
13 {
14 public function getAllNotifications($per_page, $page, $action = 'all')
15 {
16 $user = wp_get_current_user();
17
18 $query = Notification::where('object_type', Constant::OBJECT_TYPE_BOARD_NOTIFICATION)
19 ->whereHas('users', function($q) use ($user) {
20 $q->where('user_id', $user->ID);
21 });
22
23 // Add action filter if not 'all'
24 if ($action !== 'all') {
25 $query->where('action', $action);
26 }
27
28 $notifications = $query->with('activitist', 'task')
29 ->orderBy('created_at', 'desc')
30 ->paginate($per_page, ['*'], 'page', $page);
31
32 foreach ($notifications as $notification){
33 $notification->read = $notification->checkReadOrNot();
34 }
35
36 return $notifications;
37 }
38
39 /**
40 * @throws \Exception
41 */
42 public function getAllUnreadNotifications($per_page, $page)
43 {
44 $userId = get_current_user_id();
45 if (!$userId) {
46 throw new \Exception(esc_html__('You are not allowed to do that', 'fluent-boards'), 403);
47 }
48 $unreadNotifications = Notification::where('object_type', Constant::OBJECT_TYPE_BOARD_NOTIFICATION)
49 ->whereHas('users', function($q) use ($userId) {
50 $q->where('user_id', $userId)
51 ->whereNull('marked_read_at');
52 })->with('activitist', 'task')->orderBy('created_at', 'desc')->paginate($per_page, ['*'], 'page', $page);
53 return $unreadNotifications;
54 }
55
56 public function markAllRead()
57 {
58 $user = wp_get_current_user();
59
60 $userNotifications = NotificationUser::where('user_id', $user->ID)
61 ->with('notification')
62 ->get();
63
64 foreach ($userNotifications as $data)
65 {
66 $data->marked_read_at = current_time('mysql');
67 $data->save();
68 }
69 }
70
71 public function markNotificationRead($notificationId)
72 {
73 $user = wp_get_current_user();
74
75 $notification = NotificationUser::where('user_id', $user->ID)
76 ->where('notification_id', $notificationId)
77 ->first();
78 if (!$notification) {
79 throw new \Exception(esc_html__('Notification could not be found', 'fluent-boards'), 404);
80 }
81
82 $notification->marked_read_at = current_time('mysql');
83 $notification->save();
84 return $notification;
85 }
86
87 public function newNotificationNumber()
88 {
89 $user = wp_get_current_user();
90
91 $unread_notifications = Notification::query()->where('object_type', Constant::OBJECT_TYPE_BOARD_NOTIFICATION)
92 ->whereHas('users', function($q) use ($user) {
93 $q->where('user_id', $user->ID)
94 ->whereNull('marked_read_at');
95 });
96
97 return $unread_notifications->count();
98 }
99
100 public function isCurrentUserObservingTask($task)
101 {
102 $currentUserId = get_current_user_id();
103 $observers = $task->watchers()->get()->pluck('ID');
104
105 foreach ($observers as $id){
106 if($id == $currentUserId)
107 return true;
108 }
109
110 return false;
111 }
112
113 public function getBoardNotificationSettingsOfUser($id, $userId)
114 {
115 $boardSettings = Relation::where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
116 ->where('object_id', $id)
117 ->where('foreign_id', $userId)
118 ->first();
119
120 return $boardSettings;
121 }
122
123 public function getGlobalNotificationSettingsOfUser($userId)
124 {
125 $settings = Meta::where('object_type', Constant::OBJECT_TYPE_USER)
126 ->where('object_id', $userId)
127 ->where('key', Constant::USER_GLOBAL_NOTIFICATIONS)
128 ->first();
129
130 return $settings;
131 }
132
133 /**
134 * Return board notification preferences with defaults and global watch fallbacks applied.
135 */
136 public function getBoardNotificationSettingsWithDefaults($boardId, $userId)
137 {
138 $settings = array_merge(
139 Constant::BOARD_NOTIFICATION_TYPES,
140 $this->getGlobalWatchNotificationSettings($userId)
141 );
142
143 $boardSettings = $this->getBoardNotificationSettingsOfUser($boardId, $userId);
144 if ($boardSettings && $boardSettings->preferences) {
145 $preferences = maybe_unserialize($boardSettings->preferences);
146 if (is_array($preferences)) {
147 $settings = array_merge($settings, $preferences);
148 }
149 }
150
151 foreach ($settings as $key => $value) {
152 $settings[$key] = $this->normalizePreferenceValue($value);
153 }
154
155 return $settings;
156 }
157
158 /**
159 * Check if a board-scoped auto-watch preference is enabled for a user.
160 */
161 public function isBoardAutoWatchEnabled($boardId, $userId, $preferenceKey)
162 {
163 $settings = $this->getBoardNotificationSettingsWithDefaults($boardId, $userId);
164
165 return array_key_exists($preferenceKey, $settings) && $this->normalizePreferenceValue($settings[$preferenceKey]);
166 }
167
168 /**
169 * Get global watch preferences for fallback when a board has no saved watch keys.
170 */
171 private function getGlobalWatchNotificationSettings($userId)
172 {
173 $watchSettings = [
174 Constant::GLOBAL_EMAIL_NOTIFICATION_CREATING_TASK => true,
175 Constant::GLOBAL_EMAIL_NOTIFICATION_COMMENTING => true,
176 Constant::GLOBAL_EMAIL_NOTIFICATION_ASSIGNING => true,
177 ];
178
179 $globalSettings = $this->getGlobalNotificationSettingsOfUser($userId);
180 if (!$globalSettings || !$globalSettings->value) {
181 return $watchSettings;
182 }
183
184 $preferences = maybe_unserialize($globalSettings->value);
185 if (!is_array($preferences)) {
186 return $watchSettings;
187 }
188
189 foreach (array_keys($watchSettings) as $key) {
190 if (array_key_exists($key, $preferences)) {
191 $watchSettings[$key] = $this->normalizePreferenceValue($preferences[$key]);
192 }
193 }
194
195 return $watchSettings;
196 }
197
198 /**
199 * Convert stored preference values into strict booleans.
200 */
201 private function normalizePreferenceValue($value)
202 {
203 return true === $value || 1 === $value || '1' === $value || 'true' === $value;
204 }
205
206 public function updateBoardNotificationSettings($newSettings, $id)
207 {
208 $userId = get_current_user_id();
209 $boardSettings = $this->getBoardNotificationSettingsOfUser($id, $userId);
210 if(empty($boardSettings)){
211 return;
212 }
213 foreach ($newSettings as $index => $setting)
214 {
215 $newSettings[$index] = $setting == 'true' ? true : false;
216 }
217 $boardSettings->preferences = $newSettings;
218 $boardSettings->save();
219
220 }
221
222 public function filterAssigneeToSendEmail($taskId, $emailPurpose){
223 $task = Task::findOrFail($taskId);
224 $watchers = $task->watchers;
225 $currentUserId = get_current_user_id();
226
227 $wathersToSendEmail = array();
228
229 foreach ($watchers as $watcher){
230 if($watcher->ID != $currentUserId)
231 {
232 if($this->checkIfEmailEnable($watcher->ID, $emailPurpose, $task->board_id))
233 {
234 $wathersToSendEmail[] = $watcher->user_email;
235 }
236 }
237 }
238
239 return $wathersToSendEmail;
240 }
241
242 public function checkIfEmailEnable($userId, $emailPurpose, $boardId)
243 {
244 if(
245 $this->checkIfEmailEnabled($boardId, $userId, $emailPurpose)
246 ){
247 return true;
248 }else{
249 return false;
250 }
251 }
252
253 public function checkIfEmailEnabled($boardId, $userId, $purpose)
254 {
255 $boardSettings = $this->getBoardNotificationSettingsOfUser($boardId, $userId);
256
257 if($boardSettings){
258 $preferences = maybe_unserialize($boardSettings['preferences']);
259 if(!array_key_exists($purpose, $preferences)){
260 $preferences[$purpose] = true;
261 $boardSettings->preferences = $preferences;
262 $boardSettings->save();
263 return true;
264 }
265 return $preferences[$purpose];
266 }
267
268 return false;
269 }
270
271 public function mentionInComment($comment, $mentionedUserIds)
272 {
273 $uniqueIds = array_unique($mentionedUserIds);
274
275 $uniqueIds = array_filter($uniqueIds, function($value) {
276 return (int)$value !== get_current_user_id();
277 });
278
279 //sending emails to mentioned users
280 $mentionedUserEmails = User::whereIn('ID', $uniqueIds)->pluck('user_email');
281 $this->sendMailAfterMention($comment->id, $mentionedUserEmails);
282
283 //sending desktop notifications
284 do_action('fluent_boards/mention_comment_notification', $comment, $uniqueIds);
285 }
286
287 public function sendMailAfterMention($commentId, $usersToSendEmail)
288 {
289 $current_user_id = get_current_user_id();
290
291 /* this will run in background as soon as possible */
292 /* sending Model or Model Instance won't work here */
293 as_enqueue_async_action('fluent_boards/one_time_schedule_send_email_for_mention', [$commentId, $usersToSendEmail, $current_user_id], 'fluent-boards');
294 }
295
296 public function getUnreadNotificationsOfTasks($task)
297 {
298 $userId = get_current_user_id();
299 if (!$userId) {
300 throw new \Exception(esc_html__('You are not allowed to do that', 'fluent-boards'), 403);
301 }
302 $unreadNotifications = Notification::where('object_type', Constant::OBJECT_TYPE_BOARD_NOTIFICATION)
303 ->whereHas('users', function($q) use ($userId) {
304 $q->where('user_id', $userId)
305 ->whereNull('marked_read_at');
306 })->whereHas('task', function($q) use ($task) {
307 $q->where('id', $task->id);
308 })
309 ->with('activitist')->orderBy('created_at', 'desc')->count();
310 return $unreadNotifications;
311 }
312
313 public function getUnreadNotificationCountsByTaskIds($taskIds)
314 {
315 $userId = get_current_user_id();
316 if (!$userId) {
317 throw new \Exception(esc_html__('You are not allowed to do that', 'fluent-boards'), 403);
318 }
319
320 $taskIds = array_values(array_filter(array_map('intval', (array) $taskIds)));
321 if (!$taskIds) {
322 return [];
323 }
324
325 $rows = Notification::query()
326 // Board/list views can return many tasks at once, so unread counts are
327 // grouped in one query instead of issuing a count query per task.
328 ->selectRaw('task_id, COUNT(*) as unread_count')
329 ->join(
330 (new NotificationUser())->getTable(),
331 'fbs_notifications.id',
332 '=',
333 'fbs_notification_users.notification_id'
334 )
335 ->where('object_type', Constant::OBJECT_TYPE_BOARD_NOTIFICATION)
336 ->where('fbs_notification_users.user_id', $userId)
337 ->whereNull('fbs_notification_users.marked_read_at')
338 ->whereIn('task_id', $taskIds)
339 ->groupBy('task_id')
340 ->get();
341
342 $notificationCounts = [];
343 foreach ($rows as $row) {
344 $notificationCounts[(int) $row->task_id] = (int) $row->unread_count;
345 }
346
347 return $notificationCounts;
348 }
349 }
350