PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 1.95
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v1.95
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 1.40 1.41 All 42 releases
fluent-boards / app / Hooks / Handlers / ActivityHandler.php

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

466 lines 15.8 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\Board;
6 use FluentBoards\App\Models\Stage;
7 use FluentBoards\App\Models\Task;
8 use FluentBoards\App\Models\User;
9 use FluentBoards\App\Services\Constant;
10 use FluentCrm\App\Models\Subscriber;
11 use FluentBoards\App\Models\Comment;
12 use FluentBoards\App\Services\Helper;
13
14 class ActivityHandler
15 {
16 public function createLogActivity($taskId, $action, $column, $oldValue = null, $newValue = null, $description = null, $settings = null )
17 {
18 $data = [
19 'object_type' => Constant::ACTIVITY_TASK,
20 'object_id' => $taskId,
21 'action' => $action, // action type: changed, updated, added, removed
22 'column' => $column,
23 'old_value' => $oldValue,
24 'new_value' => $newValue,
25 'description' => $description,
26 'settings' => $settings
27 ];
28 $userId = get_current_user_id();
29 if($userId == 0){
30 $task = Task::find($taskId);
31 $data['created_by'] = $task->created_by;
32 }
33
34 Helper::createActivity($data);
35 }
36 public function logMoveTaskToAnotherBoardActivity($task, $oldTask)
37 {
38 $old = $this->getBoardTitleById($oldTask->board_id);
39 $new = $this->getBoardTitleById($task->board_id);
40 $this->createLogActivity( $task->id,'changed', 'board', $old, $new);
41 }
42
43 public function logAssigneeAddedActivity($task, $newAssigneeId)
44 {
45 $currentUserId = get_current_user_id();
46 if($newAssigneeId == $currentUserId) {
47 $this->taskAssigneeJoin($task->id);
48 return;
49 }
50 $user = User::findOrFail($newAssigneeId);
51 $currentUserId = get_current_user_id();
52 if($currentUserId === $user->ID){
53 $this->taskAssigneeJoin($task->id);
54 } elseif ($user) {
55 $this->createLogActivity($task->id, 'added', 'assignee', null, $user->display_name);
56 }
57 }
58
59 public function logAssigneeRemovedActivity($task, $newAssigneeId)
60 {
61 $currentUserId = get_current_user_id();
62 if($newAssigneeId == $currentUserId) {
63 $this->taskAssigneeLeave($task->id);
64 return;
65 }
66 $user = User::findOrFail($newAssigneeId);
67 $currentUserId = get_current_user_id();
68 if($currentUserId === $user->ID){
69 $this->taskAssigneeLeave($task->id);
70 } else if($user) {
71 $this->createLogActivity($task->id, 'removed', 'assignee', null, $user->display_name);
72 }
73 }
74
75 public function logTaskCreationActivity($task)
76 {
77 $this->createLogActivity( $task->id,'created', 'task', null, $task->title, null );
78 }
79
80 public function logTaskContentUpdatedActivity($task, $col, $oldTask = null)
81 {
82 $action = 'updated';
83 if($col == 'description'){
84 $this->createLogActivity( $task->id, $action, $col, $oldTask->description, $task->description );
85 }else{
86 if($task->parent_id){
87 $this->createLogActivity( $task->parent_id, $action, 'subtask', $oldTask->title, $task->title );
88 }else{
89 $this->createLogActivity( $task->id, $action, $col, $oldTask->title, $task->title );
90 }
91 }
92 }
93
94 public function taskLabelActivity($task, $label, $action)
95 {
96 $column = 'label';
97 $settings = [
98 'bg_color' => $label->bg_color,
99 'color' => $label->color,
100 'title' => $label->title,
101 ];
102
103 $this->createLogActivity($task->id, $action, $column, null, null, null, $settings);
104 }
105
106 public function logDueDateActivity($task, $oldDate)
107 {
108 $column = 'Due Date';
109 $action = 'changed';
110
111 if($oldDate){
112 $new = gmdate("F j, Y, g:i a", strtotime($task->due_at));
113 $old = gmdate("F j, Y, g:i a", strtotime($oldDate));
114 if($new == $old)
115 return;
116 }
117 $newDueDate = $task->due_at;
118 $new = null;
119 if ($newDueDate) {
120 $new = gmdate("F j, Y, g:i a", strtotime($newDueDate));
121 if(str_contains($new, '12:00 am')){
122 $new = gmdate("F j, Y", strtotime($newDueDate));
123 }
124 }
125 $old = null;
126 if(!$oldDate){
127 $action = 'added';
128 }else{
129 $old = gmdate("F j, Y, g:i a", strtotime($oldDate));
130 if(str_contains($old, '12:00 am')){
131 $old = gmdate("F j, Y", strtotime($oldDate));
132 }
133 }
134
135 $this->createLogActivity($task->id, $action, $column, $old, $new);
136 }
137 public function logDueDateRemoveActivity($task)
138 {
139 $this->createLogActivity( $task->id, 'removed', 'Due Date', null);
140 }
141
142 public function logStartDateActivity($task, $oldDate)
143 {
144 $column = 'Start Date';
145 $action = 'changed';
146
147 if($oldDate){
148 $new = gmdate("F j, Y", strtotime($task->started_at));
149 $old = gmdate("F j, Y", strtotime($oldDate));
150 if($new == $old)
151 return;
152 }
153 $newStartDate = $task->started_at;
154 $new = null;
155 if ($newStartDate) {
156 $new = gmdate("F j, Y", strtotime($newStartDate));
157 }
158 $old = null;
159 if(!$oldDate){
160 $action = 'added';
161 }else{
162 $old = gmdate("F j, Y", strtotime($oldDate));
163 }
164
165 $this->createLogActivity($task->id, $action, $column, $old, $new);
166 }
167
168
169 public function logPriorityChangeActivity($task, $old)
170 {
171 $new = $task->priority;
172 $this->createLogActivity($task->id, 'changed', 'priority', $old, $new);
173 }
174
175 public function logCommentCreateActivity($comment)
176 {
177 if($comment->parent_id) {
178 // dd($comment);
179 $parent = Comment::findOrFail($comment->parent_id);
180 $parentDescription = $parent->description;
181 $this->createLogActivity($comment->task_id, 'added', 'a reply');
182 }else{
183 $commentPlainText = wp_strip_all_tags($comment->description);
184 $this->createLogActivity($comment->task_id, 'added', 'comment', null, $commentPlainText, null);
185 }
186 }
187 public function logCommentUpdateActivity($comment, $oldComment)
188 {
189 $taskId = $comment->task_id;
190 $newComment = $comment->settings['raw_description'] ?? $comment->description;
191
192 $this->createLogActivity($taskId, 'updated', 'comment', $oldComment, $newComment);
193 }
194 public function logCommentDeleteActivity($comment)
195 {
196 $commentDescription = wp_strip_all_tags($comment->settings['raw_description'] ?? $comment->description );
197 $taskId = $comment->task_id;
198
199 $this->createLogActivity($taskId, 'removed', 'comment', null, $commentDescription, null);
200 }
201
202 public function logSubtaskAddedActivity($parentTask, $subTask)
203 {
204 $this->createLogActivity($parentTask->id, 'added', 'subtask', null, $subTask->title);
205 }
206
207 public function logSubtaskCloneActivity($parentTask, $subTask)
208 {
209 $this->createLogActivity($parentTask->id, 'cloned', 'subtask', null, $subTask->title);
210 }
211 public function logSubtaskGroupAddedActivity($task_id, $subTaskGroup)
212 {
213 $this->createLogActivity($task_id, 'added', 'subtask group', null, $subTaskGroup->value);
214 }
215
216 public function logSubtaskDeletedActivity($id, $subTaskTitle)
217 {
218 $this->createLogActivity($id, 'removed', 'subtask', null, $subTaskTitle);
219 }
220
221 public function logSubtaskGroupDeletedActivity($task_id, $subTaskGroup)
222 {
223 $this->createLogActivity($task_id, 'removed', 'subtask group', null, $subTaskGroup->value);
224 }
225 public function logSubtaskGroupTitleUpdatedActivity($oldTitle, $group)
226 {
227 $this->createLogActivity($group->task_id, 'changed', 'subtask group title', $oldTitle, $group->value);
228 }
229 public function logTaskCompletedOrReopenActivity($task, $status)
230 {
231 if($status == 'closed'){
232 if($task->parent_id){
233 $this->createLogActivity($task->parent_id, 'closed', 'subtask', $task->title);
234 }else{
235 $this->createLogActivity($task->id, 'closed', 'task', $task->title);
236 }
237 }else{
238 if($task->parent_id){
239 $this->createLogActivity($task->parent_id, 'reopened', 'subtask', $task->title);
240 }else{
241 $this->createLogActivity($task->id, 'reopened', 'task', $task->title);
242 }
243 }
244 }
245
246 public function logTaskStageUpdatedActivity($task, $oldStageId)
247 {
248 $oldStage = Stage::findOrFail($oldStageId);
249 $newStage = Stage::findOrFail($task->stage_id);
250 if($oldStage && $newStage){
251 $this->createLogActivity($task->id, 'changed', 'stage', $oldStage->title, $newStage->title);
252 }
253 }
254
255 public function associateUserAddChangeRemoveActivity($oldAssociateId, $newAssociateId, $taskId)
256 {
257 $subsciber = new Subscriber();
258 $oldAssociateUser = $subsciber->find($oldAssociateId);
259 $newAssociateUser = $subsciber->find($newAssociateId);
260 $action = 'added';
261 $column = 'the associate email';
262 $old = null; $new = null;
263
264 if ($oldAssociateUser && $newAssociateUser) {
265 $old = $oldAssociateUser->email;
266 $new = $newAssociateUser->email;
267 $action = 'changed';
268 } elseif ($oldAssociateUser && !$newAssociateUser) {
269 $old = $oldAssociateUser->email;
270 $action = 'removed';
271 } else {
272 $new = $newAssociateUser->email;
273 }
274 $this->createLogActivity($taskId, $action, $column, $old, $new);
275 }
276
277 public function taskAssigneeJoin($id)
278 {
279 $this->createLogActivity($id, 'joined', 'task', null, null);
280 }
281
282 public function taskAssigneeLeave($id)
283 {
284 $this->createLogActivity($id, 'left', 'task', null, null);
285 }
286
287 public function labelManageForTaskActivity($id, $action)
288 {
289 $this->createLogActivity($id, $action, 'label', null, null);
290 }
291
292 private function getBoardTitleById($boardId)
293 {
294 return Board::findOrFail($boardId)->title; // it can be further optimized , we may limit multiple query here.
295 }
296
297 public function taskAddedFromFluentForms($task)
298 {
299 $taskActivity = [
300 'object_type' => Constant::ACTIVITY_TASK,
301 'object_id' => $task->id,
302 'action' => 'created', // action type: changed, updated, added, removed
303 'column' => 'task',
304 'old_value' => $task->title,
305 'new_value' => null,
306 'description' => " from Fluent Forms",
307 ];
308
309 $board = Board::find($task->board_id);
310 $settings = $board->settings ?? [];
311
312 if (isset($settings['tasks_count'])) {
313 if ($settings['tasks_count'] != 0) $settings['tasks_count'] += 1;
314 } else {
315 $settings['tasks_count'] = 1;
316 }
317 $board->settings = $settings;
318 $board->save();
319 $taskStage = $task->stage;
320 $settings = ['task_id' => $task->id];
321
322 $boardActivity = [
323 'object_type' => Constant::ACTIVITY_BOARD,
324 'object_id' => $task->board_id,
325 'action' => 'created', // action type: changed, updated, added, removed, created
326 'column' => 'task',
327 'old_value' => null,
328 'new_value' => $task->title,
329 'description' => 'on stage '. $taskStage->title . ' from Fluent Forms ',
330 'settings' => $settings
331 ];
332 if (intval($task->created_by) > 0) {
333 $taskActivity['created_by'] = intval($task->created_by);
334 $boardActivity['created_by'] = intval($task->created_by);
335
336 } else {
337 $taskActivity['description'] .= ' by '. $task['settings']['author']['name'] . " (" . $task['settings']['author']['email'] . ")";
338 $boardActivity['description'] .= ' by '. $task['settings']['author']['name'] . " (" . $task['settings']['author']['email'] . ")";
339 }
340 Helper::createActivity($taskActivity);
341 Helper::createActivity($boardActivity);
342
343 }
344 public function taskAttachmentAdded($attachment)
345 {
346 $this->createLogActivity($attachment->object_id , 'added', 'attachment', null, strlen($attachment->title) > 0 ? $attachment->title : $attachment->full_url);
347 }
348 public function taskAttachmentDeleted($attachment)
349 {
350 $this->createLogActivity($attachment->object_id , 'deleted', 'attachment', null, strlen($attachment->title) > 0 ? $attachment->title : $attachment->full_url);
351 }
352
353 public function taskArchived($task)
354 {
355 if(!$task->archived_at){
356 $this->createLogActivity($task->id, 'restored', 'task', $task->title);
357 }else{
358 $this->createLogActivity($task->id, 'archived', 'task', $task->title);
359 }
360 }
361
362 public function logRepeatTaskCreatedActivity($newTask, $parentTask)
363 {
364 $this->createLogActivity(
365 $newTask->id,
366 'created',
367 'repeat task',
368 $newTask->title,
369 $parentTask->title,
370 null,
371 $parentTask
372 );
373 }
374
375 public function logRepeatTaskSet($newTask)
376 {
377 $this->createLogActivity(
378 $newTask->id,
379 'set',
380 'Repeat Task',
381 null,
382 null,
383 );
384 }
385
386 public function logRepeatTaskUpdated($newTask)
387 {
388 $this->createLogActivity(
389 $newTask->id,
390 'updated',
391 'Repeat Task',
392 null,
393 null
394 );
395 }
396 public function taskMovedFromBoard($task, $oldBoard, $newBoard)
397 {
398 $this->createLogActivity($task->id, 'moved', 'board', $oldBoard->title, $newBoard->title);
399 }
400
401 public function logCustomFieldActivity($taskId, $customField, $oldValue, $newValue, $isNewCustomField)
402 {
403 // Format values for display in activity
404 $displayNewValue = $this->formatValueForDisplay($newValue, $customField->settings['custom_field_type']);
405
406 $action = 'changed';
407 $column = $customField->title;
408
409 // Ensure we have a value to display
410 if (empty($displayNewValue)) {
411 $displayNewValue = 'empty';
412 }
413
414 // Handle old value display logic
415 $displayOldValue = null;
416 if (!$isNewCustomField && $oldValue !== null && $oldValue !== '') {
417 // Format old value for display if it exists
418 $displayOldValue = $this->formatValueForDisplay($oldValue, $customField->settings['custom_field_type']);
419 }
420
421 $settings = [
422 'custom_field_id' => $customField->id,
423 'custom_field_title' => $customField->title,
424 'custom_field_type' => $customField->settings['custom_field_type']
425 ];
426
427 $this->createLogActivity($taskId, $action, $column, $displayOldValue, $displayNewValue, null, $settings);
428 }
429
430 /**
431 * Format custom field value for display in activity logs
432 */
433 private function formatValueForDisplay($value, $fieldType)
434 {
435 if ($value === null || $value === '') {
436 return 'empty';
437 }
438
439 switch ($fieldType) {
440 case 'checkbox':
441 return $value ? 'checked' : 'unchecked';
442 case 'date':
443 // If it's already formatted as Y-m-d H:i:s, convert to readable format
444 if (preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value)) {
445 return gmdate('M j, Y g:i A', strtotime($value));
446 }
447 return $value;
448 case 'select':
449 case 'text':
450 case 'textarea':
451 case 'number':
452 default:
453 return (string) $value;
454 }
455 }
456 public function taskCloned($originalTask, $clonedTask)
457 {
458 $this->createLogActivity(
459 $clonedTask->id,
460 'cloned',
461 'task',
462 'from ' . $originalTask->title,
463 );
464 }
465 }
466