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
← All changes | app/Hooks/Handlers/BoardHandler.php +113 -7 2.0.0 → 2.2.0 View file →
@@ -34,8 +34,47 @@
34 34 }
35 35
36 36 Helper::createActivity($data);
37 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 +
38 77 public function getAllBoards($sortBy = 'ASC')
39 78 {
40 79 $boards = Board::orderBy('created_at', $sortBy)->get();
41 80
@@ -57,8 +96,40 @@
57 96 $this->createLogActivity($boardId, 'created', 'board', null, null, $board->title);
58 97 $this->updateOnboarding();
59 98 }
60 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 +
61 132 private function updateOnboarding()
62 133 {
63 134 $onboarding = Meta::where('key', Constant::FBS_ONBOARDING)->first();
64 135 if($onboarding && $onboarding->value == 'no'){
@@ -194,8 +265,35 @@
194 265 $this->updateBoardTaskCount($task->board_id);
195 266 }
196 267 }
197 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 +
198 296 public function boardLabelCreatedActivity($label)
199 297 {
200 298 $column = 'label';
201 299 $settings = [
@@ -444,8 +542,15 @@
444 542 $board->settings = $settings;
445 543 $board->save();
446 544 }
447 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 + */
448 553 public function backgroundUpdated($boardId, $oldBackground)
449 554 {
450 555 if (
451 556 is_array($oldBackground) &&
@@ -451,19 +556,20 @@
451 556 is_array($oldBackground) &&
452 557 !empty($oldBackground['is_image']) &&
453 558 !empty($oldBackground['image_url'])
454 559 ) {
455 - // Delete attachment if ID exists
560 + // Only the target board's background attachment may be removed by this hook.
456 561 if (!empty($oldBackground['id'])) {
457 - $attachment = Attachment::find($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 +
458 567 if ($attachment) {
568 + $deletedAttachment = clone $attachment;
459 569 $attachment->delete();
570 + (new FileHandler())->deleteAttachmentFile($deletedAttachment, absint($boardId));
460 571 }
461 - }
462 -
463 - // Delete file if full_url exists
464 - if (!empty($oldBackground['full_url'])) {
465 - (new FileHandler())->deleteFileByUrl($oldBackground['full_url']);
466 572 }
467 573 }
468 574
469 575 $this->createLogActivity($boardId, 'changed', 'board background', null, null);