PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.1.0
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.1.0
2.1.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 All 42 releases
← All changes | app/Services/UserService.php +157 -64 2.0.12.1.0 View file →
@@ -108,20 +108,46 @@
108 108
109 109 return $boardUsers;
110 110 }
111 111
112 + /**
113 + * Return associated users and roles only from boards shared with the requester.
114 + */
112 115 public function memberAssociatedTaskUsers($userId)
113 116 {
114 117 $user = User::find($userId);
115 - $boards = $user->whichBoards->pluck('id');
116 - $boardUsers = Relation::whereIn('object_id', $boards)
118 + $memberBoardIds = array_values(array_unique(array_filter(array_map(
119 + 'intval',
120 + $user->whichBoards->pluck('id')->toArray()
121 + ))));
122 + $requesterBoardIds = array_values(array_unique(array_filter(array_map(
123 + 'intval',
124 + PermissionManager::getBoardIdsForUser(get_current_user_id())
125 + ))));
126 + $sharedBoardIds = array_values(array_intersect($memberBoardIds, $requesterBoardIds));
127 +
128 + if (!$sharedBoardIds) {
129 + return [
130 + 'uniqueUsers' => [],
131 + 'userWiseBoardDesignation' => [],
132 + ];
133 + }
134 +
135 + $boardUsers = Relation::whereIn('object_id', $sharedBoardIds)
117 136 ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
118 137 ->pluck('foreign_id')->toArray();
119 138 $uniqueUsersIds = array_unique($boardUsers);
120 - $uniqueUsers = User::whereIn('ID', $uniqueUsersIds)->with('whichBoards')->get();
139 + $boardTable = (new Board())->getTable();
140 + $uniqueUsers = User::whereIn('ID', $uniqueUsersIds)
141 + ->with(['whichBoards' => function ($query) use ($boardTable, $sharedBoardIds) {
142 + $query->whereIn($boardTable . '.id', $sharedBoardIds);
143 + }])
144 + ->get();
121 145
122 146 $userWiseBoardDesignation = Relation::query()->whereIn('foreign_id', $uniqueUsersIds)
123 - ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)->get();
147 + ->whereIn('object_id', $sharedBoardIds)
148 + ->where('object_type', Constant::OBJECT_TYPE_BOARD_USER)
149 + ->get();
124 150
125 151 $data = array();
126 152 $data['userWiseBoardDesignation'] = $userWiseBoardDesignation;
127 153
@@ -135,9 +161,9 @@
135 161 } elseif (PermissionManager::isFluentBoardsAdmin($uniqueUser['ID'])) {
136 162 $uniqueUser['is_super'] = true;
137 163 $uniqueUser['is_wpadmin'] = false;
138 164 } else {
139 - $uniqueUser['all_boards'] = Arr::get($uniqueUser, 'boards');
165 + $uniqueUser['all_boards'] = $uniqueUser->getRelation('whichBoards');
140 166 $uniqueUser['is_super'] = false;
141 167 $uniqueUser['is_wpadmin'] = false;
142 168 }
143 169 }
@@ -243,42 +269,55 @@
243 269
244 270 // Table view needs the labels column; list view ignores the extra relation.
245 271 $taskRelations = ['stage', 'board', 'labels'];
246 272
247 - if($taskType == 'assigned') {
248 - $tasksQuery = $user->assignedTasks()->with($taskRelations)->whereNull('archived_at')->whereNull('parent_id')->whereIn('board_id', $allowedBoardIds);
249 - } else if($taskType == 'mentioned') {
250 - $tasksQuery = $user->mentionedTasks()->with($taskRelations)->whereNull('archived_at')->whereNull('parent_id')->whereIn('board_id', $allowedBoardIds);
273 + if ($taskType == 'assigned') {
274 + $tasksQuery = $user->assignedTasks()
275 + ->with($taskRelations)
276 + ->whereNull('archived_at')
277 + ->whereNull('parent_id')
278 + ->whereIn('board_id', $allowedBoardIds)
279 + ->where('status', '!=', 'closed')
280 + ->onActiveAvailableBoards();
281 + } else if ($taskType == 'mentioned') {
282 + $tasksQuery = $user->mentionedTasks()
283 + ->with($taskRelations)
284 + ->whereNull('archived_at')
285 + ->whereNull('parent_id')
286 + ->whereIn('board_id', $allowedBoardIds)
287 + ->onActiveAvailableBoards();
251 288 } else {
252 - // Get the task assigned to the user
253 - $tasksQuery = $user->tasks()->with($taskRelations)->whereNull('archived_at') ->whereIn('board_id', $allowedBoardIds);
289 + // Watched tasks power the date-based and completed profile tabs.
290 + $tasksQuery = $user->tasks()
291 + ->with($taskRelations)
292 + ->whereNull('archived_at')
293 + ->whereIn('board_id', $allowedBoardIds)
294 + ->onActiveAvailableBoards();
254 295
255 - switch ($taskType) {
256 - case 'upcoming':
257 - $tasksQuery->upcoming()
258 - ->whereIn('board_id', $allowedBoardIds);
259 - break;
260 - case 'due_today':
261 - $tasksQuery->dueToday()
262 - ->whereIn('board_id', $allowedBoardIds);
263 - break;
264 - case 'overdue':
265 - $tasksQuery->overdue()
266 - ->whereIn('board_id', $allowedBoardIds);
267 - break;
268 - case 'completed':
269 - $tasksQuery->where('status', 'closed')
270 - ->whereIn('board_id', $allowedBoardIds);
271 - break;
272 - default:
273 - $tasksQuery->whereNull('due_at')
274 - ->whereIn('board_id', $allowedBoardIds);
275 - break;
296 + switch ($taskType) {
297 + case 'upcoming':
298 + $tasksQuery->upcoming()
299 + ->whereIn('board_id', $allowedBoardIds);
300 + break;
301 + case 'due_today':
302 + $tasksQuery->dueToday()
303 + ->whereIn('board_id', $allowedBoardIds);
304 + break;
305 + case 'overdue':
306 + $tasksQuery->overdue()
307 + ->whereIn('board_id', $allowedBoardIds);
308 + break;
309 + case 'completed':
310 + $tasksQuery->where('status', 'closed')
311 + ->whereIn('board_id', $allowedBoardIds);
312 + break;
313 + default:
314 + $tasksQuery->whereNull('due_at')
315 + ->whereIn('board_id', $allowedBoardIds);
316 + break;
317 + }
276 318 }
277 - }
278 319
279 -
280 -
281 320 $currentUserId = get_current_user_id();
282 321 if ($currentUserId != $user->ID && !PermissionManager::isAdmin()) {
283 322 $currentUser = User::find($currentUserId);
284 323 $currentUserBoardIds = $currentUser->boards->pluck('id')->toArray();
@@ -352,9 +391,10 @@
352 391 // Keep the count queries aligned with the profile list without loading task models or relations.
353 392 $applyTaskScope = function ($query) use ($allowedBoardIds, $boardIds) {
354 393 $query->whereNull('archived_at')
355 394 ->whereNull('parent_id')
356 - ->whereIn('board_id', $allowedBoardIds);
395 + ->whereIn('board_id', $allowedBoardIds)
396 + ->onActiveAvailableBoards();
357 397
358 398 if (!empty($boardIds)) {
359 399 $query->whereIn('board_id', $boardIds);
360 400 }
@@ -366,9 +406,11 @@
366 406 };
367 407
368 408 return [
369 409 'due_today' => (int) $watchedTasks()->dueToday()->count(),
370 - 'assigned' => (int) $applyTaskScope($user->assignedTasks())->count(),
410 + 'assigned' => (int) $applyTaskScope($user->assignedTasks())
411 + ->where('status', '!=', 'closed')
412 + ->count(),
371 413 'upcoming' => (int) $watchedTasks()->upcoming()->count(),
372 414 'overdue' => (int) $watchedTasks()->overdue()->count(),
373 415 'mentioned' => (int) $applyTaskScope($user->mentionedTasks())->count(),
374 416 'completed' => (int) $watchedTasks()->where('status', 'closed')->count(),
@@ -376,38 +418,91 @@
376 418 ];
377 419 }
378 420
379 421
422 + /**
423 + * Get a member's activities scoped to boards the requesting user can access.
424 + */
380 425 public function getMemberRelatedAcitivies($user_id, $page)
381 426 {
382 - $activities = Activity::query()->where('created_by', $user_id)
427 + $perPage = 40;
428 + $user_id = absint($user_id);
429 + $page = max(1, absint($page));
430 + $allowedBoardIds = array_values(array_filter(array_map(
431 + 'intval',
432 + PermissionManager::getBoardIdsForUser(get_current_user_id())
433 + )));
434 +
435 + if (empty($allowedBoardIds)) {
436 + return [
437 + 'activities' => [],
438 + 'pagination' => $this->getEmptyPaginationInfo($page, $perPage),
439 + ];
440 + }
441 +
442 + $allowedTaskIds = Task::query()
443 + ->select('id')
444 + ->whereIn('board_id', $allowedBoardIds);
445 +
446 + $activities = Activity::query()
447 + ->where('created_by', $user_id)
448 + ->where(function ($query) use ($allowedBoardIds, $allowedTaskIds) {
449 + $query->where(function ($boardQuery) use ($allowedBoardIds) {
450 + $boardQuery->where('object_type', Constant::ACTIVITY_BOARD)
451 + ->whereIn('object_id', $allowedBoardIds);
452 + })->orWhere(function ($taskQuery) use ($allowedTaskIds) {
453 + $taskQuery->where('object_type', Constant::ACTIVITY_TASK)
454 + ->whereIn('object_id', $allowedTaskIds);
455 + });
456 + })
383 457 ->orderBy('created_at', 'desc')
384 - ->with('user')->paginate(40, ['*'], 'page', $page);
458 + ->with('user')
459 + ->paginate($perPage, ['*'], 'page', $page);
385 460
386 - $activitiesToShow = array();
461 + $activitiesToShow = [];
387 462
388 463 foreach ($activities as $activity) {
389 464 if ($activity->object_type == Constant::ACTIVITY_BOARD) {
390 465 $activity->load('board');
391 -// if($activity->settings && $activity->settings['task_id']){
392 -// $activity->task = Task::findOrFail($activity->settings['task_id']);
393 -// }
394 - if (PermissionManager::userHasPermission($activity->board_id, get_current_user_id())) {
395 - $activitiesToShow[] = $activity;
396 - }
466 + $activitiesToShow[] = $activity;
397 467 } elseif ($activity->object_type == Constant::ACTIVITY_TASK) {
398 468 $activity->load('task');
399 - if ($activity->task && PermissionManager::userHasPermission($activity->task->board_id, get_current_user_id())) {
400 - $activitiesToShow[] = $activity;
401 - }
469 + $activitiesToShow[] = $activity;
402 470 }
403 471 }
472 +
404 473 return [
405 - 'activities' => $activitiesToShow,
406 - 'pagination' => $activities->toArray(),
474 + 'activities' => $activitiesToShow,
475 + 'pagination' => $this->getPaginationInfo($activities),
407 476 ];
408 477 }
409 478
479 + /**
480 + * Return pagination metadata without duplicating serialized row data.
481 + */
482 + private function getPaginationInfo($paginator)
483 + {
484 + return [
485 + 'current_page' => $paginator->currentPage(),
486 + 'last_page' => $paginator->lastPage(),
487 + 'per_page' => (int) $paginator->perPage(),
488 + 'total' => $paginator->total(),
489 + ];
490 + }
491 +
492 + /**
493 + * Return an empty pagination payload for callers without accessible boards.
494 + */
495 + private function getEmptyPaginationInfo($page, $perPage)
496 + {
497 + return [
498 + 'current_page' => max(1, (int) $page),
499 + 'last_page' => 1,
500 + 'per_page' => (int) $perPage,
501 + 'total' => 0,
502 + ];
503 + }
504 +
410 505 private function getTaskById($taskId)
411 506 {
412 507 return Task::findOrFail($taskId);
413 508 }
@@ -416,25 +511,23 @@
416 511 {
417 512 if(!$user_id) {
418 513 return [];
419 514 }
420 - $boardIds = [];
421 - $boards = [];
422 515 $user = User::find($user_id);
423 516 $currentUserId = get_current_user_id();
424 - if($currentUserId != $user->ID) {
425 - if(!PermissionManager::isAdmin()){
426 - $currentUser = User::find($currentUserId);
427 - $currentUserBoardIds = $currentUser->whichBoards->pluck('id')->toArray();
428 - $boardIds = $currentUserBoardIds;
429 - }
517 +
518 + if ($currentUserId == $user->ID || PermissionManager::isAdmin($currentUserId)) {
519 + return $user->whichBoards;
430 520 }
431 - if (!empty($boardIds)) {
432 - $boards = $user->whichBoards()->whereIn('fbs_boards.id', $boardIds)->get();
433 - } else {
434 - $boards = $user->whichBoards;
521 +
522 + $currentUser = User::find($currentUserId);
523 + $boardIds = $currentUser ? $currentUser->whichBoards->pluck('id')->toArray() : [];
524 +
525 + if (empty($boardIds)) {
526 + return [];
435 527 }
436 - return $boards;
528 +
529 + return $user->whichBoards()->whereIn('fbs_boards.id', $boardIds)->get();
437 530 }
438 531
439 532 /**
440 533 * Returns four aggregate counts for a member's stats widget.