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.1 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 All 44 releases
fluent-boards / app / Hooks / Handlers / BoardHandler.php

BoardHandler.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.2.0, at app/Hooks/Handlers/BoardHandler.php

580 lines 19.5 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\Hooks\Handlers;
4
5 use FluentBoards\App\Models\Attachment;
6 use FluentBoards\App\Models\Comment;
7 use FluentBoards\App\Models\Meta;
8 use FluentBoards\App\Models\NotificationUser;
9 use FluentBoards\App\Models\Relation;
10 use FluentBoards\App\Models\Stage;
11 use FluentBoards\App\Models\Task;
12 use FluentBoards\App\Models\Board;
13 use FluentBoards\App\Models\User;
14 use FluentBoards\App\Services\Constant;
15 use FluentBoards\App\Services\BoardService;
16 use FluentBoards\App\Services\Helper;
17
18 class BoardHandler
19 {
20 public function createLogActivity($boardId, $action, $column = null, $oldValue = null, $newValue = null, $description = null, $settings = null, $userId = null )
21 {
22 $data = [
23 'object_type' => Constant::ACTIVITY_BOARD,
24 'object_id' => $boardId,
25 'action' => $action, // action type: changed, updated, added, removed, created
26 'column' => $column,
27 'old_value' => $oldValue,
28 'new_value' => $newValue,
29 'description' => $description,
30 'settings' => $settings
31 ];
32 if($userId) {
33 $data['created_by'] = $userId;
34 }
35
36 Helper::createActivity($data);
37 }
38 /** Record the creation of a board's custom-field definition. */
39 public function customFieldCreated($customField)
40 {
41 $this->createLogActivity(
42 $customField->board_id,
43 Constant::ACTIVITY_ACTION_CREATED,
44 Constant::ACTIVITY_CUSTOM_FIELD,
45 null,
46 $customField->title,
47 null,
48 ['custom_field_id' => $customField->id, 'custom_field_type' => $customField->settings['custom_field_type']]
49 );
50 }
51
52 /** Record changed names and options using snapshots taken before the definition was saved. */
53 public function customFieldUpdated($customField, $oldCustomField)
54 {
55 $settings = [
56 'custom_field_id' => $customField->id,
57 'custom_field_title' => $customField->title,
58 'custom_field_type' => $customField->settings['custom_field_type']
59 ];
60 if ($oldCustomField->title !== $customField->title) {
61 $this->createLogActivity($customField->board_id, Constant::ACTIVITY_ACTION_UPDATED,
62 Constant::ACTIVITY_CUSTOM_FIELD, $oldCustomField->title, $customField->title, null, $settings);
63 }
64
65 $oldOptions = $oldCustomField->settings['select_options'] ?? [];
66 $newOptions = $customField->settings['select_options'] ?? [];
67 if ($oldOptions !== $newOptions) {
68 $this->createLogActivity($customField->board_id, Constant::ACTIVITY_ACTION_UPDATED,
69 /* translators: %s is the custom field title */
70 sprintf(__('custom field options for %s', 'fluent-boards'), $customField->title),
71 $oldOptions ? implode(', ', $oldOptions) : __('empty', 'fluent-boards'),
72 $newOptions ? implode(', ', $newOptions) : __('empty', 'fluent-boards'),
73 null, $settings);
74 }
75 }
76
77 public function getAllBoards($sortBy = 'ASC')
78 {
79 $boards = Board::orderBy('created_at', $sortBy)->get();
80
81 return [
82 'boards' => $boards,
83 ];
84 }
85
86 public function attachFolderToBoard($board)
87 {
88 $board->folder = (new BoardService())->getBoardFolder($board->id);
89
90 return $board;
91 }
92
93 public function boardCreated($board)
94 {
95 $boardId = $board->id;
96 $this->createLogActivity($boardId, 'created', 'board', null, null, $board->title);
97 $this->updateOnboarding();
98 }
99
100 /**
101 * Log a system activity without allowing a non-critical log failure to fail the automation.
102 *
103 * @param Board $board
104 * @return void
105 */
106 public function boardCreatedFromAutomation($board)
107 {
108 $previousUserId = get_current_user_id();
109
110 try {
111 wp_set_current_user(0);
112
113 $this->createLogActivity(
114 $board->id,
115 'created',
116 'board',
117 null,
118 null,
119 null,
120 ['source' => 'fluentcrm_automation']
121 );
122 } catch (\Throwable $exception) {
123 error_log(sprintf(
124 'FluentBoards: Failed to log FluentCRM automation board activity: %s',
125 sanitize_text_field($exception->getMessage())
126 ));
127 } finally {
128 wp_set_current_user($previousUserId);
129 }
130 }
131
132 private function updateOnboarding()
133 {
134 $onboarding = Meta::where('key', Constant::FBS_ONBOARDING)->first();
135 if($onboarding && $onboarding->value == 'no'){
136 $onboarding->value = 'yes' ;
137 $onboarding->save();
138 }
139 }
140
141 public function taskCreatedOnBoard($task)
142 {
143 $boardId = $task->board_id;
144 $this->updateBoardTaskCount($boardId);
145 $taskStage = $task->stage;
146 $settings = ['task_id' => $task->id];
147 $this->createLogActivity($boardId, 'created', 'task', null, $task->title, 'on stage '.$taskStage->title, $settings, $task->created_by);
148 }
149
150 public function boardStagesReOrdered($boardId, $oldStageOrders)
151 {
152 $stages = [];
153 foreach ($oldStageOrders as $oldStageId){
154 $stage = Stage::findOrFail($oldStageId);
155 $stages[] = $stage->title;
156 }
157 $this->createLogActivity($boardId,'moved', 'stages', implode(',', $stages));
158 }
159
160 public function beforeBoardDeleted($board, $options = [])
161 {
162 // do something
163 }
164
165 public function boardUpdated($board, $oldBoard)
166 {
167 $boardId = $board->id;
168 $titleChanged = false;
169 $descriptionChanged = ($board->description != $oldBoard->description) ? true : false;
170 if ($board->title != $oldBoard->title) {
171 $titleChanged = true;
172 }
173 if ($descriptionChanged) {
174 $this->createLogActivity($boardId, 'changed', 'description',null , $oldBoard->description, $board->description);
175 }
176 if ($titleChanged) {
177 $this->createLogActivity($boardId, 'changed', 'title', $oldBoard->title, $board->title);
178 }
179 }
180
181 public function boardStageUpdated($boardId, $newStage, $oldStage)
182 {
183 $newStageLabel = $newStage['title'];
184 $oldStageLabel = $oldStage->title;
185 $this->createLogActivity($boardId, 'updated', 'title of stage', $oldStageLabel, $newStageLabel);
186 }
187
188 public function boardStageAdded($board, $stage)
189 {
190 $this->createLogActivity($board->id,'created', 'stage', null, $stage->title);
191 }
192 public function boardStageMoved($stage, $direction)
193 {
194 $this->createLogActivity($stage->board_id,'moved', $stage->title.' stage', $direction);
195 }
196
197 public function boardStageDeleted($board, $stageTobeDeleted)
198 {
199 $this->createLogActivity($board->id,'deleted', 'stage', $stageTobeDeleted);
200 }
201
202 public function boardStageArchived($boardId, $stage)
203 {
204 $stageTitle = $stage->title;
205 $this->createLogActivity($boardId,'archived', 'stage', $stageTitle);
206 }
207
208 public function boardArchivedStageRestore($boardId, $stageTitle)
209 {
210 $this->createLogActivity($boardId,'restored', 'stage', $stageTitle);
211 }
212
213 public function boardMemberAdded($boardId, $boardMember)
214 {
215 $this->createLogActivity($boardId,'added', 'member', $boardMember->dispaly_name, null, '');
216 }
217
218 public function boardViewerAdded($boardId, $boardMember)
219 {
220 $this->createLogActivity($boardId,'added', 'viewer', $boardMember->dispaly_name, null, '');
221
222 }
223
224 public function boardMemberRemoved($boardId, $memberName)
225 {
226 $this->createLogActivity($boardId,'removed', 'member', $memberName, 'from board');
227 }
228
229 public function boardAdminRemoved($boardId, $memberId)
230 {
231 $boardMember = $this->getMember($memberId);
232 $this->createLogActivity($boardId,'demoted', $boardMember->display_name, 'Manager', 'Member');
233 }
234
235 public function boardAdminAdded($boardId, $memberId)
236 {
237 $boardMember = $this->getMember($memberId);
238 $this->createLogActivity($boardId,'promoted', $boardMember->display_name, 'Member','Manager');
239 }
240
241 private function getMember($memberId)
242 {
243 return User::find($memberId);
244 }
245
246 public function beforeTaskDeleted($task, $options = [])
247 {
248 //do something
249 }
250
251 public function taskdeleted($task)
252 {
253 if (!$task->parent_id) {
254 $this->createLogActivity($task->board_id, 'deleted', 'task', $task->title);
255 }
256 }
257
258 public function taskArchivedOnBoard($task)
259 {
260 if(!$task->archived_at){
261 $this->createLogActivity($task->board_id, 'restored', 'task', $task->title);
262 $this->updateBoardTaskCount($task->board_id);
263 }else{
264 $this->createLogActivity($task->board_id, 'archived', 'task', $task->title);
265 $this->updateBoardTaskCount($task->board_id);
266 }
267 }
268
269 /**
270 * Log one board activity for a stage-level bulk task move.
271 *
272 * @param int $boardId
273 * @param Stage $sourceStage
274 * @param Stage $targetStage
275 * @param int $taskCount
276 * @return void
277 */
278 public function tasksMovedBetweenStages($boardId, $sourceStage, $targetStage, $taskCount)
279 {
280 $description = sprintf(
281 /* translators: %d is the number of tasks moved */
282 _n('%d task moved', '%d tasks moved', $taskCount, 'fluent-boards'),
283 $taskCount
284 );
285
286 $this->createLogActivity(
287 $boardId,
288 'moved',
289 'tasks',
290 $sourceStage->title,
291 $targetStage->title,
292 $description
293 );
294 }
295
296 public function boardLabelCreatedActivity($label)
297 {
298 $column = 'label';
299 $settings = [
300 'bg_color' => $label->bg_color,
301 'color' => $label->color,
302 'title' => $label->title ?? ''
303 ];
304 $this->createLogActivity(
305 $label->board_id,
306 'created',
307 $column,
308 null,
309 null,
310 null,
311 $settings
312 );
313 }
314
315 public function boardLabelUpdatedActivity($label)
316 {
317 $column = 'label';
318 $settings = [
319 'bg_color' => $label->bg_color,
320 'color' => $label->color,
321 'title' => $label->title ?? ''
322 ];
323 $this->createLogActivity(
324 $label->board_id,
325 'updated',
326 $column,
327 null,
328 null,
329 null,
330 $settings
331 );
332 }
333
334 public function boardLabelDeletedActivity($label)
335 {
336 $column = 'label';
337 $settings = [
338 'bg_color' => $label->bg_color,
339 'color' => $label->color,
340 'title' => $label->title ?? ''
341 ];
342 $this->createLogActivity(
343 $label->board_id,
344 'deleted',
345 $column,
346 null,
347 null,
348 null,
349 $settings
350 );
351 }
352
353 public function defaultAssigneesUpdated($stage, $assignees)
354 {
355 $column = 'default assignees of stage';
356
357 $this->createLogActivity(
358 $stage->board_id,
359 'updated',
360 $column,
361 null,
362 null,
363 $stage->title
364 );
365 }
366
367 public static function getCurrencies()
368 {
369 return [
370 'AED' => 'United Arab Emirates Dirham',
371 'AFN' => 'Afghan Afghani',
372 'ALL' => 'Albanian Lek',
373 'AMD' => 'Armenian Dram',
374 'ANG' => 'Netherlands Antillean Gulden',
375 'AOA' => 'Angolan Kwanza',
376 'ARS' => 'Argentine Peso', // non amex
377 'AUD' => 'Australian Dollar',
378 'AWG' => 'Aruban Florin',
379 'AZN' => 'Azerbaijani Manat',
380 'BAM' => 'Bosnia & Herzegovina Convertible Mark',
381 'BBD' => 'Barbadian Dollar',
382 'BDT' => 'Bangladeshi Taka',
383 'BIF' => 'Burundian Franc',
384 'BGN' => 'Bulgarian Lev',
385 'BMD' => 'Bermudian Dollar',
386 'BND' => 'Brunei Dollar',
387 'BOB' => 'Bolivian Boliviano',
388 'BRL' => 'Brazilian Real',
389 'BSD' => 'Bahamian Dollar',
390 'BWP' => 'Botswana Pula',
391 'BZD' => 'Belize Dollar',
392 'CAD' => 'Canadian Dollar',
393 'CDF' => 'Congolese Franc',
394 'CHF' => 'Swiss Franc',
395 'CLP' => 'Chilean Peso',
396 'CNY' => 'Chinese Renminbi Yuan',
397 'COP' => 'Colombian Peso',
398 'CRC' => 'Costa Rican Colón',
399 'CVE' => 'Cape Verdean Escudo',
400 'CZK' => 'Czech Koruna',
401 'DJF' => 'Djiboutian Franc',
402 'DKK' => 'Danish Krone',
403 'DOP' => 'Dominican Peso',
404 'DZD' => 'Algerian Dinar',
405 'EGP' => 'Egyptian Pound',
406 'ETB' => 'Ethiopian Birr',
407 'EUR' => 'Euro',
408 'FJD' => 'Fijian Dollar',
409 'FKP' => 'Falkland Islands Pound',
410 'GBP' => 'British Pound',
411 'GEL' => 'Georgian Lari',
412 'GIP' => 'Gibraltar Pound',
413 'GMD' => 'Gambian Dalasi',
414 'GNF' => 'Guinean Franc',
415 'GTQ' => 'Guatemalan Quetzal',
416 'GYD' => 'Guyanese Dollar',
417 'HKD' => 'Hong Kong Dollar',
418 'HNL' => 'Honduran Lempira',
419 'HRK' => 'Croatian Kuna',
420 'HTG' => 'Haitian Gourde',
421 'HUF' => 'Hungarian Forint',
422 'IDR' => 'Indonesian Rupiah',
423 'ILS' => 'Israeli New Sheqel',
424 'INR' => 'Indian Rupee',
425 'ISK' => 'Icelandic Króna',
426 'JMD' => 'Jamaican Dollar',
427 'JPY' => 'Japanese Yen',
428 'KES' => 'Kenyan Shilling',
429 'KGS' => 'Kyrgyzstani Som',
430 'KHR' => 'Cambodian Riel',
431 'KMF' => 'Comorian Franc',
432 'KRW' => 'South Korean Won',
433 'KYD' => 'Cayman Islands Dollar',
434 'KZT' => 'Kazakhstani Tenge',
435 'LAK' => 'Lao Kip',
436 'LBP' => 'Lebanese Pound',
437 'LKR' => 'Sri Lankan Rupee',
438 'LRD' => 'Liberian Dollar',
439 'LSL' => 'Lesotho Loti',
440 'MAD' => 'Moroccan Dirham',
441 'MDL' => 'Moldovan Leu',
442 'MGA' => 'Malagasy Ariary',
443 'MKD' => 'Macedonian Denar',
444 'MNT' => 'Mongolian Tögrög',
445 'MOP' => 'Macanese Pataca',
446 'MRO' => 'Mauritanian Ouguiya',
447 'MUR' => 'Mauritian Rupee',
448 'MVR' => 'Maldivian Rufiyaa',
449 'MWK' => 'Malawian Kwacha',
450 'MXN' => 'Mexican Peso',
451 'MYR' => 'Malaysian Ringgit',
452 'MZN' => 'Mozambican Metical',
453 'NAD' => 'Namibian Dollar',
454 'NGN' => 'Nigerian Naira',
455 'NIO' => 'Nicaraguan Córdoba',
456 'NOK' => 'Norwegian Krone',
457 'NPR' => 'Nepalese Rupee',
458 'NZD' => 'New Zealand Dollar',
459 'PAB' => 'Panamanian Balboa',
460 'PEN' => 'Peruvian Nuevo Sol',
461 'PGK' => 'Papua New Guinean Kina',
462 'PHP' => 'Philippine Peso',
463 'PKR' => 'Pakistani Rupee',
464 'PLN' => 'Polish Złoty',
465 'PYG' => 'Paraguayan Guaraní',
466 'QAR' => 'Qatari Riyal',
467 'RON' => 'Romanian Leu',
468 'RSD' => 'Serbian Dinar',
469 'RUB' => 'Russian Ruble',
470 'RWF' => 'Rwandan Franc',
471 'SAR' => 'Saudi Riyal',
472 'SBD' => 'Solomon Islands Dollar',
473 'SCR' => 'Seychellois Rupee',
474 'SEK' => 'Swedish Krona',
475 'SGD' => 'Singapore Dollar',
476 'SHP' => 'Saint Helenian Pound',
477 'SLL' => 'Sierra Leonean Leone',
478 'SOS' => 'Somali Shilling',
479 'SRD' => 'Surinamese Dollar',
480 'STD' => 'São Tomé and Príncipe Dobra',
481 'SVC' => 'Salvadoran Colón',
482 'SZL' => 'Swazi Lilangeni',
483 'THB' => 'Thai Baht',
484 'TJS' => 'Tajikistani Somoni',
485 'TOP' => 'Tongan Paʻanga',
486 'TRY' => 'Turkish Lira',
487 'TTD' => 'Trinidad and Tobago Dollar',
488 'TWD' => 'New Taiwan Dollar',
489 'TZS' => 'Tanzanian Shilling',
490 'UAH' => 'Ukrainian Hryvnia',
491 'UGX' => 'Ugandan Shilling',
492 'USD' => 'United States Dollar',
493 'UYU' => 'Uruguayan Peso',
494 'UZS' => 'Uzbekistani Som',
495 'VND' => 'Vietnamese Đồng',
496 'VUV' => 'Vanuatu Vatu',
497 'WST' => 'Samoan Tala',
498 'XAF' => 'Central African Cfa Franc',
499 'XCD' => 'East Caribbean Dollar',
500 'XOF' => 'West African Cfa Franc',
501 'XPF' => 'Cfp Franc',
502 'YER' => 'Yemeni Rial',
503 'ZAR' => 'South African Rand',
504 'ZMW' => 'Zambian Kwacha',
505 ];
506 }
507 public function taskMovedFromBoard($task, $oldBoard, $newBoard)
508 {
509 // add tasks_count in the board
510 $this->updateBoardTaskCount($newBoard->id);
511 // subtract tasks_count in the board
512 $this->updateBoardTaskCount($oldBoard->id);
513
514 $this->createLogActivity($oldBoard->id, 'moved', 'task', $task->title . ' to ' . $newBoard->title);
515 $this->createLogActivity($newBoard->id, 'added', 'task', $task->title . ' from ' . $oldBoard->title);
516 }
517
518 public function deleteUserRelatedData($id, $reassign, $user)
519 {
520 try{
521 if(!$id) {
522 throw new \Exception(esc_html__('Member Not deleted', 'fluent-boards'));
523 }
524 Meta::where('object_type', Constant::OBJECT_TYPE_USER)
525 ->where('object_id', $id)
526 ->delete();
527 NotificationUser::where('user_id', $id)->delete();
528 Relation::where('foreign_id', $id)
529 ->whereIn('object_type', [
530 Constant::OBJECT_TYPE_BOARD_USER,
531 Constant::OBJECT_TYPE_USER_TASK_WATCH,
532 Constant::TASK_ASSIGNEE
533 ])->delete();
534 }catch (\Exception $e){}
535 }
536 public function updateBoardTaskCount($boardId)
537 {
538 $board = Board::find($boardId);
539 $settings = $board->settings ?? [];
540 $stageIds = Stage::where('board_id', $boardId)->whereNull('archived_at')->pluck('id')->toArray();
541 $settings['tasks_count'] = $board->tasks->where('parent_id', null)->whereNull('archived_at')->whereIn('stage_id', $stageIds)->count();
542 $board->settings = $settings;
543 $board->save();
544 }
545
546 /**
547 * Delete a board-owned previous background attachment and log the change.
548 *
549 * @param int $boardId
550 * @param array|string $oldBackground
551 * @return void
552 */
553 public function backgroundUpdated($boardId, $oldBackground)
554 {
555 if (
556 is_array($oldBackground) &&
557 !empty($oldBackground['is_image']) &&
558 !empty($oldBackground['image_url'])
559 ) {
560 // Only the target board's background attachment may be removed by this hook.
561 if (!empty($oldBackground['id'])) {
562 $attachment = Attachment::where('id', absint($oldBackground['id']))
563 ->where('object_id', absint($boardId))
564 ->where('object_type', Constant::BOARD_BACKGROUND_IMAGE)
565 ->first();
566
567 if ($attachment) {
568 $deletedAttachment = clone $attachment;
569 $attachment->delete();
570 (new FileHandler())->deleteAttachmentFile($deletedAttachment, absint($boardId));
571 }
572 }
573 }
574
575 $this->createLogActivity($boardId, 'changed', 'board background', null, null);
576 }
577
578
579 }
580