PluginProbe
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration / 2.0.4
FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration v2.0.4
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 / Services / Intergrations / FluentCRM / DeepIntegration.php

DeepIntegration.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.0.4, at app/Services/Intergrations/FluentCRM/DeepIntegration.php

218 lines 6.6 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\Intergrations\FluentCRM;
4
5 use FluentBoards\App\Models\Board;
6 use FluentBoards\App\Models\Task;
7 use FluentBoards\App\Models\TaskMeta;
8 use FluentBoards\App\Models\User;
9 use FluentBoards\App\Services\PermissionManager;
10 use FluentBoards\Framework\Database\Orm\Builder;
11
12 class DeepIntegration
13 {
14 private const USER_TEMPLATE_OPTION_LIMIT = 50;
15
16 public function init()
17 {
18 add_filter('fluentcrm_ajax_options_boards', [$this, 'getBoards'], 10, 3);
19 add_filter('fluentcrm_ajax_options_task_templates', [$this, 'getTaskTemplates'], 10, 3);
20 add_filter('fluentcrm_ajax_options_board_default_templates', [$this, 'getDefaultBoardTemplates'], 10, 3);
21 add_filter('fluentcrm_ajax_options_board_user_templates', [$this, 'getUserBoardTemplates'], 10, 3);
22 add_filter('fluentcrm_ajax_options_board_members', [$this, 'getBoardMembers'], 10, 3);
23 }
24
25 public function getBoards($records, $search, $includeIds)
26 {
27 $query = Board::select(['id', 'title']);
28
29 if (!empty($search)) {
30 $query->where('title', 'like', "%$search%");
31 }
32
33 $boards = $query->orderBy('title', 'ASC')->get();
34
35 return $this->getFormattedBoards($boards);
36 }
37
38 public function getFormattedBoards($boards)
39 {
40 $formattedBoards = [];
41 foreach ($boards as $board) {
42 $formattedBoards[] = [
43 'id' => strval($board->id),
44 'title' => $board->title
45 ];
46 }
47 return $formattedBoards;
48 }
49
50 public function getTaskTemplates($records, $search, $includeIds)
51 {
52 if (!defined('FLUENT_BOARDS_PRO')) {
53 return [];
54 }
55
56 $userId = get_current_user_id();
57 $currentUser = User::find($userId);
58
59 $relatedBoardsQuery = Board::query();
60
61 if (!PermissionManager::isAdmin($userId)) {
62 $relatedBoardsQuery->whereIn('id', $currentUser->whichBoards->pluck('id'));
63 }
64
65 $templateTaskIds = TaskMeta::where('key', 'is_template')->where('value', 'yes')->pluck('task_id');
66 $query = Task::whereIn('id', $templateTaskIds)
67 ->where('archived_at', null)
68 ->whereIn('board_id', $relatedBoardsQuery->pluck('id'))
69 ->with('assignees', 'labels');
70
71
72 if (!empty($search)) {
73 $query->where('title', 'like', "%$search%");
74 }
75
76 $templateTasks = $query->orderBy('title', 'ASC')->get();
77
78 $formattedTemplateTasks = [];
79 foreach ($templateTasks as $task) {
80 $formattedTemplateTasks[] = [
81 'id' => strval($task->id),
82 'title' => $task->title
83 ];
84 }
85 return $formattedTemplateTasks;
86 }
87
88 public function getDefaultBoardTemplates($records, $search, $includeIds)
89 {
90 // Built-in board templates are coming soon. Keep this selector empty so
91 // FluentCRM option lookups do not request the external default-template API.
92 return [];
93 }
94
95 /**
96 * Return bounded user-template options for the FluentCRM selector.
97 *
98 * @param array $records
99 * @param string $search
100 * @param array $includeIds
101 * @return array
102 */
103 public function getUserBoardTemplates($records, $search, $includeIds)
104 {
105 if (!defined('FLUENT_BOARDS_PRO')) {
106 return [];
107 }
108
109 global $wpdb;
110
111 $search = is_scalar($search) ? sanitize_text_field((string) $search) : '';
112 $includeIds = array_slice(array_values(array_unique(array_filter(
113 array_map('absint', (array) $includeIds)
114 ))), 0, self::USER_TEMPLATE_OPTION_LIMIT);
115
116 $query = $this->newUserTemplateOptionsQuery();
117
118 if ($search !== '') {
119 $query->where('title', 'like', '%' . $wpdb->esc_like($search) . '%');
120 }
121
122 $templates = $query->orderBy('title', 'ASC')
123 ->limit(self::USER_TEMPLATE_OPTION_LIMIT)
124 ->get();
125 $options = $this->formatUserTemplateOptions($templates);
126
127 // Preserve saved selections even when they fall outside the current result page.
128 $missingIds = array_diff($includeIds, array_keys($options));
129 if ($missingIds) {
130 $selectedTemplates = $this->newUserTemplateOptionsQuery()
131 ->whereIn('id', $missingIds)
132 ->get();
133 $options += $this->formatUserTemplateOptions($selectedTemplates);
134 }
135
136 $selectedOptions = array_intersect_key($options, array_flip($includeIds));
137 $regularOptions = array_diff_key($options, $selectedOptions);
138 $options = array_merge(
139 array_values($selectedOptions),
140 array_slice(
141 array_values($regularOptions),
142 0,
143 max(0, self::USER_TEMPLATE_OPTION_LIMIT - count($selectedOptions))
144 )
145 );
146
147 usort($options, function ($first, $second) {
148 return strcasecmp($first['title'], $second['title']);
149 });
150
151 return $options;
152 }
153
154 /**
155 * Create a fresh query for lightweight user-template selector options.
156 *
157 * @return Builder
158 */
159 private function newUserTemplateOptionsQuery()
160 {
161 return Board::select(['id', 'title'])
162 ->whereIn('type', ['to-do', 'roadmap'])
163 ->onlyTemplates();
164 }
165
166 /**
167 * Format template models as selector options keyed by integer ID.
168 *
169 * @param iterable $templates
170 * @return array
171 */
172 private function formatUserTemplateOptions($templates)
173 {
174 $options = [];
175
176 foreach ($templates as $template) {
177 $options[(int) $template->id] = [
178 'id' => (int) $template->id,
179 'title' => $template->title,
180 ];
181 }
182
183 return $options;
184 }
185
186 public function getBoardMembers($records, $search, $includeIds)
187 {
188 // Get all WordPress users
189 $args = [
190 'orderby' => 'display_name',
191 'order' => 'ASC',
192 ];
193
194 // Add search filter if provided
195 if (!empty($search)) {
196 $args['search'] = '*' . $search . '*';
197 $args['search_columns'] = ['user_login', 'user_email', 'display_name'];
198 }
199
200 // Include specific IDs if provided
201 if (!empty($includeIds)) {
202 $args['include'] = $includeIds;
203 }
204
205 $users = get_users($args);
206
207 $formattedMembers = [];
208 foreach ($users as $user) {
209 $formattedMembers[] = [
210 'id' => strval($user->ID),
211 'title' => $user->display_name . ' (' . $user->user_email . ')'
212 ];
213 }
214
215 return $formattedMembers;
216 }
217 }
218