PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 3.6.65
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v3.6.65
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
fluentform / app / Modules / Entries / Entries.php

Entries.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 3.6.65, at app/Modules/Entries/Entries.php

755 lines 24.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Modules\Entries;
4
5 use FluentForm\App\Helpers\Helper;
6 use FluentForm\App\Modules\Form\FormDataParser;
7 use FluentForm\App\Modules\Form\FormFieldsParser;
8 use FluentForm\Framework\Helpers\ArrayHelper;
9 use FluentForm\View;
10
11 class Entries extends EntryQuery
12 {
13 /**
14 * The form response model.
15 *
16 * @var \WpFluent\QueryBuilder\QueryBuilderHandler $responseMetaModel
17 */
18 protected $responseMetaModel;
19
20 /**
21 * Entries constructor.
22 *
23 * @throws \Exception
24 */
25 public function __construct()
26 {
27 parent::__construct();
28
29 $this->responseMetaModel = wpFluent()->table('fluentform_submission_meta');
30 }
31
32 public function getAllFormEntries()
33 {
34 $formId = intval($this->request->get('form_id'));
35
36
37 $limit = $this->request->get('per_page', 10);
38 $page = $this->request->get('page', 1);
39 $offset = ($page - 1) * $limit;
40
41 $search = $this->request->get('search');
42 $status = $this->request->get('entry_status');
43
44 $query = wpFluent()->table('fluentform_submissions')
45 ->select([
46 'fluentform_submissions.id',
47 'fluentform_submissions.form_id',
48 'fluentform_submissions.status',
49 'fluentform_submissions.created_at',
50 'fluentform_submissions.browser',
51 'fluentform_submissions.currency',
52 'fluentform_submissions.total_paid',
53 'fluentform_forms.title',
54 ])
55 ->join('fluentform_forms', 'fluentform_forms.id', '=', 'fluentform_submissions.form_id')
56 ->orderBy('fluentform_submissions.id', 'DESC')
57 ->limit($limit)
58 ->offset($offset);
59
60 if ($formId) {
61 $query->where('fluentform_submissions.form_id', $formId);
62 }
63
64 if ($status) {
65 $query->where('fluentform_submissions.status', $status);
66 } else {
67 $query->where('fluentform_submissions.status', '!=', 'trashed');
68 }
69
70 if ($search) {
71 $query->where('fluentform_submissions.response', 'LIKE', '%' . $search . '%');
72 }
73
74 $total = $query->count();
75 $entries = $query->get();
76 foreach ($entries as $entry) {
77 $entry->entry_url = admin_url('admin.php?page=fluent_forms&route=entries&form_id=' . $entry->form_id . '#/entries/' . $entry->id);
78 $entry->human_date = human_time_diff(strtotime($entry->created_at), strtotime(current_time('mysql')));
79 }
80 wp_send_json_success([
81 'entries' => $entries,
82 'total' => $total,
83 'last_page' => ceil($total / $limit)
84 ]);
85 }
86
87 public function getEntriesReport()
88 {
89 $from = date('Y-m-d H:i:s', strtotime('-30 days'));
90 $to = date('Y-m-d H:i:s', strtotime('+1 days'));
91 $period = new \DatePeriod(new \DateTime($from), new \DateInterval('P1D'), new \DateTime($to));
92
93 $range = [];
94
95 foreach ($period as $date) {
96 $range[$date->format('Y-m-d')] = 0;
97 }
98 $itemsQuery = wpFluent()->table('fluentform_submissions')->select([
99 wpFluent()->raw('DATE(created_at) AS date'),
100 wpFluent()->raw('COUNT(id) AS count'),
101 ])
102 ->whereBetween('created_at', $from, $to)
103 ->groupBy('date')
104 ->orderBy('date', 'ASC');
105
106 $formId = $this->request->get('form_id');
107
108 if ($formId) {
109 $itemsQuery = $itemsQuery->where('form_id', $formId);
110 }
111
112 $items = $itemsQuery->get();
113 foreach ($items as $item) {
114 $range[$item->date] = $item->count; //Filling value in the array
115 }
116
117 wp_send_json_success([
118 'stats' => $range
119 ]);
120
121 }
122
123 public function renderEntries($form_id)
124 {
125 wp_enqueue_script('fluentform_form_entries');
126
127 $forms = wpFluent()
128 ->table('fluentform_forms')
129 ->select(['id', 'title'])
130 ->orderBy('id', 'DESC')
131 ->get();
132
133 $emailNotifications = wpFluent()
134 ->table('fluentform_form_meta')
135 ->where('form_id', $form_id)
136 ->where('meta_key', 'notifications')
137 ->get();
138
139 $formattedNotification = [];
140
141 foreach ($emailNotifications as $notification) {
142 $value = \json_decode($notification->value, true);
143 $formattedNotification[] = [
144 'id' => $notification->id,
145 'name' => ArrayHelper::get($value, 'name')
146 ];
147 }
148
149 $form = wpFluent()->table('fluentform_forms')->find($form_id);
150
151
152 $app = wpFluentForm();
153
154 $fluentFormEntriesVars = apply_filters('fluent_form_entries_vars', [
155 'all_forms_url' => admin_url('admin.php?page=fluent_forms'),
156 'forms' => $forms,
157 'form_id' => $form->id,
158 'enabled_auto_delete' => Helper::isEntryAutoDeleteEnabled($form_id),
159 'current_form_title' => $form->title,
160 'entry_statuses' => Helper::getEntryStatuses($form_id),
161 'entries_url_base' => admin_url('admin.php?page=fluent_forms&route=entries&form_id='),
162 'no_found_text' => __('Sorry! No entries found. All your entries will be shown here once you start getting form submissions', 'fluentform'),
163 'has_pro' => defined('FLUENTFORMPRO'),
164 'printStyles' => [fluentformMix('css/settings_global.css')],
165 'email_notifications' => $formattedNotification,
166 'available_countries' => $app->load(
167 $app->appPath('Services/FormBuilder/CountryNames.php')
168 ),
169 'upgrade_url' => fluentform_upgrade_url()
170 ], $form);
171
172 wp_localize_script(
173 'fluentform_form_entries', 'fluent_form_entries_vars', $fluentFormEntriesVars
174 );
175
176 View::render('admin.form.entries', [
177 'form_id' => $form_id,
178 'has_pdf' => defined('FLUENTFORM_PDF_VERSION') ? 'true' : 'false'
179 ]);
180 }
181
182 public function getEntriesGroup()
183 {
184 $formId = intval($this->request->get('form_id'));
185 $counts = $this->groupCount($formId);
186 wp_send_json_success([
187 'counts' => $counts
188 ], 200);
189 }
190
191 public function _getEntries(
192 $formId,
193 $currentPage,
194 $perPage,
195 $sortBy,
196 $entryType,
197 $search,
198 $wheres = []
199 )
200 {
201 $this->formId = $formId;
202 $this->per_page = $perPage;
203 $this->sort_by = $sortBy;
204 $this->page_number = $currentPage;
205 $this->search = $search;
206 $this->wheres = $wheres;
207
208 if ($entryType == 'favorite') {
209 $this->is_favourite = true;
210 } elseif ($entryType != 'all' && $entryType) {
211 $this->status = $entryType;
212 }
213
214 $dateRange = $this->request->get('date_range');
215 if ($dateRange) {
216 $this->startDate = $dateRange[0];
217 $this->endDate = $dateRange[1];
218 }
219
220 $form = $this->formModel->find($formId);
221 $formMeta = $this->getFormInputsAndLabels($form);
222 $formLabels = $formMeta['labels'];
223 $formLabels = apply_filters('fluentfoform_entry_lists_labels', $formLabels, $form);
224 $submissions = $this->getResponses();
225 $submissions['data'] = FormDataParser::parseFormEntries($submissions['data'], $form);
226
227 return compact('submissions', 'formLabels');
228 }
229
230 public function getEntries()
231 {
232 if (!defined('FLUENTFORM_RENDERING_ENTRIES')) {
233 define('FLUENTFORM_RENDERING_ENTRIES', true);
234 }
235
236 $wheres = [];
237
238 if ($paymentStatuses = $this->request->get('payment_statuses')) {
239 if (is_array($paymentStatuses)) {
240 $wheres[] = ['payment_status', $paymentStatuses];
241 }
242 }
243
244 $entries = $this->_getEntries(
245 intval($this->request->get('form_id')),
246 intval($this->request->get('current_page', 1)),
247 intval($this->request->get('per_page', 10)),
248 sanitize_text_field($this->request->get('sort_by', 'DESC')),
249 sanitize_text_field($this->request->get('entry_type', 'all')),
250 sanitize_text_field($this->request->get('search')),
251 $wheres
252 );
253
254
255 $labels = apply_filters(
256 'fluentform_all_entry_labels', $entries['formLabels'], $this->request->get('form_id')
257 );
258
259 $form = $this->formModel->find($this->request->get('form_id'));
260
261 if ($form->has_payment) {
262 $labels = apply_filters(
263 'fluentform_all_entry_labels_with_payment', $entries['formLabels'], false, $form
264 );
265 }
266
267 wp_send_json_success([
268 'submissions' => apply_filters('fluentform_all_entries', $entries['submissions']),
269 'labels' => $labels
270 ], 200);
271 }
272
273 public function _getEntry()
274 {
275 $this->formId = intval($this->request->get('form_id'));
276
277 $entryId = intval($this->request->get('entry_id'));
278
279 $entry_type = sanitize_text_field($this->request->get('entry_type', 'all'));
280
281 if ($entry_type === 'favorite') {
282 $this->is_favourite = true;
283 } elseif ($entry_type !== 'all') {
284 $this->status = $entry_type;
285 }
286
287 $this->sort_by = sanitize_text_field($this->request->get('sort_by', 'ASC'));
288
289 $this->search = sanitize_text_field($this->request->get('search'));
290
291 $submission = $this->getResponse($entryId);
292
293 if (!$submission) {
294 wp_send_json_error([
295 'message' => 'No Entry found.'
296 ], 422);
297 }
298
299 $form = $this->formModel->find($this->formId);
300
301 if ($submission->status == 'unread' && apply_filters('fluentform_auto_read', true, $form)) {
302 wpFluent()->table('fluentform_submissions')
303 ->where('id', $entryId)
304 ->update([
305 'status' => 'read'
306 ]);
307
308 $submission->status = 'read';
309 }
310
311 $formMeta = $this->getFormInputsAndLabels($form);
312
313 $submission = FormDataParser::parseFormEntry($submission, $form, $formMeta['inputs'], true);
314
315 if ($submission->user_id) {
316 $user = get_user_by('ID', $submission->user_id);
317 $user_data = [
318 'name' => $user->display_name,
319 'email' => $user->user_email,
320 'ID' => $user->ID,
321 'permalink' => get_edit_user_link($user->ID)
322 ];
323 $submission->user = $user_data;
324 }
325
326 $submission = apply_filters('fluentform_single_response_data', $submission, $this->formId);
327
328 $fields = apply_filters(
329 'fluentform_single_response_input_fields', $formMeta['inputs'], $this->formId
330 );
331
332 $labels = apply_filters(
333 'fluentform_single_response_input_labels', $formMeta['labels'], $this->formId
334 );
335
336 $order_data = false;
337
338 if ($submission->payment_status || $submission->payment_total) {
339 $order_data = apply_filters(
340 'fluentform_submission_order_data', false, $submission, $form
341 );
342
343 $labels = apply_filters(
344 'fluentform_submission_entry_labels_with_payment', $labels, $submission, $form
345 );
346 }
347
348 $nextSubmissionId = $this->getNextResponse($entryId);
349
350 $previousSubmissionId = $this->getPrevResponse($entryId);
351
352 return [
353 'submission' => $submission,
354 'next' => $nextSubmissionId,
355 'prev' => $previousSubmissionId,
356 'labels' => $labels,
357 'fields' => $fields,
358 'order_data' => $order_data
359 ];
360 }
361
362 public function getEntry()
363 {
364 $entryData = $this->_getEntry();
365
366 $entryData['widgets'] = apply_filters('fluentform_single_entry_widgets', [], $entryData);
367
368 wp_send_json_success($entryData, 200);
369 }
370
371 /**
372 * @param $form
373 * @param array $with
374 *
375 * @return array
376 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
377 */
378 private function getFormInputsAndLabels($form, $with = ['admin_label', 'raw'])
379 {
380 $formInputs = FormFieldsParser::getEntryInputs($form, $with);
381 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
382 return [
383 'inputs' => $formInputs,
384 'labels' => $inputLabels
385 ];
386 }
387
388 public function getNotes()
389 {
390 $formId = intval($this->request->get('form_id'));
391 $entry_id = intval($this->request->get('entry_id'));
392 $apiLog = sanitize_text_field($this->request->get('api_log')) == 'yes';
393
394 $metaKeys = ['_notes'];
395
396 if ($apiLog) {
397 $metaKeys[] = 'api_log';
398 }
399
400 $notes = $this->responseMetaModel
401 ->where('form_id', $formId)
402 ->where('response_id', $entry_id)
403 ->whereIn('meta_key', $metaKeys)
404 ->orderBy('id', 'DESC')
405 ->get();
406
407 foreach ($notes as $note) {
408 if ($note->user_id) {
409 $note->pemalink = get_edit_user_link($note->user_id);
410 $user = get_user_by('ID', $note->user_id);
411 if ($user) {
412 $note->created_by = $user->display_name;
413 } else {
414 $note->created_by = __('Fluent Forms Bot', 'fluentform');
415 }
416 } else {
417 $note->pemalink = false;
418 }
419 }
420
421 $notes = apply_filters('fluentform_entry_notes', $notes, $entry_id, $formId);
422
423 wp_send_json_success([
424 'notes' => $notes
425 ], 200);
426 }
427
428 public function addNote()
429 {
430 $entryId = intval($this->request->get('entry_id'));
431 $formId = intval($this->request->get('form_id'));
432 $note = $this->request->get('note');
433 $note_content = sanitize_textarea_field($note['content']);
434 $note_status = sanitize_text_field($note['status']);
435 $user = get_user_by('ID', get_current_user_id());
436
437 $response_note = [
438 'response_id' => $entryId,
439 'form_id' => $formId,
440 'meta_key' => '_notes',
441 'value' => $note_content,
442 'status' => $note_status,
443 'user_id' => $user->ID,
444 'name' => $user->display_name,
445 'created_at' => current_time('mysql'),
446 'updated_at' => current_time('mysql')
447 ];
448
449 $response_note = apply_filters('fluentform_add_response_note', $response_note);
450
451 $insertId = $this->responseMetaModel->insert($response_note);
452
453 $added_note = $this->responseMetaModel->find($insertId);
454
455 do_action('fluentform_new_response_note_added', $insertId, $added_note);
456
457 wp_send_json_success([
458 'message' => __('Note has been successfully added', 'fluentform'),
459 'note' => $added_note,
460 'insert_id' => $insertId
461 ], 200);
462 }
463
464 public function changeEntryStatus()
465 {
466 $formId = intval($this->request->get('form_id'));
467 $entryId = intval($this->request->get('entry_id'));
468 $newStatus = sanitize_text_field($this->request->get('status'));
469
470 $this->responseModel
471 ->where('form_id', $formId)
472 ->where('id', $entryId)
473 ->update(['status' => $newStatus]);
474
475 wp_send_json_success([
476 'message' => __('Item has been marked as ' . $newStatus, 'fluentform'),
477 'status' => $newStatus
478 ], 200);
479 }
480
481 public function deleteEntry()
482 {
483 $formId = intval($this->request->get('form_id'));
484 $entryId = intval($this->request->get('entry_id'));
485 $newStatus = sanitize_text_field($this->request->get('status'));
486
487 $this->deleteEntryById($entryId, $formId);
488
489 wp_send_json_success([
490 'message' => __('Item Successfully deleted', 'fluentform'),
491 'status' => $newStatus
492 ], 200);
493 }
494
495 public function deleteEntryById($entryId, $formId = false)
496 {
497 do_action('fluentform_before_entry_deleted', $entryId, $formId);
498
499 $disableAttachmentDelete = apply_filters('fluentform_disable_attachment_delete', false, $formId);
500 if (defined('FLUENTFORMPRO') && $formId && !$disableAttachmentDelete) {
501 if (is_numeric($formId)) {
502 $form = wpFluent()->table('fluentform_forms')->find($formId);
503 } else {
504 $form = $formId;
505 }
506 $deletableFiles = $this->getSubmissionAttachments($entryId, $form);
507 if ($deletableFiles) {
508 foreach ($deletableFiles as $eachFile) {
509 $file = wp_upload_dir()['basedir'] . FLUENTFORM_UPLOAD_DIR . '/' . basename($eachFile);
510 if (is_readable($file) && !is_dir($file)) {
511 @unlink($file);
512 }
513 }
514 }
515 }
516
517
518 wpFluent()->table('fluentform_submissions')
519 ->where('id', $entryId)
520 ->delete();
521 wpFluent()->table('fluentform_submission_meta')
522 ->where('response_id', $entryId)
523 ->delete();
524
525 wpFluent()->table('fluentform_logs')
526 ->where('source_id', $entryId)
527 ->where('source_type', 'submission_item')
528 ->delete();
529
530 wpFluent()->table('fluentform_entry_details')
531 ->where('submission_id', $entryId)
532 ->delete();
533
534 ob_start();
535 if (defined('FLUENTFORMPRO')) {
536 try {
537 wpFluent()->table('fluentform_order_items')
538 ->where('submission_id', $entryId)
539 ->delete();
540
541
542 wpFluent()->table('fluentform_transactions')
543 ->where('submission_id', $entryId)
544 ->delete();
545
546 wpFluent()->table('ff_scheduled_actions')
547 ->where('origin_id', $entryId)
548 ->where('type', 'submission_action')
549 ->delete();
550
551 } catch (\Exception $exception) {
552 // ...
553 }
554 }
555
556
557 $errors = ob_get_clean();
558
559
560 do_action('fluentform_after_entry_deleted', $entryId, $formId);
561
562 return true;
563 }
564
565 private function getSubmissionAttachments($submissionId, $form)
566 {
567 $fields = FormFieldsParser::getAttachmentInputFields($form, ['element', 'attributes']);
568
569 $deletableFiles = [];
570 if ($fields) {
571 $submission = wpFluent()->table('fluentform_submissions')
572 ->where('id', $submissionId)
573 ->first();
574
575 $data = json_decode($submission->response, true);
576
577 foreach ($fields as $field) {
578 if (!empty($data[$field['attributes']['name']])) {
579 $files = $data[$field['attributes']['name']];
580 if (is_array($files)) {
581 $deletableFiles = array_merge($deletableFiles, $files);
582 } else {
583 $deletableFiles = $files;
584 }
585
586 }
587 }
588 }
589
590 return $deletableFiles;
591 }
592
593 public function favoriteChange()
594 {
595 $formId = intval($this->request->get('form_id'));
596 $entryId = intval($this->request->get('entry_id'));
597 $newStatus = intval($this->request->get('is_favourite'));
598 if ($newStatus) {
599 $message = __('Item has been added to favorites', 'fluentform');
600 } else {
601 $message = __('Item has been removed from favorites', 'fluentform');
602 }
603 $this->responseModel
604 ->where('form_id', $formId)
605 ->where('id', $entryId)
606 ->update(['is_favourite' => $newStatus]);
607
608 wp_send_json_success([
609 'message' => $message,
610 'is_favourite' => $newStatus
611 ], 200);
612 }
613
614 public function handleBulkAction()
615 {
616 $formId = intval($this->request->get('form_id'));
617 $entries = fluentFormSanitizer($this->request->get('entries', []));
618
619 $actionType = sanitize_text_field($this->request->get('action_type'));
620
621 // check if it's status change or not
622 $statuses = Helper::getEntryStatuses($formId);
623
624 if (!$formId || !count($entries)) {
625 wp_send_json_error([
626 'message' => __('Please select entries first', 'fluentform')
627 ], 400);
628 }
629
630 $bulkQuery = wpFluent()->table('fluentform_submissions')
631 ->where('form_id', $formId)
632 ->whereIn('id', $entries);
633
634 if (isset($statuses[$actionType])) {
635 // it's status change
636 $bulkQuery->update([
637 'status' => $actionType,
638 'updated_at' => current_time('mysql')
639 ]);
640
641 wp_send_json_success([
642 'message' => 'Selected entries successfully marked as ' . $statuses[$actionType]
643 ], 200);
644 }
645
646 // now other action handler
647 if ($actionType == 'other.delete_permanently') {
648 $form = wpFluent()->table('fluentform_forms')->find($formId);
649 foreach ($entries as $entryId) {
650 $this->deleteEntryById($entryId, $form);
651 }
652 $message = __('Selected entries successfully deleted', 'fluentform');
653
654 } elseif ($actionType == 'other.make_favorite') {
655 $bulkQuery->update([
656 'is_favourite' => 1
657 ]);
658 $message = __('Selected entries successfully marked as Favorite', 'fluentform');
659 } elseif ($actionType == 'other.unmark_favorite') {
660 $bulkQuery->update([
661 'is_favourite' => 0
662 ]);
663 $message = __('Selected entries successfully remove from favorite', 'fluentform');
664 }
665
666 wp_send_json_success([
667 'message' => $message
668 ], 200);
669 }
670
671 public function recordEntryDetails($entryId, $formId, $data)
672 {
673 $formData = ArrayHelper::except($data, [
674 '__fluent_form_embded_post_id',
675 '_fluentform_' . $formId . '_fluentformnonce',
676 '_wp_http_referer'
677 ]);
678
679 $entryItems = [];
680 foreach ($formData as $dataKey => $dataValue) {
681 if (!$dataValue) {
682 continue;
683 }
684
685 if (is_array($dataValue)) {
686 foreach ($dataValue as $subKey => $subValue) {
687 $entryItems[] = [
688 'form_id' => $formId,
689 'submission_id' => $entryId,
690 'field_name' => $dataKey,
691 'sub_field_name' => $subKey,
692 'field_value' => maybe_serialize($subValue)
693 ];
694 }
695 } else {
696 $entryItems[] = [
697 'form_id' => $formId,
698 'submission_id' => $entryId,
699 'field_name' => $dataKey,
700 'sub_field_name' => '',
701 'field_value' => $dataValue
702 ];
703 }
704 }
705
706 foreach ($entryItems as $entryItem) {
707 wpFluent()->table('fluentform_entry_details')->insert($entryItem);
708 }
709
710 return true;
711 }
712
713 public function updateEntryDiffs($entryId, $formId, $formData)
714 {
715 wpFluent()->table('fluentform_entry_details')
716 ->where('submission_id', $entryId)
717 ->where('form_id', $formId)
718 ->whereIn('field_name', array_keys($formData))
719 ->delete();
720
721 $entryItems = [];
722 foreach ($formData as $dataKey => $dataValue) {
723 if (!$dataValue) {
724 continue;
725 }
726
727 if (is_array($dataValue)) {
728 foreach ($dataValue as $subKey => $subValue) {
729 $entryItems[] = [
730 'form_id' => $formId,
731 'submission_id' => $entryId,
732 'field_name' => $dataKey,
733 'sub_field_name' => $subKey,
734 'field_value' => maybe_serialize($subValue)
735 ];
736 }
737 } else {
738 $entryItems[] = [
739 'form_id' => $formId,
740 'submission_id' => $entryId,
741 'field_name' => $dataKey,
742 'sub_field_name' => '',
743 'field_value' => $dataValue
744 ];
745 }
746 }
747
748 foreach ($entryItems as $entryItem) {
749 wpFluent()->table('fluentform_entry_details')->insert($entryItem);
750 }
751
752 return true;
753 }
754 }
755