PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.11
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.11
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 / Http / Controllers / BoardController.php

BoardController.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 1.11, at app/Http/Controllers/BoardController.php

893 lines 29.2 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\Http\Controllers;
4
5 use FluentBoards\App\Models\Meta;
6 use FluentBoards\App\Models\Relation;
7 use FluentBoards\App\Models\Task;
8 use FluentBoards\App\Models\User;
9 use FluentBoards\App\Models\Board;
10 use FluentBoards\App\Services\Constant;
11 use FluentBoards\App\Services\Helper;
12 use FluentBoards\App\Models\Stage;
13 use FluentBoards\App\Services\StageService;
14 use FluentBoards\App\Services\TaskService;
15 use FluentBoards\App\Services\BoardService;
16 use FluentBoards\App\Services\UserService;
17 use FluentBoards\Framework\Http\Request\Request;
18 use FluentBoards\App\Services\PermissionManager;
19 use FluentBoards\App\Hooks\Handlers\BoardHandler;
20 use FluentBoards\App\Services\LabelService;
21 use FluentBoards\Framework\Support\Arr;
22 use FluentBoards\Framework\Support\Collection;
23 use FluentCrm\App\Models\Subscriber;
24
25 class BoardController extends Controller
26 {
27 private $boardService;
28 private $taskService;
29 private $stageService;
30 private $labelService;
31
32 public function __construct(
33 BoardService $boardService,
34 TaskService $taskService,
35 StageService $stageService,
36 LabelService $labelService
37 )
38 {
39 parent::__construct();
40 $this->boardService = $boardService;
41 $this->taskService = $taskService;
42 $this->stageService = $stageService;
43 $this->labelService = $labelService;
44 }
45
46 public function getBoards(Request $request)
47 {
48 $per_page = $request->getSafe('per_page', 'intval', 20);
49 $userId = get_current_user_id();
50 $type = $request->getSafe('type', 'sanitize_text_field', 'to-do');
51
52 $order = $request->getSafe('order', 'sanitize_text_field', 'created_at');
53 $orderBy = $request->getSafe('orderBy', 'sanitize_text_field', 'DESC');
54 $searchInput = $request->getSafe('searchInput', 'sanitize_text_field');
55
56 $relatedBoardsQuery = Board::where('type', $type)
57 ->byAccessUser($userId);
58 if (!empty($searchInput)) {
59 $relatedBoardsQuery = $relatedBoardsQuery->where('title', 'like', '%' . $searchInput . '%');
60 }
61
62 $relatedBoards = $relatedBoardsQuery->orderBy($order, $orderBy)
63 ->withCount('completedTasks')
64 ->with('stages', 'users')
65 ->paginate($per_page);
66
67 foreach ($relatedBoards as $relatedBoard) {
68 $relatedBoard->users = Helper::sanitizeUserCollections($relatedBoard->users);
69 }
70
71 return $this->sendSuccess([
72 'boards' => $relatedBoards
73 ], 200);
74 }
75
76 public function getBoardsList(Request $request)
77 {
78 try {
79 $userId = get_current_user_id();
80 $type = $request->getSafe('type', 'sanitize_text_field', 'to-do');
81
82 if (PermissionManager::isAdmin($userId)) {
83 $relatedBoardsQuery = Board::query()->where('type', $type);
84 } else {
85 $currentUser = User::find($userId);
86 $relatedBoardsQuery = $currentUser->whichBoards()->where('type', $type);
87 }
88
89 $relatedBoards = $relatedBoardsQuery->with('stages')->get();
90 $stages = Stage::whereIn('board_id', $relatedBoards->pluck('id'))->get();
91
92 return $this->sendSuccess([
93 'boards' => $relatedBoards,
94 'all_stages' => $stages,
95 ], 200);
96 } catch (\Exception $e) {
97 return $this->sendError($e->getMessage(), 404);
98 }
99 }
100
101 public function getRecentBoards()
102 {
103 $boards = $this->boardService->getRecentBoards();
104
105 if (!$boards || $boards->isEmpty()) {
106 $boards = Board::where('type', 'to-do')->byAccessUser(get_current_user_id())
107 ->limit(4)
108 ->with(['stages', 'users'])
109 ->get();
110 }
111
112 foreach ($boards as $board) {
113 $board->users = Helper::sanitizeUserCollections($board->users);
114 }
115
116 return [
117 'boards' => $boards,
118 ];
119 }
120
121 public function getBoardMeta($board_id)
122 {
123 $boards = $this->boardService->fetchBoardMeta($board_id);
124
125 return $this->sendSuccess([
126 'boards' => $boards,
127 ], 200);
128 }
129
130 public function setAuthenticationPermission(Request $request, $board_id)
131 {
132 $boardData = $this->boardSanitizeAndValidate($request->only([
133 'is_auth_require_idea_submit',
134 'is_auth_require_voting_commenting',
135 'is_auth_require_reaction',
136 'is_allow_email_along_with_auth',
137 'is_allow_unauthentication_reaction_along_with_auth'
138 ]), [
139 'is_auth_require_idea_submit' => 'required',
140 'is_auth_require_voting_commenting' => 'required',
141 'is_auth_require_reaction' => 'required',
142 'is_allow_email_along_with_auth' => 'nullable',
143 'is_allow_unauthentication_reaction_along_with_auth' => 'nullable'
144 ]);
145
146 try {
147 $boards = $this->boardService->modifyAuthenticationPermission($boardData, $board_id);
148
149 return $this->sendSuccess([
150 'message' => __("Board has been updated", 'fluent-boards'),
151 'boards' => $boards,
152 ], 200);
153 } catch (\Exception $e) {
154 return $this->sendError($e->getMessage(), 404);
155 }
156 }
157
158 public function getBoardsByType($type)
159 {
160 $boards = $this->boardService->getBoardsByType($type);
161
162 return $this->sendSuccess([
163 'boards' => $boards,
164 ], 200);
165 }
166
167 public function createFirstBoard(Request $request)
168 {
169 $boardData = $this->boardSanitizeAndValidate($request->get('board'), [
170 'title' => 'required|string',
171 'description' => 'nullable',
172 'type' => 'required|string',
173 'currency' => 'nullable|string',
174 'crm_contact_id' => 'nullable|numeric',
175 ]);
176
177 $postStages = $request->get('stages');
178 $stageData = array();
179 foreach ($postStages as $stage) {
180 $temp = $this->stageSanitizeAndValidate($stage, [
181 'title' => 'required|string',
182 ]);
183 $stageData[] = $temp;
184 }
185
186 $taskData = null;
187 if ($request->get('task')) {
188 $taskData = $this->taskSanitizeAndValidate($request->get('task'), [
189 'title' => 'required|string'
190 ]);
191 }
192
193 $board = $this->boardService->createBoard($boardData);
194 $this->labelService->createDefaultLabel($board->id);
195 $type = ucfirst($boardData['type']);
196 $stage = $this->stageService->createStages($board, $stageData);
197
198 if ($taskData) {
199 $taskData['board_id'] = $board->id;
200 $taskData['stage_id'] = $stage->id;
201 $this->taskService->createTask($taskData, $board->id);
202 }
203
204 do_action('fluent_boards/board_created', $board);
205
206 return [
207 'message' => __('Board has been created', 'fluent-boards'),
208 'board' => $board,
209 ];
210 }
211
212 public function create(Request $request)
213 {
214 $boardData = $this->boardSanitizeAndValidate($request->get('board'), [
215 'title' => 'required|string',
216 'description' => 'nullable',
217 'type' => 'required|string',
218 'currency' => 'nullable|string',
219 'crm_contact_id' => 'nullable|numeric',
220 ]);
221
222 try {
223 $board = $this->boardService->createBoard($boardData);
224 $this->labelService->createDefaultLabel($board->id);
225 $type = ucfirst($boardData['type']);
226
227 if (isset($boardData['is_roadmap']) && $boardData['is_roadmap'] == 'yes') {
228 $this->stageService->createRoadmapStages($board, $boardData['stages']);
229 } else {
230 $this->stageService->createDefaultStages($board);
231 }
232
233 // if board is created from crm contact
234 if (isset($boardData['crm_contact_id'])) {
235 $this->boardService->updateAssociateMember($boardData['crm_contact_id'], $board->id);
236 }
237
238 do_action('fluent_boards/board_created', $board);
239
240 $message = __('Board has been created successfully', 'fluent-boards');
241
242 return $this->sendSuccess([
243 'message' => $message,
244 'board' => $board,
245 ], 201);
246 } catch (\Exception $e) {
247 return $this->sendError($e->getMessage(), 400);
248 }
249 }
250
251 public function getArchivedStage(Request $request, $board_id)
252 {
253 try {
254 $pagination = $request->noPagination ? true : false;
255 $per_page = isset($data['per_page']) ? $data['per_page'] : 30;
256 $page = isset($data['page']) ? $data['page'] : 1;
257 if ($pagination) {
258 $stages = Stage::where('board_id', $board_id)
259 ->whereNotNull('archived_at')
260 ->orderBy('created_at', 'DESC')
261 ->get();
262 } else {
263 $stages = Stage::where('board_id', $board_id)
264 ->whereNotNull('archived_at')
265 ->orderBy('created_at', 'DESC')
266 ->paginate($per_page, ['*'], 'page', $page);
267 }
268
269 return $this->sendSuccess([
270 'stages' => $stages,
271 ], 200);
272 } catch (\Exception $e) {
273 return $this->sendError($e->getMessage(), 404);
274 }
275 }
276
277 public function find($board_id)
278 {
279 $board = Board::findOrFail($board_id);
280 $board->background = maybe_unserialize($board->background);
281 $board->createdOn = $board->created_at->format('Y-m-d');
282
283 $board->load(['users', 'stages', 'labels', 'owner']);
284 $this->boardService->updateRecentOpenedBoards($board_id);
285
286 $board->labelColor = Constant::TRELLO_COLOR_MAP;
287 $board->labelColorText = Constant::TEXT_COLOR_MAP;
288
289 $board->users = Helper::sanitizeUserCollections($board->users);
290 $board->owner = Helper::sanitizeUserCollections($board->owner);
291
292 $board = apply_filters('fluent_boards/board_find', $board);
293
294 return [
295 'board' => $board
296 ];
297 }
298
299 public function update(Request $request, $board_id)
300 {
301 $boardData = $this->boardSanitizeAndValidate($request->only(['title', 'description']), [
302 'title' => 'required|string',
303 'description' => 'nullable|string',
304 ]);
305
306 $board = Board::findOrFail($board_id);
307
308 $oldBoard = clone $board;
309 $board->fill($boardData);
310 $board->save();
311
312 do_action('fluent_boards/board_updated', $board, $oldBoard);
313
314 return [
315 'stages' => $board->stages()->get(),
316 'message' => __('Board has been updated', 'fluent-boards'),
317 'board' => $board,
318 ];
319 }
320
321 public function archiveStage($board_id, $stage_id)
322 {
323 try {
324 $stage = Stage::findOrFail($stage_id);
325 $board = Board::findOrFail($stage->board_id);
326
327 $updatedStage = $this->boardService->archiveStage($board->id, $stage);
328
329 return $this->sendSuccess([
330 'updatedStage' => $updatedStage,
331 'message' => __('Stage has been archived', 'fluent-boards'),
332 ], 200);
333 } catch (\Exception $e) {
334 return $this->sendError($e->getMessage(), 400);
335 }
336 }
337
338 public function restoreStage($board_id, $stage_id)
339 {
340 try {
341 $stage = Stage::findOrFail($stage_id);
342 $board = Board::findOrFail($board_id);
343
344 $updatedStage = $this->boardService->restoreStage($board->id, $stage);
345
346 return $this->sendSuccess([
347 'success' => true,
348 'updatedStage' => $updatedStage,
349 'message' => __('Stage has been restored', 'fluent-boards')
350 ], 200);
351 } catch (\Exception $e) {
352 return $this->sendError($e->getMessage(), 400);
353 }
354 }
355
356
357 public function changePositionOfStage(Request $request, $board_id)
358 {
359 $changeData = $this->boardSanitizeAndValidate($request->only(['fromPosition', 'toPosition']), [
360 'fromPosition' => 'required',
361 'toPosition' => 'required',
362 ]);
363
364 try {
365 $this->boardService->changePositionOfStage($board_id, $changeData);
366
367 return $this->sendSuccess([
368 'message' => __('Board stage has been updated', 'fluent-boards')
369 ], 200);
370 } catch (\Exception $e) {
371 return $this->sendError($e->getMessage(), 400);
372 }
373 }
374
375 public function rePositionStages(Request $request, $board_id)
376 {
377 $incomingList = $request->get('list');
378 try {
379 $this->boardService->rePositionStages($board_id, $incomingList);
380 return $this->sendSuccess([
381 'message' => __('Stages Reordered', 'fluent-boards'),
382 'updatedStages' => $this->stageService->getLastOneMinuteUpdatedStages($board_id)
383 ], 200);
384 } catch (\Exception $e) {
385 return $this->sendError($e->getMessage(), 400);
386 }
387 }
388
389 public function getAssigneesByBoard($board_id)
390 {
391 return $this->sendSuccess([
392 'data' => $this->boardService->getAssigneesByBoard($board_id),
393 ], 200);
394 }
395
396 public function delete($board_id)
397 {
398 try {
399 if (!PermissionManager::isAdmin()) {
400 throw new \Exception('You do not have permission to delete this board', 400);
401 }
402 $this->boardService->deleteBoard($board_id);
403
404 return $this->sendSuccess([
405 'message' => __('Board has been deleted', 'fluent-boards'),
406 ], 200);
407 } catch (\Exception $e) {
408 return $this->sendError($e->getMessage(), 400);
409 }
410 }
411
412 public function getCurrencies()
413 {
414 return BoardHandler::getCurrencies();
415 }
416
417 public function getActivities(Request $request, $board_id)
418 {
419 try {
420 $activities = $this->boardService->getActivities($board_id, $request->all());
421 return $this->sendSuccess([
422 'activities' => $activities,
423 ], 200);
424 } catch (\Exception $e) {
425 return $this->sendError($e->getMessage(), 404);
426 }
427 }
428
429 public function getBoardUsers($board_id)
430 {
431 $board = Board::findOrFail($board_id);
432
433 $boardObjects = Relation::where('object_type', 'board_user')
434 ->where('object_id', $board_id)
435 ->get()->keyBy('foreign_id');
436
437 $userIds = $boardObjects->pluck('foreign_id')->toArray();
438
439 $coreUsers = [];
440 if ($userIds) {
441 // Get the users who are in the board (members and managers
442 $coreUsers = get_users([
443 'include' => $userIds
444 ]);
445 }
446
447 $formattedUsers = [];
448
449 foreach ($coreUsers as $user) {
450 $name = trim($user->first_name . ' ' . $user->last_name);
451 if (!$name) {
452 $name = $user->display_name;
453 }
454
455 $boardRelation = $boardObjects[$user->ID] ?? null;
456
457 $formattedUsers[] = [
458 'ID' => $user->ID,
459 'display_name' => $name,
460 'email' => $user->user_email,
461 'photo' => fluent_boards_user_avatar($user->user_email, $name),
462 'role' => $boardRelation && $boardRelation->settings['is_admin'] ? 'manager' : 'member'
463 ];
464 }
465
466 // order formatted users by display_name
467 usort($formattedUsers, function ($a, $b) {
468 return strcmp($a['display_name'], $b['display_name']);
469 });
470
471 $returnData = [
472 'users' => Helper::sanitizeUsersArray($formattedUsers),
473 'global_admins' => []
474 ];
475
476 if (!PermissionManager::isAdmin(get_current_user_id())) {
477 return $returnData;
478 }
479
480 /*
481 * These are the rest of the admin users who are not in the board
482 */
483 $adminUserIds = Meta::query()->where('object_type', Constant::FLUENT_BOARD_ADMIN)
484 ->whereNotIn('object_id', $userIds)
485 ->get()
486 ->pluck('object_id')
487 ->toArray();
488
489 if ($adminUserIds) {
490 $adminUsers = get_users([
491 'include' => $adminUserIds,
492 ]);
493
494 $formattedAdminUsers = [];
495
496 foreach ($adminUsers as $user) {
497 $name = trim($user->first_name . ' ' . $user->last_name);
498 if (!$name) {
499 $name = $user->display_name;
500 }
501
502 $formattedAdminUsers[] = [
503 'ID' => $user->ID,
504 'display_name' => $name,
505 'email' => $user->user_email,
506 'photo' => fluent_boards_user_avatar($user->user_email, $name),
507 'role' => 'admin'
508 ];
509 }
510
511 // order formatted users by display_name
512 usort($formattedAdminUsers, function ($a, $b) {
513 return strcmp($a['display_name'], $b['display_name']);
514 });
515
516 $returnData['global_admins'] = Helper::sanitizeUsersArray($formattedAdminUsers);
517 }
518
519 return $this->sendSuccess($returnData, 200);
520 }
521
522
523 public function removeUserFromBoard($board_id, $userId)
524 {
525 $this->boardService->removeUserFromBoard($board_id, $userId);
526
527 if (!PermissionManager::isAdmin($userId)) {
528 $this->boardService->removeFromRecentlyOpened($board_id, $userId);
529 }
530
531 return [
532 'message' => __('Member removed successfully', 'fluent-boards'),
533 ];
534 }
535
536 public function addMembersInBoard(Request $request, $board_id)
537 {
538 $memberId = $request->getSafe('memberId');
539 $isAlreadyMember = $this->boardService->isAlreadyMember($board_id, $memberId);
540
541 if ($isAlreadyMember) {
542 return $this->sendError([
543 'message' => __('User already a member', 'fluent-boards'),
544 ], 304);
545 }
546 $member = $this->boardService->addMembersInBoard($board_id, $memberId);
547
548 return [
549 'message' => __('Member added successfully', 'fluent-boards'),
550 'member' => Helper::sanitizeUserCollections($member)
551 ];
552 }
553
554 private function boardSanitizeAndValidate($data, array $rules = [])
555 {
556 $data = Helper::sanitizeBoard($data);
557
558 return $this->validate($data, $rules);
559 }
560
561 private function stageSanitizeAndValidate($data, array $rules = [])
562 {
563 $data = Helper::sanitizeStage($data);
564
565 return $this->validate($data, $rules);
566 }
567
568 private function taskSanitizeAndValidate($data, array $rules = [])
569 {
570 $data = Helper::sanitizeTask($data);
571
572 return $this->validate($data, $rules);
573 }
574
575 public function searchBoards(Request $request)
576 {
577 $per_page = $request->get('per_page', 10);
578 $search_input = $request->searchInput . trim('');
579 $type = $request->type;
580
581 $currentUserId = get_current_user_id();
582
583 if (PermissionManager::isAdmin($currentUserId)) {
584 $boards = Board::query()->where('type', $type)
585 ->where('title', 'like', '%' . $search_input . '%')
586 ->with('stages', 'tasks', 'users')
587 ->paginate($per_page);
588
589 foreach ($boards as $board) {
590 $board->users = Helper::sanitizeUserCollections($board->users);
591 }
592
593 } else {
594 $currentUser = User::find($currentUserId);
595 $boards = $currentUser->boards()->where('type', $type)->where('title', 'like', '%' . $search_input . '%')->paginate($per_page);
596 }
597
598 return [
599 'boards' => $boards,
600 ];
601 }
602
603 public function getUsersOfBoards()
604 {
605 $userBoards = $this->boardService->getUsersOfBoards();
606
607 return $this->sendSuccess([
608 'userBoards' => $userBoards,
609 ], 200);
610 }
611
612
613
614 /**
615 * Refactor this code form me - Masiur
616 * change stage settings is_public for roadmap user and admin view
617 * @param $board_id
618 * @param $stage_id
619 * @return
620 */
621 public function changeStageView($board_id, $stage_id)
622 {
623 try {
624 $stage = Stage::findOrFail($stage_id);
625 $message = __('The stage is made public!', 'fluent-boards');
626 $settings = $stage->settings;
627
628 if (isset($settings['is_public'])) {
629 if ($settings['is_public']) {
630 $settings['is_public'] = false;
631 $message = __('The stage is made admin only!', 'fluent-boards');
632 } else {
633 $settings['is_public'] = true;
634 }
635 } else {
636 $settings['is_public'] = true;
637 }
638
639 $stage->settings = $settings;
640 $stage->save();
641 return $this->sendSuccess([
642 'message' => $message,
643 'stage' => $stage
644 ]);
645 } catch (\Exception $e) {
646 return $this->sendError($e->getMessage(), 400);
647 }
648 }
649
650
651 /**
652 * Set board background image or color
653 * @param \FluentBoards\Framework\Http\Request\Request $request
654 * @return
655 */
656 public function setBoardBackground(Request $request, $board_id)
657 {
658 // sanitize and validate image_url
659 if ($request->image_url) {
660 $backgroundData = $this->boardSanitizeAndValidate($request->all(), [
661 "id" => 'required',
662 'image_url' => 'required|string|url',
663 ]);
664 }
665
666 // sanitize and validate color
667 if ($request->color) {
668 $backgroundData = $this->boardSanitizeAndValidate($request->all(), [
669 "id" => 'required',
670 'color' => 'required',
671 ]);
672 }
673
674 try {
675 if (!$board_id) {
676 $errorMessage = __('Board id is required', 'fluent-boards');
677 throw new \Exception($errorMessage, 400);
678 }
679
680 return $this->sendSuccess([
681 'message' => __('Background updated successfully', 'fluent-boards'),
682 'background' => $this->boardService->setBoardBackground($backgroundData, $board_id),
683 ]);
684 } catch (\Exception $e) {
685 $this->sendError([$e->getMessage(), 400]);
686 }
687 }
688
689
690 /**
691 * Summary of getStageTaskAvailablePositions
692 * @param mixed $board_id
693 * @param mixed $stage_slug
694 * @return $availablePositions as an array
695 * @throws \Exception
696 */
697 public function getStageTaskAvailablePositions($board_id, $stage_id)
698 {
699 try {
700 if ($board_id && $stage_id) {
701 $availablePositions = $this->boardService->getStageTaskAvailablePositions($board_id, $stage_id);
702 return $this->sendSuccess([
703 'availablePositions' => $availablePositions
704 ], 200);
705 } else {
706 $message = '';
707 if (!$board_id) {
708 $message = 'Board id ';
709 }
710 if (!$stage_id) {
711 $message = 'Stage ';
712 }
713 throw new \Exception($message . 'is required', 400);
714 }
715 } catch (\Exception $e) {
716 $this->sendError([$e->getMessage(), 400]);
717 }
718 }
719
720 public function getAssociateCrmContacts($board_id)
721 {
722 try {
723 $contactAssociatedTasks = Task::with('board')->where('board_id', $board_id)
724 ->whereNotNull('crm_contact_id')
725 ->get();
726
727 $formattedContacts = Collection::make($contactAssociatedTasks)
728 ->groupBy('crm_contact_id')
729 ->map(function ($tasks, $contactId) {
730 $subscriber = Subscriber::find($contactId);
731 if (!$subscriber) {
732 return null; // Skip if subscriber not found
733 }
734
735 return [
736 'name' => $subscriber->first_name . ' ' . $subscriber->last_name,
737 'photo' => $subscriber->photo,
738 'email' => $subscriber->email,
739 'crm_contact_id' => $contactId,
740 'id' => $contactId,
741 'tasks' => $tasks,
742 ];
743 })
744 ->filter()->toArray();
745
746
747 return $this->sendSuccess([
748 'associatedContacts' => $formattedContacts
749 ], 200);
750 } catch (\Exception $e) {
751 return $this->sendError($e->getMessage(), 404);
752 }
753 }
754
755 public function updateAssociateCrmContact(Request $request, $board_id)
756 {
757 $value = $request->getSafe('value');
758 $this->boardService->updateAssociateMember($value, $board_id);
759
760 return $this->sendSuccess([
761 'message' => __('Associated Crm Member has been updated', 'fluent-boards'),
762 ], 200);
763 }
764
765 public function hasDataChanged($board_id)
766 {
767 return $this->boardService->hasDataChanged($board_id);
768 }
769
770 public function createStage(Request $request, $board_id)
771 {
772 $stageData = $this->stageSanitizeAndValidate($request->all(), [
773 'title' => 'required|string',
774 ]);
775
776 $board = Board::find($board_id);
777 $stage = $this->stageService->createStage($stageData, $board_id);
778
779 do_action('fluent_boards/board_stage_added', $board, $stage);
780
781 $updatedStates = (new StageService())->getLastOneMinuteUpdatedStages($board_id);
782
783 return [
784 'updatedStages' => $updatedStates,
785 'message' => __('stage has been created', 'fluent-boards'),
786 ];
787 }
788
789 public function sortStageTasks(Request $request, $board_id, $stage_id)
790 {
791 $sort = $request->getSafe('sort', 'sanitize_text_field');
792
793 $updatedTasks = $this->stageService->sortStageTasks($sort, $stage_id);
794 return [
795 'message' => __('Tasks has been sorted', 'fluent-boards'),
796 'updatedTasks' => $updatedTasks,
797 ];
798 }
799
800 public function moveAllTasks(Request $request, $board_id)
801 {
802 $oldStageId = $request->getSafe('oldStageId');
803 $newStageId = $request->getSafe('newStageId');
804
805 $updates = $this->stageService->moveAllTasks($oldStageId, $newStageId, $board_id);
806
807 return [
808 'message' => __('Tasks has been Moved', 'fluent-boards'),
809 'updatedTasks' => $updates,
810 ];
811
812 }
813
814 public function archiveAllTasksInStage($board_id, $stage_id)
815 {
816 $updates = $this->stageService->archiveAllTasksInStage($stage_id);
817 return [
818 'message' => __('Tasks has been archived', 'fluent-boards'),
819 'updatedTasks' => $updates,
820 ];
821 }
822
823 public function getAssociatedBoards(Request $request, $associated_id)
824 {
825 $associatedBoards = $this->boardService->getAssociatedBoards($associated_id);
826 return [
827 'boards' => $associatedBoards,
828 ];
829 }
830
831 public function duplicateBoard(Request $request, $board_id)
832 {
833 $boardData = $this->taskSanitizeAndValidate($request->get('board'), [
834 'title' => 'required|string'
835 ]);
836 $isWithLabels = $request->getSafe('isWithLabels');
837 $isWithTasks = $request->getSafe('isWithTasks');
838
839 try {
840 if(!PermissionManager::isAdmin()) {
841 $errorMessage = __('You do not have permission to duplicate board', 'fluent-boards');
842 throw new \Exception($errorMessage, 400);
843 }
844 //create board
845 $newBoard = $this->boardService->copyBoard($boardData);
846
847 //label copy
848 if ($isWithLabels == 'yes') {
849 $this->labelService->copyLabelsOfBoard($board_id, $newBoard);
850 }
851
852 //stage copy
853 $stageMapForCopyingTask = $this->stageService->copyStagesOfBoard($newBoard, $board_id);
854
855 //copy tasks of selected stages
856 if ($isWithTasks == 'yes') {
857 $this->taskService->copyTasks($board_id, $stageMapForCopyingTask, $newBoard);
858 }
859
860 return $this->sendSuccess([
861 'board' => $newBoard,
862 ], 200);
863 } catch (\Exception $e) {
864 return $this->sendError($e->getMessage(), 400);
865 }
866 }
867
868 public function importFromBoard(Request $request, $board_id)
869 {
870 $selectedStages = $request->getSafe('selectedStages');
871
872 try {
873 $this->stageService->importStagesFromBoard($board_id, $selectedStages);
874
875 return $this->sendSuccess([
876 'message' => __('Import successfully', 'fluent-boards'),
877 ], 200);
878
879 } catch (\Exception $e) {
880 return $this->sendError($e->getMessage(), 400);
881 }
882 }
883
884 public function getBoardDefaultBackgroundColors()
885 {
886 return [
887 'solidColors' => Constant::BOARD_BACKGROUND_DEFAULT_SOLID_COLORS,
888 'gradients' => Constant::BOARD_BACKGROUND_DEFAULT_GRADIENT_COLORS
889 ];
890 }
891
892 }
893