fileHandler = $fileHandler; } public function taskDeleted($task) { // Delete all activities and comments related to this task Activity::where('object_id', $task->id)->where('object_type', Constant::ACTIVITY_TASK)->delete(); Meta::where('object_id', $task->id)->where('object_type', Constant::REPEAT_TASK_META)->delete(); } public function searchAssignees($options, $search, $includedIds) { $users = get_users([ 'number' => 20, 'search' => $search, ]); $formattedUsers = []; $pushedIds = []; foreach ($users as $user) { $pushedIds[] = $user->ID; $formattedUsers[] = [ 'id' => $user->ID, 'title' => $user->display_name . ' (' . $user->user_email . ')', 'photo' => get_avatar_url($user->user_email), 'left_side_value' => $user->display_name, 'right_side_value' => $user->user_email, ]; } if (!$includedIds) { return $formattedUsers; } if (!is_array($includedIds)) { $includedIds = [$includedIds]; } $includedIds = array_diff(array_map('intval', $includedIds), $pushedIds); if ($includedIds) { $users = get_users([ 'include' => $includedIds, ]); foreach ($users as $user) { $formattedUsers[] = [ 'id' => $user->ID, 'title' => $user->display_name . ' (' . $user->user_email . ')', 'photo' => get_avatar_url($user->user_email), 'left_side_value' => $user->display_name, 'right_side_value' => $user->user_email, ]; } } return $formattedUsers; } public function searchNonBoardWordpressUsers() { // This enumerates every WordPress user with their email; only user managers may see it. if (!current_user_can('list_users')) { return []; } $superAdmin = Relation::select('user_id')->distinct()->pluck('user_id'); $users = User::whereDoesntHave('boards')->whereNotIn('ID', $superAdmin)->get(); $formattedUsers = []; foreach ($users as $user) { $formattedUsers[] = [ 'id' => $user->ID, 'photo' => $user->photo, 'title' => $user->display_name . ' (' . $user->user_email . ')', 'left_side_value' => $user->display_name, 'right_side_value' => $user->user_email, ]; } return $formattedUsers; } public function searchContact($options, $search, $includedIds) { if (!defined('FLUENTCRM')) { return []; } // check if the use has permission to access contacts $contactPermission = CRMPermissionManager::currentUserCan('fcrm_read_contacts'); if(!$contactPermission) { return []; } $contactsQuery = new ContactsQuery([ 'search' => $search, 'with' => [], 'limit' => 20, 'offset' => 0, ]); $subscribers = $contactsQuery->get(); $formattedSubscribers = []; $pushedIs = []; foreach ($subscribers as $subscriber) { $pushedIs[] = $subscriber->id; $formattedSubscribers[] = [ 'id' => $subscriber->id, 'title' => $subscriber->full_name . ' (' . $subscriber->email . ')', 'photo' => $subscriber->photo, 'name' => $subscriber->full_name, 'email' => $subscriber->email, ]; } if (!is_array($includedIds)) { $includedIds = [$includedIds]; } if (!$includedIds) { return $formattedSubscribers; } $remainingIds = array_diff($includedIds, $pushedIs); if ($remainingIds) { $remainingContacts = Subscriber::whereIn('id', $remainingIds)->get(); foreach ($remainingContacts as $subscriber) { $formattedSubscribers[] = [ 'id' => $subscriber->id, 'title' => $subscriber->full_name . ' (' . $subscriber->email . ')', 'photo' => $subscriber->photo, 'name' => $subscriber->full_name, 'email' => $subscriber->email, ]; } } return $formattedSubscribers; } /** * Delete an attachment file only after the owning database transaction commits. * * @param mixed $deletedAttachment * @param int|null $boardId * @return void */ public function taskAttachmentDeleted($deletedAttachment, $boardId = null) { if ($deletedAttachment->attachment_type === 'url') { return; } if ($boardId === null) { $task = Task::find(absint($deletedAttachment->object_id)); $boardId = $task ? $task->board_id : null; } $dbInstance = App::getInstance('db'); if ($dbInstance->inTransaction()) { $attachmentSnapshot = clone $deletedAttachment; $dbInstance->afterCommit(function () use ($attachmentSnapshot, $boardId) { try { $this->fileHandler->deleteAttachmentFile($attachmentSnapshot, $boardId); } catch (\Throwable $e) { error_log(sprintf( 'FluentBoards: Failed to delete committed task attachment file: %s', sanitize_text_field($e->getMessage()) )); } }); return; } try { $this->fileHandler->deleteAttachmentFile($deletedAttachment, $boardId); } catch (Exception $e) { wp_send_json_error($e->getMessage()); } } /** * Auto-watch newly created tasks when the board preference allows it. */ public function onTaskCreated($task) { $userId = get_current_user_id(); if (!$userId) { return; } if ($this->shouldAutoWatchForBoard($task->board_id, Constant::GLOBAL_EMAIL_NOTIFICATION_CREATING_TASK)) { $task->watchers()->syncWithoutDetaching([$userId => ['object_type' => Constant::OBJECT_TYPE_USER_TASK_WATCH]]); } } /** * Auto-watch commented tasks when the board preference allows it. */ public function onCommentCreated($comment) { $task = $comment->task; $userId = get_current_user_id(); if (!$userId) { return; } if ($this->shouldAutoWatchForBoard($task->board_id, Constant::GLOBAL_EMAIL_NOTIFICATION_COMMENTING)) { $task->watchers()->syncWithoutDetaching([$userId => ['object_type' => Constant::OBJECT_TYPE_USER_TASK_WATCH]]); } } /** * Auto-watch assigned tasks when the board preference allows it. */ public function onAssignAnotherUser($task, $assigneeId) { if ($this->shouldAutoWatchForBoard($task->board_id, Constant::GLOBAL_EMAIL_NOTIFICATION_ASSIGNING)) { $task->watchers()->syncWithoutDetaching([$assigneeId => ['object_type' => Constant::OBJECT_TYPE_USER_TASK_WATCH]]); } } /** * Determine auto-watch behavior from the current user's board preference. */ private function shouldAutoWatchForBoard($boardId, $preferenceKey) { return (new NotificationService())->isBoardAutoWatchEnabled($boardId, get_current_user_id(), $preferenceKey); } public function taskCloned($originalTask, $clonedTask) { Activity::where('object_id', $clonedTask->id) ->where('object_type', Constant::ACTIVITY_TASK) ->delete(); do_action('fluent_boards/task_cloned_activity', $originalTask, $clonedTask); } }