PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
← All changes | app/Modules/Logger/DataLogger.php +246 -56 3.6.226.2.14 View file →
@@ -1,7 +1,10 @@
1 1 <?php namespace FluentForm\App\Modules\Logger;
2 2
3 -use FluentForm\App\Databases\Migrations\FormLogs;
3 +use FluentForm\App\Helpers\Helper;
4 +use FluentForm\Database\Migrations\Logs;
5 +use FluentForm\App\Modules\Form\FormDataParser;
6 +use FluentForm\App\Modules\Form\FormFieldsParser;
4 7 use FluentForm\Framework\Foundation\Application;
5 8 use FluentForm\Framework\Helpers\ArrayHelper;
6 9
7 10 class DataLogger
@@ -14,12 +17,14 @@
14 17 }
15 18
16 19 public function getLogFilters()
17 20 {
21 + // SECURITY (H-02): unregistered handler; guard it so it is safe if ever wired to an action.
22 + \FluentForm\App\Modules\Acl\Acl::verify('fluentform_settings_manager');
18 23 $statuses = wpFluent()->table('fluentform_logs')
19 - ->select('status')
20 - ->groupBy('status')
21 - ->get();
24 + ->select('status')
25 + ->groupBy('status')
26 + ->get();
22 27 $formattedStatuses = [];
23 28
24 29 foreach ($statuses as $status) {
25 30 $formattedStatuses[] = $status->status;
@@ -24,8 +29,18 @@
24 29 foreach ($statuses as $status) {
25 30 $formattedStatuses[] = $status->status;
26 31 }
27 32
33 + $apis = wpFluent()->table('ff_scheduled_actions')
34 + ->select('status')
35 + ->groupBy('status')
36 + ->get();
37 +
38 + $apiStatuses = [];
39 + foreach ($apis as $api) {
40 + $apiStatuses[] = $api->status;
41 + }
42 +
28 43 $components = wpFluent()->table('fluentform_logs')
29 44 ->select('component')
30 45 ->groupBy('component')
31 46 ->get();
@@ -46,16 +61,18 @@
46 61
47 62 foreach ($forms as $form) {
48 63 $formattedForms[] = [
49 64 'form_id' => $form->parent_source_id,
50 - 'title' => $form->title
51 - ];;
65 + 'title' => $form->title,
66 + ];
67 +
52 68 }
53 69
54 70 wp_send_json_success([
55 - 'available_statuses' => $formattedStatuses,
71 + 'available_statuses' => $formattedStatuses,
56 72 'available_components' => $formattedComponents,
57 - 'available_forms' => $formattedForms
73 + 'available_forms' => $formattedForms,
74 + 'api_statuses' => $apiStatuses,
58 75 ]);
59 76 }
60 77
61 78 public function log($data)
@@ -62,21 +79,34 @@
62 79 {
63 80 if (!$data) {
64 81 return;
65 82 }
83 +
84 + if (isset($data['description'])) {
85 + $data['description'] = wp_kses($data['description'], [
86 + 'br' => [],
87 + 'b' => [],
88 + 'strong' => [],
89 + 'i' => [],
90 + 'em' => [],
91 + 'code' => [],
92 + 'p' => [],
93 + 'a' => ['href' => [], 'title' => [], 'target' => [], 'rel' => []],
94 + ]);
95 + }
96 +
66 97 $data['created_at'] = current_time('mysql');
67 98
68 99 if (!get_option('fluentform_db_fluentform_logs_added')) {
69 - FormLogs::migrate();
100 + Logs::migrate();
70 101 }
71 102
72 - return wpFluent()->table('fluentform_logs')
73 - ->insert($data);
103 + wpFluent()->table('fluentform_logs')->insert($data);
74 104 }
75 105
76 106 public function getLogsByEntry($entry_id, $log_type = 'logs', $sourceType = 'submission_item')
77 107 {
78 - if($log_type == 'logs') {
108 + if ($log_type == 'logs') {
79 109 $logs = wpFluent()->table('fluentform_logs')
80 110 ->where('source_id', $entry_id)
81 111 ->where('source_type', $sourceType)
82 112 ->orderBy('id', 'DESC')
@@ -81,9 +111,20 @@
81 111 ->where('source_type', $sourceType)
82 112 ->orderBy('id', 'DESC')
83 113 ->get();
84 114
85 - $logs = apply_filters('fluentform_entry_logs', $logs, $entry_id);
115 + $logs = apply_filters_deprecated(
116 + 'fluentform_entry_logs',
117 + [
118 + $logs,
119 + $entry_id,
120 + ],
121 + FLUENTFORM_FRAMEWORK_UPGRADE,
122 + 'fluentform/submission_logs',
123 + 'Use fluentform/submission_logs instead of fluentform_entry_logs.'
124 + );
125 +
126 + $logs = apply_filters('fluentform/submission_logs', $logs, $entry_id);
86 127 } else {
87 128 $logs = wpFluent()->table('ff_scheduled_actions')
88 129 ->select([
89 130 'id',
@@ -89,27 +130,39 @@
89 130 'id',
90 131 'action',
91 132 'status',
92 133 'note',
93 - 'created_at'
134 + 'created_at',
94 135 ])
95 136 ->where('origin_id', $entry_id)
96 137 ->orderBy('id', 'DESC')
97 138 ->get();
98 139
99 - $logs = apply_filters('fluentform_entry_api_logs', $logs, $entry_id);
140 + $logs = apply_filters_deprecated(
141 + 'fluentform_entry_api_logs',
142 + [
143 + $logs,
144 + $entry_id,
145 + ],
146 + FLUENTFORM_FRAMEWORK_UPGRADE,
147 + 'fluentform/submission_api_logs',
148 + 'Use fluentform/submission_api_logs instead of fluentform_entry_api_logs.'
149 + );
150 +
151 + $logs = apply_filters('fluentform/submission_api_logs', $logs, $entry_id);
100 152 }
101 153
102 -
103 154 wp_send_json_success([
104 - 'logs' => $logs
155 + 'logs' => $logs,
105 156 ], 200);
106 157 }
107 158
108 159 public function getAllLogs()
109 160 {
110 - $limit = intval($_REQUEST['per_page']);
111 - $pageNumber = intval($_REQUEST['page_number']);
161 + // SECURITY (H-02): unregistered handler; guard it so it is safe if ever wired to an action.
162 + \FluentForm\App\Modules\Acl\Acl::verify('fluentform_settings_manager');
163 + $limit = intval($this->app->request->get('per_page'));
164 + $pageNumber = intval($this->app->request->get('page_number'));
112 165
113 166 $skip = ($pageNumber - 1) * $limit;
114 167
115 168 global $wpdb;
@@ -114,51 +167,72 @@
114 167
115 168 global $wpdb;
116 169 $logsQuery = wpFluent()->table('fluentform_logs')
117 170 ->select([
118 - 'fluentform_logs.*'
171 + 'fluentform_logs.*',
172 + wpFluent()->raw($wpdb->prefix . 'fluentform_forms.title as form_title'),
173 + wpFluent()->raw($wpdb->prefix . 'fluentform_logs.parent_source_id as form_id'),
174 + wpFluent()->raw($wpdb->prefix . 'fluentform_logs.source_id as entry_id'),
119 175 ])
120 - ->select(wpFluent()->raw( $wpdb->prefix.'fluentform_forms.title as form_title' ))
121 - ->join('fluentform_forms', 'fluentform_forms.id', '=', 'fluentform_logs.parent_source_id')
122 - ->orderBy('fluentform_logs.id', 'DESC')
123 - ->whereIn('fluentform_logs.source_type', ['submission_item', 'form_item']);
176 + ->leftJoin('fluentform_forms', 'fluentform_forms.id', '=', 'fluentform_logs.parent_source_id')
177 + ->orderBy('fluentform_logs.id', 'DESC');
178 + // ->whereIn('fluentform_logs.source_type', ['submission_item', 'form_item']);
124 179
125 -
126 - if($parentSourceId = ArrayHelper::get($_REQUEST, 'parent_source_id')) {
180 + if ($parentSourceId = $this->app->request->get('parent_source_id')) {
127 181 $logsQuery = $logsQuery->where('fluentform_logs.parent_source_id', intval($parentSourceId));
128 182 }
129 183
130 - if($status = ArrayHelper::get($_REQUEST, 'status')) {
131 - $logsQuery = $logsQuery->where('fluentform_logs.status', $status);
184 + if ($status = $this->app->request->get('status')) {
185 + $logsQuery = $logsQuery->where('fluentform_logs.status', sanitize_text_field($status));
132 186 }
133 187
134 - if($component = ArrayHelper::get($_REQUEST, 'component')) {
135 - $logsQuery = $logsQuery->where('fluentform_logs.component', $component);
188 + if ($component = $this->app->request->get('component')) {
189 + $logsQuery = $logsQuery->where('fluentform_logs.component', sanitize_text_field($component));
136 190 }
137 191
192 + if ($formId = $this->app->request->get('form_id')) {
193 + $logsQuery = $logsQuery->where('fluentform_forms.id', intval($formId));
194 + }
138 195
139 196 $logsQueryMain = $logsQuery;
140 197
141 - $logs = $logsQuery->offset($skip)
198 + $logs = $logsQuery->offset($skip)
142 199 ->limit($limit)
143 200 ->get();
144 201
145 - $logs = apply_filters('fluentform_all_logs', $logs);
202 + foreach ($logs as $log) {
203 + if ('submission_item' == $log->source_type && $log->entry_id) {
204 + $log->submission_url = admin_url('admin.php?page=fluent_forms&route=entries&form_id=' . $log->form_id . '#/entries/' . $log->entry_id);
205 + }
206 + }
146 207
208 + $logs = apply_filters_deprecated(
209 + 'fluentform_all_logs',
210 + [
211 + $logs,
212 + ],
213 + FLUENTFORM_FRAMEWORK_UPGRADE,
214 + 'fluentform/all_logs',
215 + 'Use fluentform/all_logs instead of fluentform_all_logs.'
216 + );
217 +
218 + $logs = apply_filters('fluentform/all_logs', $logs);
219 +
147 220 $total = $logsQueryMain->count();
148 221
149 222 wp_send_json_success([
150 223 'logs' => $logs,
151 - 'total' => $total
224 + 'total' => $total,
152 225 ], 200);
153 -
154 226 }
155 227
156 228
157 229 public function getApiLogs()
158 230 {
159 - $limit = intval($_REQUEST['per_page']);
160 - $pageNumber = intval($_REQUEST['page_number']);
231 + // SECURITY (H-02): unregistered handler; guard it so it is safe if ever wired to an action.
232 + \FluentForm\App\Modules\Acl\Acl::verify('fluentform_settings_manager');
233 + $limit = intval($this->app->request->get('per_page'));
234 + $pageNumber = intval($this->app->request->get('page_number'));
161 235
162 236 $skip = ($pageNumber - 1) * $limit;
163 237 global $wpdb;
164 238 $logsQuery = wpFluent()->table('ff_scheduled_actions')
@@ -169,22 +243,25 @@
169 243 'ff_scheduled_actions.origin_id',
170 244 'ff_scheduled_actions.status',
171 245 'ff_scheduled_actions.note',
172 246 'ff_scheduled_actions.created_at',
247 + wpFluent()->raw($wpdb->prefix . 'fluentform_forms.title as form_title'),
173 248 ])
174 - ->select(wpFluent()->raw( $wpdb->prefix.'fluentform_forms.title as form_title' ))
175 249 ->join('fluentform_forms', 'fluentform_forms.id', '=', 'ff_scheduled_actions.form_id')
176 250 ->orderBy('ff_scheduled_actions.id', 'DESC');
177 251
178 -
179 - if($formId = ArrayHelper::get($_REQUEST, 'form_id')) {
252 + if ($formId = $this->app->request->get('form_id')) {
180 253 $logsQuery = $logsQuery->where('ff_scheduled_actions.form_id', intval($formId));
181 254 }
182 255
183 - if($status = ArrayHelper::get($_REQUEST, 'status')) {
256 + if ($status = $this->app->request->get('status')) {
184 257 $logsQuery = $logsQuery->where('ff_scheduled_actions.status', $status);
185 258 }
186 259
260 + if ($component = $this->app->request->get('component')) {
261 + $logsQuery = $logsQuery->where('ff_scheduled_actions.action', $component);
262 + }
263 +
187 264 $logsQueryMain = $logsQuery;
188 265
189 266 $logs = $logsQuery->offset($skip)
190 267 ->limit($limit)
@@ -189,12 +266,22 @@
189 266 $logs = $logsQuery->offset($skip)
190 267 ->limit($limit)
191 268 ->get();
192 269
193 - $logs = apply_filters('fluentform_api_all_logs', $logs);
270 + $logs = apply_filters_deprecated(
271 + 'fluentform_api_all_logs',
272 + [
273 + $logs,
274 + ],
275 + FLUENTFORM_FRAMEWORK_UPGRADE,
276 + 'fluentform/api_all_logs',
277 + 'Use fluentform/api_all_logs instead of fluentform_api_all_logs.'
278 + );
194 279
280 + $logs = apply_filters('fluentform/api_all_logs', $logs);
281 +
195 282 foreach ($logs as $log) {
196 - $log->submission_url = admin_url('admin.php?page=fluent_forms&route=entries&form_id='.$log->form_id.'#/entries/'.$log->origin_id);
283 + $log->submission_url = admin_url('admin.php?page=fluent_forms&route=entries&form_id=' . $log->form_id . '#/entries/' . $log->origin_id);
197 284 }
198 285
199 286 $total = $logsQueryMain->count();
200 287
@@ -199,43 +286,42 @@
199 286 $total = $logsQueryMain->count();
200 287
201 288 wp_send_json_success([
202 289 'logs' => $logs,
203 - 'total' => $total
290 + 'total' => $total,
204 291 ], 200);
205 -
206 292 }
207 293
208 294 public function deleteLogsByIds($ids = [])
209 295 {
210 - if(!$ids) {
211 - $ids = wp_unslash($_REQUEST['log_ids']);
296 + if (!$ids) {
297 + $ids = wp_unslash($this->app->request->get('log_ids'));
212 298 }
213 299
214 - if(!$ids) {
300 + if (!$ids) {
215 301 wp_send_json_error([
216 - 'message' => 'No selections found'
302 + 'message' => 'No selections found',
217 303 ], 423);
218 304 }
219 305
220 - wpFluent()->table('fluentform_logs')
306 + wpFluent()->table('fluentform_logs')
221 307 ->whereIn('id', $ids)
222 - ->delete();
308 + ->delete();
223 309
224 310 wp_send_json_success([
225 - 'message' => __('Selected logs successfully deleted', 'fluentform')
311 + 'message' => __('Selected log(s) successfully deleted', 'fluentform'),
226 312 ], 200);
227 313 }
228 314
229 315 public function deleteApiLogsByIds($ids = [])
230 316 {
231 - if(!$ids) {
232 - $ids = wp_unslash($_REQUEST['log_ids']);
317 + if (!$ids) {
318 + $ids = wp_unslash($this->app->request->get('log_ids'));
233 319 }
234 320
235 - if(!$ids) {
321 + if (!$ids) {
236 322 wp_send_json_error([
237 - 'message' => 'No selections found'
323 + 'message' => 'No selections found',
238 324 ], 423);
239 325 }
240 326
241 327 wpFluent()->table('ff_scheduled_actions')
@@ -242,8 +328,112 @@
242 328 ->whereIn('id', $ids)
243 329 ->delete();
244 330
245 331 wp_send_json_success([
246 - 'message' => __('Selected logs successfully deleted', 'fluentform')
332 + 'message' => __('Selected log(s) successfully deleted', 'fluentform'),
247 333 ], 200);
334 + }
335 +
336 + public function retryApiAction()
337 + {
338 + // SECURITY (H-02): unregistered handler; guard it so it is safe if ever wired to an action.
339 + \FluentForm\App\Modules\Acl\Acl::verify('fluentform_settings_manager');
340 + $logId = $this->app->request->get('log_id');
341 + $actionFeed = wpFluent()->table('ff_scheduled_actions')
342 + ->find($logId);
343 +
344 + if (!$actionFeed) {
345 + wp_send_json_error([
346 + 'message' => 'API log does not exist',
347 + ], 423);
348 + }
349 +
350 + if ($actionFeed->status == 'success') {
351 + wp_send_json_error([
352 + 'message' => 'API log already in success mode',
353 + ], 423);
354 + }
355 +
356 + $form = wpFluent()->table('fluentform_forms')->find($actionFeed->form_id);
357 +
358 + $feed = Helper::safeUnserialize($actionFeed->data);
359 + $feed['scheduled_action_id'] = $actionFeed->id;
360 +
361 + $submission = wpFluent()->table('fluentform_submissions')->find($actionFeed->origin_id);
362 + $entry = $this->getEntry($submission, $form);
363 + $formData = json_decode($submission->response, true);
364 +
365 + wpFluent()->table('ff_scheduled_actions')
366 + ->where('id', $actionFeed->id)
367 + ->update([
368 + 'status' => 'manual_retry',
369 + 'retry_count' => $actionFeed->retry_count + 1,
370 + 'updated_at' => current_time('mysql'),
371 + ]);
372 +
373 + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.DynamicHooknameFound -- Dynamic hook name from action feed
374 + do_action($actionFeed->action, $feed, $formData, $entry, $form);
375 +
376 + /*
377 + * Hopefully it's done
378 + */
379 + $actionFeed = wpFluent()->table('ff_scheduled_actions')
380 + ->find($logId);
381 +
382 + wp_send_json_success([
383 + 'message' => 'Retry completed',
384 + 'feed' => $actionFeed,
385 + ], 200);
386 + }
387 +
388 + private function getEntry($submission, $form)
389 + {
390 + $formInputs = FormFieldsParser::getEntryInputs($form, ['admin_label', 'raw']);
391 + return FormDataParser::parseFormEntry($submission, $form, $formInputs);
392 + }
393 +
394 + public function getApiLogFilters()
395 + {
396 + $apis = wpFluent()->table('ff_scheduled_actions')
397 + ->select('status')
398 + ->groupBy('status')
399 + ->get();
400 +
401 + $apiStatuses = [];
402 + foreach ($apis as $api) {
403 + $apiStatuses[] = $api->status;
404 + }
405 +
406 + $components = wpFluent()->table('ff_scheduled_actions')
407 + ->select('action')
408 + ->groupBy('action')
409 + ->get();
410 +
411 + $formattedComponents = [];
412 + foreach ($components as $component) {
413 + $formattedComponents[] = $component->action;
414 + }
415 +
416 + $forms = wpFluent()->table('ff_scheduled_actions')
417 + ->select('ff_scheduled_actions.form_id', 'fluentform_forms.title')
418 + ->groupBy('ff_scheduled_actions.form_id')
419 + ->orderBy('ff_scheduled_actions.form_id', 'DESC')
420 + ->join('fluentform_forms', 'fluentform_forms.id', '=', 'ff_scheduled_actions.form_id')
421 + ->get();
422 +
423 + $formattedForms = [];
424 +
425 + foreach ($forms as $form) {
426 + $formattedForms[] = [
427 + 'form_id' => $form->form_id,
428 + 'title' => $form->title,
429 + ];
430 +
431 + }
432 +
433 + wp_send_json_success([
434 + 'available_components' => $formattedComponents,
435 + 'available_forms' => $formattedForms,
436 + 'api_statuses' => $apiStatuses,
437 + ]);
248 438 }
249 439 }