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.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 1.40 All 43 releases
fluent-boards / app / Http / Controllers / WebhookController.php

WebhookController.php in FluentBoards – Project Management, Task Management, Goal Tracking, Kanban Board, and, Team Collaboration 2.2.0, at app/Http/Controllers/WebhookController.php

334 lines 11.2 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\Http\Controllers;
4
5 use FluentBoards\App\Models\Webhook;
6 use FluentBoards\App\Models\Meta;
7 use FluentBoards\App\Models\Relation;
8 use FluentBoards\Framework\Http\Request\Request;
9
10
11 class WebhookController extends Controller
12 {
13 public function index(Request $request, Webhook $webhook)
14 {
15 $fields = $webhook->getFields();
16 $search = $request->getSafe('search', 'sanitize_text_field', '');
17
18 $webhooks = $webhook->latest()->get()->toArray();
19 if ( ! empty($search)) {
20 $search = strtolower($search);
21 $webhooks = array_map(function ($row) use ($search) {
22 $name = strtolower($row['value']['name']);
23 if ($row['value'] && str_contains($name, $search)) {
24 return $row;
25 }
26
27 return null;
28 }, $webhooks);
29 }
30
31 $rows = [];
32 foreach ($webhooks as $row) {
33 if ($row) {
34 $rows[] = $row;
35 }
36 }
37
38
39 $response = [
40 'webhooks' => $rows,
41 'fields' => $fields['fields']
42 ];
43
44 return $response;
45 }
46
47 public function create(Request $request, Webhook $webhook)
48 {
49 $name = $request->name;
50 $boardId = $request->getSafe('board', 'intval');
51 $stageId = $request->getSafe('stage', 'intval');
52 // Sanitize name field
53 $name = sanitize_text_field($name);
54
55 if(!$name || !$boardId || !$stageId) {
56 return $this->sendError('Name, board and stage are required');
57 }
58
59 $webhook = $webhook->store([
60 'name' => $name,
61 'board' => $boardId,
62 'stage' => $stageId,
63 ]);
64
65 return [
66 'id' => $webhook->id,
67 'webhook' => $webhook->value,
68 'webhooks' => $webhook->latest()->get(),
69 'message' => __('Successfully Created the WebHook', 'fluent-boards'),
70 ];
71 }
72
73 public function update(Request $request, Webhook $webhook, $id)
74 {
75 $id = absint($id);
76 $data = $request->only(['name']);
77 // Sanitize data if needed based on webhook structure
78 if (isset($data['name'])) {
79 $data['name'] = sanitize_text_field($data['name']);
80 }
81
82 $foundWebhook = $webhook->find($id);
83 if (!$foundWebhook) {
84 return $this->sendError(__('Webhook not found', 'fluent-boards'), 404);
85 }
86
87 $foundWebhook->saveChanges($data);
88
89 return [
90 'webhooks' => $webhook->latest()->get(),
91 'message' => __('Successfully updated the webhook', 'fluent-boards'),
92 ];
93 }
94
95 public function delete(Webhook $webhook, $id)
96 {
97 $id = absint($id);
98 $webhook->where('id', $id)->delete();
99
100 return [
101 'webhooks' => $webhook->latest()->get(),
102 'message' => __('Successfully deleted the webhook', 'fluent-boards'),
103 ];
104 }
105
106 // Outgoing Webhook Methods
107 public function outgoingWebhooks(Request $request, Meta $meta)
108 {
109 $search = $request->getSafe('search', 'sanitize_text_field', '');
110 $boardId = $request->getSafe('board_id', 'intval');
111
112 $webhooks = $meta->where('object_type', 'outgoing_webhook')
113 ->latest()
114 ->get()
115 ->toArray();
116
117 // Add board filtering logic
118 if ($boardId) {
119 $webhooks = array_filter($webhooks, function($row) use ($boardId) {
120 if (!isset($row['value']['board_id'])) {
121 return false;
122 }
123
124 $webhookBoardId = $row['value']['board_id'];
125
126 // Handle array of board IDs
127 if (is_array($webhookBoardId)) {
128 return in_array($boardId, array_map('intval', $webhookBoardId));
129 }
130
131 // Handle single board ID or null (all boards)
132 return $webhookBoardId === null || intval($webhookBoardId) === $boardId;
133 });
134 }
135
136 if (!empty($search)) {
137 $search = strtolower($search);
138 $webhooks = array_map(function ($row) use ($search) {
139 $name = strtolower($row['value']['name']);
140 if ($row['value'] && str_contains($name, $search)) {
141 return $row;
142 }
143 return null;
144 }, $webhooks);
145 }
146
147 $rows = [];
148 foreach ($webhooks as $row) {
149 if ($row) {
150 $rows[] = $row;
151 }
152 }
153
154 return [
155 'webhooks' => $rows
156 ];
157 }
158
159 public function createOutgoingWebhook(Request $request)
160 {
161 $data = $this->validate(
162 $request->only(['name', 'url', 'board_id', 'triggered_events', 'event_mode', 'header_type', 'headers']),
163 [
164 'name' => 'required',
165 'url' => 'required',
166 'board_id' => 'array',
167 'triggered_events' => 'array',
168 ]
169 );
170
171 $data['name'] = sanitize_text_field($data['name']);
172 $data['url'] = sanitize_url($data['url']);
173
174 // Sanitize header_type if present
175 if (isset($data['header_type'])) {
176 $data['header_type'] = sanitize_text_field($data['header_type']);
177 }
178
179 if(isset($data['header_type']) && $data['header_type'] == 'with_headers') {
180 // sanitize all headers key and value
181 if (!empty($data['headers']) && is_array($data['headers'])) {
182 foreach ($data['headers'] as $index => $header) {
183 if (isset($header['name'])) {
184 $data['headers'][$index]['name'] = sanitize_text_field($header['name']);
185 }
186 if (isset($header['value'])) {
187 $data['headers'][$index]['value'] = sanitize_text_field($header['value']);
188 }
189 }
190 }
191 }
192
193 $data['event_mode'] = ($data['event_mode'] ?? 'selected') === 'all' ? 'all' : 'selected';
194 $data['triggered_events'] = array_values(array_filter(array_map('sanitize_text_field', $data['triggered_events'] ?? [])));
195 if ($data['event_mode'] !== 'all' && !$data['triggered_events']) {
196 return $this->sendError(__('At least one event must be selected for the webhook to be triggered.', 'fluent-boards'));
197 }
198
199 // Sanitize board_id array to integers
200 if (!empty($data['board_id']) && is_array($data['board_id'])) {
201 $data['board_id'] = array_filter(array_map('intval', $data['board_id']));
202 } else {
203 $data['board_id'] = [];
204 }
205
206 $webhook = Meta::create([
207 'object_type' => 'outgoing_webhook',
208 'value' => $data
209 ]);
210
211 foreach ($data['board_id'] as $boardId) {
212 $boardId = absint($boardId);
213 Relation::create([
214 'object_id' => $webhook->id,
215 'object_type' => 'outgoing_webhook_board',
216 'foreign_id' => $boardId,
217 'settings' => \maybe_serialize($data['triggered_events'] ?? []),
218 'preferences' => ['event_mode' => $data['event_mode']]
219 ]);
220 }
221
222
223 return [
224 'id' => $webhook->id,
225 'webhook' => $webhook->value,
226 'webhooks' => Meta::where('object_type', 'outgoing_webhook')->latest()->get(),
227 'message' => __('Successfully Created the Outgoing WebHook', 'fluent-boards'),
228 ];
229 }
230
231 public function updateOutgoingWebhook(Request $request, $id)
232 {
233 $id = absint($id);
234 $data = $this->validate(
235 $request->all(),
236 [
237 'name' => 'required',
238 'url' => 'required',
239 'board_id' => 'array',
240 'triggered_events' => 'array',
241 ]
242 );
243
244 $data['name'] = sanitize_text_field($data['name']);
245 $data['url'] = sanitize_url($data['url']);
246
247 // Sanitize header_type if present
248 if (isset($data['header_type'])) {
249 $data['header_type'] = sanitize_text_field($data['header_type']);
250 }
251
252 if(isset($data['header_type']) && $data['header_type'] == 'with_headers') {
253 // sanitize all headers key and value
254 if (!empty($data['headers']) && is_array($data['headers'])) {
255 foreach ($data['headers'] as $index => $header) {
256 if (isset($header['name'])) {
257 $data['headers'][$index]['name'] = sanitize_text_field($header['name']);
258 }
259 if (isset($header['value'])) {
260 $data['headers'][$index]['value'] = sanitize_text_field($header['value']);
261 }
262 }
263 }
264 }
265
266 // Requests from legacy clients remain explicit subscriptions.
267 $data['event_mode'] = ($data['event_mode'] ?? 'selected') === 'all' ? 'all' : 'selected';
268 $data['triggered_events'] = array_values(array_filter(array_map('sanitize_text_field', $data['triggered_events'] ?? [])));
269
270 // Sanitize board_id array to integers
271 if (!empty($data['board_id']) && is_array($data['board_id'])) {
272 $data['board_id'] = array_filter(array_map('intval', $data['board_id']));
273 } else {
274 $data['board_id'] = [];
275 }
276
277 $webhook = Meta::find($id);
278
279 if (!$webhook || $webhook->object_type !== 'outgoing_webhook') {
280 return $this->sendError('Outgoing webhook not found.', 404);
281 }
282
283 $webhook->value = $data;
284 $webhook->save();
285
286
287 // Update relations
288 Relation::where('object_type', 'outgoing_webhook_board')
289 ->where('object_id', $webhook->id)
290 ->delete();
291
292 // Recreate relations
293 foreach ($data['board_id'] as $boardId) {
294 $boardId = absint($boardId);
295 Relation::create([
296 'object_id' => $webhook->id,
297 'object_type' => 'outgoing_webhook_board',
298 'foreign_id' => $boardId,
299 'settings' => \maybe_serialize($data['triggered_events'] ?? []),
300 'preferences' => ['event_mode' => $data['event_mode']]
301 ]);
302 }
303
304
305 return [
306 'webhooks' => Meta::where('object_type', 'outgoing_webhook')->latest()->get(),
307 'message' => __('Successfully updated the outgoing webhook', 'fluent-boards'),
308 ];
309 }
310
311 public function deleteOutgoingWebhook($id)
312 {
313 $id = absint($id);
314 $webhook = Meta::find($id);
315
316 if (!$webhook || $webhook->object_type !== 'outgoing_webhook') {
317 return $this->sendError('Outgoing webhook not found.', 404);
318 }
319
320 // Delete associated relations
321 Relation::where('object_type', 'outgoing_webhook_board')
322 ->where('object_id', $webhook->id)
323 ->delete();
324
325
326 $webhook->delete();
327
328 return [
329 'webhooks' => Meta::where('object_type', 'outgoing_webhook')->latest()->get(),
330 'message' => __('Successfully deleted the outgoing webhook', 'fluent-boards'),
331 ];
332 }
333 }
334