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

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