PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.2.0
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.2.0
2.2.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 All 43 releases
← All changes | app/Http/Controllers/BoardController.php +31 -5 2.1.0 → 2.2.0 View file →
@@ -62,8 +62,17 @@
62 62 $type = $request->getSafe('type', 'sanitize_text_field', 'to-do');
63 63
64 64 $order = $request->getSafe('order', 'sanitize_text_field', 'created_at');
65 65 $orderBy = $request->getSafe('orderBy', 'sanitize_text_field', 'DESC');
66 + $order = is_string($order) ? sanitize_sql_orderby($order) : false;
67 + if (!in_array($order, ['created_at', 'title', 'updated_at', 'id'], true)) {
68 + $order = 'created_at';
69 + }
70 + $orderBy = is_string($orderBy) ? strtoupper($orderBy) : 'DESC';
71 + if (!in_array($orderBy, ['ASC', 'DESC'], true)) {
72 + $orderBy = 'DESC';
73 + }
74 +
66 75 $searchInput = $request->getSafe('searchInput', 'sanitize_text_field');
67 76
68 77 $option = $request->getSafe('option', 'sanitize_text_field');
69 78 $folderId = $request->getSafe('fid', 'intval'); // Get folder ID from request
@@ -85,10 +94,10 @@
85 94
86 95 // Scope pinned before pagination, from the same id source as getBoardCounts(),
87 96 // so the pinned page and board_counts.pinned always agree. Filtering pinned
88 97 // after pagination would drop pinned boards that fall on a later active page.
98 + $pinnedIds = $this->boardService->getPinnedBoardIds();
89 99 if ($option == 'pinned') {
90 - $pinnedIds = $this->boardService->getPinnedBoardIds();
91 100
92 101 $relatedBoardsQuery = $pinnedIds
93 102 ? $relatedBoardsQuery->whereIn('id', $pinnedIds)
94 103 : $relatedBoardsQuery->where('id', 0);
@@ -110,15 +119,15 @@
110 119 }
111 120
112 121 $relatedBoards = $relatedBoardsQuery->orderBy($order, $orderBy)
113 122 ->withCount('completedTasks')
114 - ->with('stages', 'users')
123 + ->with('stages', 'users', 'boardMeta', 'viewerMembership')
115 124 ->paginate($per_page);
116 125
117 126 foreach ($relatedBoards as $relatedBoard) {
118 127 $relatedBoard->description = DescriptionMarkdownConverter::normalize($relatedBoard->description);
119 128 $relatedBoard->users = Helper::sanitizeUserCollections($relatedBoard->users);
120 - $relatedBoard->is_pinned = $this->boardService->isPinned($relatedBoard->id);
129 + $relatedBoard->is_pinned = in_array((int) $relatedBoard->id, $pinnedIds, true);
121 130 }
122 131
123 132 $response = [
124 133 'boards' => $relatedBoards,
@@ -535,10 +544,12 @@
535 544 return $this->sendError($e->getMessage(), 404);
536 545 }
537 546 }
538 547
548 + /** Return board details with a cursor covering changes made during retrieval. */
539 549 public function find(Request $request, $board_id)
540 550 {
551 + $syncStartedAt = current_time('mysql');
541 552 $board = Board::findOrFail($board_id);
542 553 $board->description = DescriptionMarkdownConverter::normalize($board->description);
543 554 $includeArchived = filter_var($request->get('include_archived', false), FILTER_VALIDATE_BOOLEAN);
544 555 $board->background = maybe_unserialize($board->background);
@@ -578,9 +589,9 @@
578 589 $board = apply_filters('fluent_boards/board_find', $board);
579 590
580 591 return [
581 592 'board' => $board,
582 - 'synced_at' => current_time('mysql')
593 + 'synced_at' => $syncStartedAt
583 594 ];
584 595 }
585 596
586 597 public function update(Request $request, $board_id)
@@ -867,8 +878,9 @@
867 878
868 879
869 880 return [
870 881 'message' => __('Member added successfully', 'fluent-boards'),
882 + 'is_admin' => PermissionManager::isAdmin($memberId),
871 883 'member' => Helper::sanitizeUserCollections($member)
872 884 ];
873 885 }
874 886
@@ -1221,8 +1233,11 @@
1221 1233
1222 1234 return (bool) $permissionManager::currentUserCan('fcrm_read_contacts');
1223 1235 }
1224 1236
1237 + /**
1238 + * Duplicate a board with the selected board data options.
1239 + */
1225 1240 public function duplicateBoard(Request $request, $board_id)
1226 1241 {
1227 1242 $boardData = $this->taskSanitizeAndValidate($request->get('board'), [
1228 1243 'title' => 'required|string'
@@ -1231,8 +1246,10 @@
1231 1246 $boardData['source_board_id'] = $board_id;
1232 1247
1233 1248 $isWithLabels = $request->getSafe('isWithLabels');
1234 1249 $isWithTasks = $request->getSafe('isWithTasks');
1250 + $isWithMembers = $request->getSafe('isWithMembers');
1251 + $isWithCustomFields = $request->getSafe('isWithCustomFields', 'sanitize_text_field', 'yes');
1235 1252 $isWithTemplates = $request->getSafe('isWithTemplates');
1236 1253
1237 1254 try {
1238 1255 if(!PermissionManager::isAdmin()) {
@@ -1240,9 +1257,14 @@
1240 1257 throw new \Exception(esc_html($errorMessage), 400);
1241 1258 }
1242 1259 //create board
1243 1260 $newBoard = $this->boardService->copyBoard($boardData);
1261 + $customFieldMap = [];
1244 1262
1263 + if ($isWithCustomFields == 'yes') {
1264 + $customFieldMap = $this->boardService->copyCustomFieldsOfBoard($board_id, $newBoard);
1265 + }
1266 +
1245 1267 //label copy
1246 1268 $labelMap = [];
1247 1269
1248 1270 if ($isWithLabels == 'yes') {
@@ -1253,9 +1275,13 @@
1253 1275 $stageMapForCopyingTask = $this->stageService->copyStagesOfBoard($newBoard, $board_id, $isWithTemplates);
1254 1276
1255 1277 //copy tasks of selected stages
1256 1278 if ($isWithTasks == 'yes') {
1257 - $this->taskService->copyTasks($board_id, $stageMapForCopyingTask, $newBoard, $labelMap,$isWithTemplates);
1279 + $this->taskService->copyTasks($board_id, $stageMapForCopyingTask, $newBoard, $labelMap, $isWithTemplates, $customFieldMap);
1280 + }
1281 +
1282 + if ($isWithMembers == 'yes') {
1283 + $this->boardService->copyMembersOfBoard($board_id, $newBoard);
1258 1284 }
1259 1285
1260 1286 return $this->sendSuccess([
1261 1287 'board' => $newBoard,