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 / Services / StageService.php

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

435 lines 14.1 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\Task;
6 use FluentBoards\App\Models\Board;
7 use FluentBoards\App\Models\Stage;
8 use FluentBoards\Framework\Http\Request\Request;
9 use FluentBoards\Framework\Support\Arr;
10
11 class StageService
12 {
13 public function createDefaultStages($board)
14 {
15 $stages = $this->defaultStages($board);
16 foreach ($stages as $stage) {
17 Stage::create($stage);
18 }
19 }
20
21 public function defaultStages($board)
22 {
23 return $this->defaultStagesForTodos($board->id);
24 }
25
26 public function defaultStagesForTodos($boardId)
27 {
28 return [
29 [
30 'board_id' => $boardId,
31 'title' => 'Open',
32 'position' => 1,
33 'slug' => 'open',
34 'settings' => [
35 'default_task_status' => 'open'
36 ]
37 ],
38 [
39 'board_id' => $boardId,
40 'title' => 'In Progress',
41 'position' => 2,
42 'slug' => 'in-progress',
43 'settings' => [
44 'default_task_status' => 'open'
45 ]
46 ],
47 [
48 'board_id' => $boardId,
49 'title' => 'Completed',
50 'position' => 3,
51 'slug' => 'completed',
52 'settings' => [
53 'default_task_status' => 'closed'
54 ]
55 ]
56 ];
57 }
58 public function updateStageProperty($col, $value, $stageId)
59 {
60 $stage = Stage::findOrFail($stageId);
61
62 if ('title' == $col) {
63 $this->updateTitle($value, $stage);
64 } elseif ('status' == $col) {
65 $this->updateStatus($value, $stage);
66 } elseif ('color' == $col) {
67 $this->updateColor($value, $stage);
68 } elseif ('bg_color' == $col) {
69 $this->updateBackgroundColor($value, $stage);
70 } elseif ('archived_at' == $col) {
71 $this->updateArchivedAt($value, $stage);
72 }
73 return $stage;
74 }
75
76 public function getLastOneMinuteUpdatedStages($boardId)
77 {
78 $oneMinuteAgoTimestamp = current_time('timestamp') - 60;
79 return Stage::where('board_id', $boardId)
80 ->where('updated_at', '>=', date_i18n('Y-m-d H:i:s', $oneMinuteAgoTimestamp))
81 ->get();
82 }
83
84 private function updateTitle($value, $stage)
85 {
86
87 }
88
89 private function updateStatus($value, $stage)
90 {
91 $oldSettings = $stage->settings;
92 $oldSettings['default_task_status'] = $value;
93 $stage->settings = $oldSettings;
94 $stage->save();
95 }
96
97 private function updateColor($value, $stage)
98 {
99
100 }
101
102 private function updateBackgroundColor($value, $stage)
103 {
104
105 }
106
107 private function updateArchivedAt($value, $stage)
108 {
109
110 }
111
112 public function createStage($stageData, $boardId)
113 {
114 $stage = new Stage();
115 $stage->board_id = $boardId;
116 $stage->title = $stageData['title'];
117 $stage->settings = [
118 'default_task_status' => Arr::get($stageData, 'status') ?? 'open'
119 ];
120 if (!Arr::get($stageData, 'position')) {
121 $lastStagePosition = $this->getLastPositionOfStagesOfBoard($boardId);
122 $stage->position = $lastStagePosition ? $lastStagePosition->position + 1 : 1;
123 $stage->save();
124 } else {
125 $stage->position = (int)$stageData['position'];
126 $stage->save();
127 $this->moveOtherStages($stage);
128 }
129
130 return $stage;
131 }
132
133 public function getLastPositionOfStagesOfBoard($boardId)
134 {
135 // return last position of stages of board
136 return Stage::where('board_id', $boardId)
137 ->whereNull('archived_at')
138 ->orderBy('position', 'desc')
139 ->first();
140 }
141
142 protected function moveOtherStages($stage)
143 {
144
145 $stages = Stage::where('board_id', $stage->board_id)
146 ->where('position', '>=', $stage->position)
147 ->whereNotIn('id', [$stage->id])
148 ->whereNull('archived_at')->get();
149
150 foreach ($stages as $stage) {
151 $stage->position = $stage->position + 1;
152 $stage->save();
153 }
154 }
155
156 public function copyStagesOfBoard($board, $fromBoardId)
157 {
158 $stages = Stage::where('board_id', $fromBoardId)->where('type', 'stage')->whereNull('archived_at')->get();
159 $stageMapForCopyingTask = array();
160 foreach($stages as $key => $stage)
161 {
162 $stageToSave = array();
163 $stageToSave['title'] = $stage['title'];
164 $stageToSave['board_id'] = $board->id;
165 $stageToSave['slug'] = str_replace(' ', '-', strtolower($stage['title']));
166 $stageToSave['type'] = 'stage';
167 $stageToSave['position'] = $key + 1;
168 $stageToSave['settings'] = [
169 'default_task_status' => $stage->settings['default_task_status']
170 ];
171 $newStage = Stage::create($stageToSave);
172 $stageMapForCopyingTask[$stage['id']] = $newStage->id;
173 }
174 return $stageMapForCopyingTask;
175 }
176
177 public function importStagesFromBoard($board_id, $selectedStages)
178 {
179 $targetStages = Stage::whereIn('id', $selectedStages)->get();
180 $stageMapForCopyingTask = array();
181 $stageIdsToCopy = array();
182
183 //need to define position of stage
184 $numberOfStages = Stage::where('board_id', $board_id)->whereNull('archived_at')->count();
185
186 foreach($targetStages as $key => $stage)
187 {
188 $stageToSave = array();
189 $stageToSave['title'] = $stage['title'] . ' - imported';
190 $stageToSave['board_id'] = $board_id;
191 $stageToSave['slug'] = str_replace(' ', '-', strtolower($stage['title']));
192 $stageToSave['type'] = 'stage';
193 $stageToSave['position'] = $numberOfStages + $key + 1;
194 $stageToSave['settings'] = [
195 'default_task_status' => $stage->settings['default_task_status']
196 ];
197 $newStage = Stage::create($stageToSave);
198 $stageMapForCopyingTask[$stage['id']] = $newStage->id;
199 $stageIdsToCopy[] = $stage['id'];
200 }
201
202 $this->importTasks($board_id, $stageMapForCopyingTask, $stageIdsToCopy);
203 }
204
205 public function importTasks($boardId, $stageMapper, $stageIds)
206 {
207 $tasksToImport = Task::whereIn('stage_id', $stageIds)->whereNull('archived_at')->get();
208
209 foreach($tasksToImport as $task)
210 {
211 $newTask = array();
212 $newTask['title'] = $task->title;
213 $newTask['description'] = $task->description;
214 $newTask['board_id'] = $boardId;
215 $newTask['stage_id'] = $stageMapper[$task->stage_id];
216 $newTask['status'] = $task->status;
217 $newTask['priority'] = $task->priority;
218 $newTask['position'] = $task->position;
219 $newTask['due_at'] = $task->due_at;
220 Task::create($newTask);
221 }
222
223 //update task count of board
224 $totalTasks = sizeof($tasksToImport);
225 $board = Board::findOrFail($boardId);
226 $settings = $board->settings ?? [];
227
228 if (isset($settings['tasks_count'])) {
229 $settings['tasks_count'] += $totalTasks;
230 } else {
231 $settings['tasks_count'] = $totalTasks;
232 }
233 $board->settings = $settings;
234 $board->save();
235 }
236
237 public function updateStageTemplate($stage_id)
238 {
239 $stage = Stage::findOrFail($stage_id);
240 $stageSettings = $stage->settings;
241 if($stageSettings && array_key_exists('is_template', $stageSettings))
242 {
243 $currentlyIsTemplate = $stageSettings['is_template'];
244 if($currentlyIsTemplate){
245 $stageSettings['is_template'] = false;
246 $stage->settings = $stageSettings;
247 }else{
248 $stageSettings['is_template'] = true;
249 $stage->settings = $stageSettings;
250 }
251 }else {
252 if(!$stageSettings) {
253 $stage->settings = [
254 'is_template' => true
255 ];
256 } else {
257 $stage->settings = array_merge($stage->settings, [
258 'is_template' => true
259 ]);
260 }
261
262 }
263 $stage->save();
264
265 return $stage;
266 }
267
268 public function moveAllTasks($oldStageId, $newStageId)
269 {
270 $tasks = Task::where('stage_id', $oldStageId)->whereNull('parent_id')->whereNull('archived_at')->get();
271
272 // get the last position available of that stage
273 $position = (new TaskService())->getLastPositionOfTasks($newStageId);
274
275 // update tasks stage and position
276 foreach ($tasks as $key => $task) {
277 $task->stage_id = $newStageId;
278 $task->position = $position + $key;
279 $task->save();
280 }
281 return $tasks;
282 }
283 public function archiveAllTasksInStage($stage_id)
284 {
285 $tasks = Task::where('stage_id', $stage_id)->whereNull('parent_id')->whereNull('archived_at')->get();
286 foreach ($tasks as $task) {
287 $task->position = 0;
288 $task->archived_at = current_time('mysql');
289 $task->save();
290 do_action('fluent_boards/board_task_archived', $task);
291 }
292 return $tasks;
293 }
294
295 public function createRoadmapStages($board, $stagesData)
296 {
297 foreach ($stagesData as $formStageData) {
298 $stage = new Stage();
299 $stage->board_id = $board->id;
300 $stage->title = $formStageData['title'];
301 $stage->slug = $formStageData['slug'];
302 $stage->position = $formStageData['position'] ? $formStageData['position'] : 1;
303 $stage->settings = $this->roadmapStageSetting();
304 $stage->save();
305 }
306 return $stagesData;
307 }
308
309 /*
310 * I have no idea what this function does, but I am doing it
311 * to make the code work
312 */
313 public function roadmapStageSetting()
314 {
315 return [
316 'is_public' => true,
317 'default_task_status' => 'open',
318 'is_template' => false,
319 ];
320 }
321
322
323 public function createStages($board, $stageData)
324 {
325 $firstStage = null;
326 foreach ($stageData as $index => $stage) {
327 $stageToPush = array();
328 $stageToPush['title'] = $stage['title'];
329 $stageToPush['board_id'] = $board->id;
330 $stageToPush['position'] = $index + 1;
331 $stageToPush['slug'] = $this->createSlug($stage['title']);
332
333 if (Arr::get($stage, 'title') == 'Completed') {
334 $stageToPush['settings'] = [
335 'default_task_status' => 'closed',
336 'is_template' => false
337 ];
338 }
339
340 $stage = Stage::create($stageToPush);
341 if($index == 0){
342 $firstStage = $stage;
343 }
344 }
345 return $firstStage;
346 }
347
348 private function createSlug($title)
349 {
350 return str_replace(' ', '-', strtolower($title));
351 }
352
353 public function stagesByBoardId($boardId)
354 {
355 return Stage::where('board_id', $boardId)->whereNull('archived_at')->get();
356 }
357
358
359
360 public function sortStageTasks($sortBy, $stage_id)
361 {
362 $tasksQuery = Task::where('stage_id', $stage_id)->whereNull('parent_id')->whereNull('archived_at')->with(['assignees', 'labels', 'watchers']);
363 if ($sortBy == 'newest') {
364 $tasksQuery->orderBy('created_at', 'desc');
365 } elseif ($sortBy == 'oldest') {
366 $tasksQuery->orderBy('created_at', 'asc');
367 } elseif ($sortBy == 'alphabetically') {
368 $tasksQuery->orderBy('title', 'asc');
369 } elseif ($sortBy == 'due_at_ascending') {
370 $tasksWithDueDate = $tasksQuery->whereNotNull('due_at')->orderBy('due_at')->get();
371
372 $tasksWithoutDueDate = Task::where('stage_id', $stage_id)
373 ->whereNull('parent_id')
374 ->whereNull('archived_at')
375 ->with(['assignees', 'labels', 'watchers'])
376 ->whereNull('due_at')->get();
377
378 $tasks = $tasksWithDueDate->merge($tasksWithoutDueDate);
379 } elseif ($sortBy == 'due_at_descending') {
380 $tasksQuery->orderBy('due_at', 'desc');
381 } elseif ($sortBy == 'priority_high_to_low') {
382 $tasksQuery->orderByRaw(
383 "FIELD(priority, 'High', 'Medium', 'Low') ASC"
384 );
385 } elseif ($sortBy == 'priority_low_to_high') {
386 $tasksQuery->orderByRaw(
387 "FIELD(priority, 'High', 'Medium', 'Low') DESC"
388 );
389 }
390
391 if ($sortBy != 'due_at_ascending'){
392 $tasks = $tasksQuery->get();
393 }
394
395 foreach ($tasks as $key => $task) {
396 $task->position = $key + 1;
397 $task->save();
398 }
399 foreach ($tasks as $task) {
400 $task->isOverdue = $task->isOverdue();
401 $task->isUpcoming = $task->upcoming();
402 $task->is_watching = $task->isWatching();
403 $task->contact = Task::lead_contact($task->crm_contact_id);
404 }
405 return $tasks;
406 }
407
408 public function checkStageEditable($stages, $toBeUpdatedStage)
409 {
410 $stageEditable = true;
411 if (empty(sanitize_text_field($toBeUpdatedStage['title']))) {
412 $stageEditable = false;
413 } else {
414 foreach ($stages as $stage) { // check if stage label is similar to any other stage label
415 if (strtolower($stage->title) == strtolower(trim($toBeUpdatedStage['title']))) {
416 $stageEditable = false;
417 break;
418 }
419 }
420 }
421
422 return $stageEditable;
423 }
424
425 public function updateStage($updatedStage, $board_id, $oldStage)
426 {
427 $oldTitle = $oldStage->title;
428 $oldStage->title = Arr::get($updatedStage, 'title');
429 $oldStage->bg_color = Arr::get($updatedStage, 'cover_bg');
430 $oldStage->save();
431 do_action('fluent_boards/board_stage_updated', $board_id, $updatedStage['title'], $oldTitle);
432 return $oldStage;
433 }
434 }
435