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

759 lines 24.6 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 ], $form);
170
171 wp_localize_script(
172 'fluentform_form_entries', 'fluent_form_entries_vars', $fluentFormEntriesVars
173 );
174
175 View::render('admin.form.entries', [
176 'form_id' => $form_id,
177 'has_pdf' => defined('FLUENTFORM_PDF_VERSION') ? 'true' : 'false'
178 ]);
179 }
180
181 public function getEntriesGroup()
182 {
183 $formId = intval($this->request->get('form_id'));
184 $counts = $this->groupCount($formId);
185 wp_send_json_success([
186 'counts' => $counts
187 ], 200);
188 }
189
190 public function _getEntries(
191 $formId,
192 $currentPage,
193 $perPage,
194 $sortBy,
195 $entryType,
196 $search,
197 $wheres = []
198 )
199 {
200 $this->formId = $formId;
201 $this->per_page = $perPage;
202 $this->sort_by = $sortBy;
203 $this->page_number = $currentPage;
204 $this->search = $search;
205 $this->wheres = $wheres;
206
207 if ($entryType == 'favorite') {
208 $this->is_favourite = true;
209 } elseif ($entryType != 'all' && $entryType) {
210 $this->status = $entryType;
211 }
212
213 $dateRange = $this->request->get('date_range');
214 if ($dateRange) {
215 $this->startDate = $dateRange[0];
216 $this->endDate = $dateRange[1];
217 }
218
219 $form = $this->formModel->find($formId);
220 $formMeta = $this->getFormInputsAndLabels($form);
221 $formLabels = $formMeta['labels'];
222 $formLabels = apply_filters('fluentfoform_entry_lists_labels', $formLabels, $form);
223 $submissions = $this->getResponses();
224 $submissions['data'] = FormDataParser::parseFormEntries($submissions['data'], $form);
225
226 return compact('submissions', 'formLabels');
227 }
228
229 public function getEntries()
230 {
231 if (!defined('FLUENTFORM_RENDERING_ENTRIES')) {
232 define('FLUENTFORM_RENDERING_ENTRIES', true);
233 }
234
235 $wheres = [];
236
237 if($paymentStatuses = $this->request->get('payment_statuses')) {
238 if(is_array($paymentStatuses)) {
239 $wheres[] = ['payment_status', $paymentStatuses];
240 }
241 }
242
243 $entries = $this->_getEntries(
244 intval($this->request->get('form_id')),
245 intval($this->request->get('current_page', 1)),
246 intval($this->request->get('per_page', 10)),
247 sanitize_text_field($this->request->get('sort_by', 'DESC')),
248 sanitize_text_field($this->request->get('entry_type', 'all')),
249 sanitize_text_field($this->request->get('search')),
250 $wheres
251 );
252
253
254 $labels = apply_filters(
255 'fluentform_all_entry_labels', $entries['formLabels'], $this->request->get('form_id')
256 );
257
258 $form = $this->formModel->find($this->request->get('form_id'));
259
260 if ($form->has_payment) {
261 $labels = apply_filters(
262 'fluentform_all_entry_labels_with_payment', $entries['formLabels'], false, $form
263 );
264 }
265
266 wp_send_json_success([
267 'submissions' => apply_filters('fluentform_all_entries', $entries['submissions']),
268 'labels' => $labels
269 ], 200);
270 }
271
272 public function _getEntry()
273 {
274 $this->formId = intval($this->request->get('form_id'));
275
276 $entryId = intval($this->request->get('entry_id'));
277
278 $entry_type = sanitize_text_field($this->request->get('entry_type', 'all'));
279
280 if ($entry_type === 'favorite') {
281 $this->is_favourite = true;
282 } elseif ($entry_type !== 'all') {
283 $this->status = $entry_type;
284 }
285
286 $this->sort_by = sanitize_text_field($this->request->get('sort_by', 'ASC'));
287
288 $this->search = sanitize_text_field($this->request->get('search'));
289
290 $submission = $this->getResponse($entryId);
291
292 if (!$submission) {
293 wp_send_json_error([
294 'message' => 'No Entry found.'
295 ], 422);
296 }
297
298 $form = $this->formModel->find($this->formId);
299
300 if ($submission->status == 'unread' && apply_filters('fluentform_auto_read', true, $form)) {
301 wpFluent()->table('fluentform_submissions')
302 ->where('id', $entryId)
303 ->update([
304 'status' => 'read'
305 ]);
306
307 $submission->status = 'read';
308 }
309
310 $formMeta = $this->getFormInputsAndLabels($form);
311
312 $submission = FormDataParser::parseFormEntry($submission, $form, $formMeta['inputs'], true);
313
314 if ($submission->user_id) {
315 $user = get_user_by('ID', $submission->user_id);
316 $user_data = [
317 'name' => $user->display_name,
318 'email' => $user->user_email,
319 'ID' => $user->ID,
320 'permalink' => get_edit_user_link($user->ID)
321 ];
322 $submission->user = $user_data;
323 }
324
325 $submission = apply_filters('fluentform_single_response_data', $submission, $this->formId);
326
327 $fields = apply_filters(
328 'fluentform_single_response_input_fields', $formMeta['inputs'], $this->formId
329 );
330
331 $labels = apply_filters(
332 'fluentform_single_response_input_labels', $formMeta['labels'], $this->formId
333 );
334
335 $order_data = false;
336
337 if ($submission->payment_status || $submission->payment_total) {
338 $order_data = apply_filters(
339 'fluentform_submission_order_data', false, $submission, $form
340 );
341
342 $labels = apply_filters(
343 'fluentform_submission_entry_labels_with_payment', $labels, $submission, $form
344 );
345 }
346
347 $nextSubmissionId = $this->getNextResponse($entryId);
348
349 $previousSubmissionId = $this->getPrevResponse($entryId);
350
351 return [
352 'submission' => $submission,
353 'next' => $nextSubmissionId,
354 'prev' => $previousSubmissionId,
355 'labels' => $labels,
356 'fields' => $fields,
357 'order_data' => $order_data
358 ];
359 }
360
361 public function getEntry()
362 {
363 $entryData = $this->_getEntry();
364
365 $entryData['widgets'] = apply_filters('fluentform_single_entry_widgets', [], $entryData);
366
367 wp_send_json_success($entryData, 200);
368 }
369
370 /**
371 * @param $form
372 * @param array $with
373 *
374 * @return array
375 * @todo: Implement Caching mechanism so we don't have to parse these things for every request
376 */
377 private function getFormInputsAndLabels($form, $with = ['admin_label', 'raw'])
378 {
379 $formInputs = FormFieldsParser::getEntryInputs($form, $with);
380 $inputLabels = FormFieldsParser::getAdminLabels($form, $formInputs);
381 return [
382 'inputs' => $formInputs,
383 'labels' => $inputLabels
384 ];
385 }
386
387 public function getNotes()
388 {
389 $formId = intval($this->request->get('form_id'));
390 $entry_id = intval($this->request->get('entry_id'));
391 $apiLog = sanitize_text_field($this->request->get('api_log')) == 'yes';
392
393 $metaKeys = ['_notes'];
394
395 if ($apiLog) {
396 $metaKeys[] = 'api_log';
397 }
398
399 $notes = $this->responseMetaModel
400 ->where('form_id', $formId)
401 ->where('response_id', $entry_id)
402 ->whereIn('meta_key', $metaKeys)
403 ->orderBy('id', 'DESC')
404 ->get();
405
406 foreach ($notes as $note) {
407 if ($note->user_id) {
408 $note->pemalink = get_edit_user_link($note->user_id);
409 $user = get_user_by('ID', $note->user_id);
410 if ($user) {
411 $note->created_by = $user->display_name;
412 } else {
413 $note->created_by = __('Fluent Forms Bot', 'fluentform');
414 }
415 } else {
416 $note->pemalink = false;
417 }
418 }
419
420 $notes = apply_filters('fluentform_entry_notes', $notes, $entry_id, $formId);
421
422 wp_send_json_success([
423 'notes' => $notes
424 ], 200);
425 }
426
427 public function addNote()
428 {
429 $entryId = intval($this->request->get('entry_id'));
430 $formId = intval($this->request->get('form_id'));
431 $note = $this->request->get('note');
432 $note_content = sanitize_textarea_field($note['content']);
433 $note_status = sanitize_text_field($note['status']);
434 $user = get_user_by('ID', get_current_user_id());
435
436 $response_note = [
437 'response_id' => $entryId,
438 'form_id' => $formId,
439 'meta_key' => '_notes',
440 'value' => $note_content,
441 'status' => $note_status,
442 'user_id' => $user->ID,
443 'name' => $user->display_name,
444 'created_at' => current_time('mysql'),
445 'updated_at' => current_time('mysql')
446 ];
447
448 $response_note = apply_filters('fluentform_add_response_note', $response_note);
449
450 $insertId = $this->responseMetaModel->insert($response_note);
451
452 $added_note = $this->responseMetaModel->find($insertId);
453
454 do_action('fluentform_new_response_note_added', $insertId, $added_note);
455
456 wp_send_json_success([
457 'message' => __('Note has been successfully added', 'fluentform'),
458 'note' => $added_note,
459 'insert_id' => $insertId
460 ], 200);
461 }
462
463 public function changeEntryStatus()
464 {
465 $formId = intval($this->request->get('form_id'));
466 $entryId = intval($this->request->get('entry_id'));
467 $newStatus = sanitize_text_field($this->request->get('status'));
468
469 $this->responseModel
470 ->where('form_id', $formId)
471 ->where('id', $entryId)
472 ->update(['status' => $newStatus]);
473
474 wp_send_json_success([
475 'message' => __('Item has been marked as ' . $newStatus, 'fluentform'),
476 'status' => $newStatus
477 ], 200);
478 }
479
480 public function deleteEntry()
481 {
482 $formId = intval($this->request->get('form_id'));
483 $entryId = intval($this->request->get('entry_id'));
484 $newStatus = sanitize_text_field($this->request->get('status'));
485
486 $this->deleteEntryById($entryId, $formId);
487
488 wp_send_json_success([
489 'message' => __('Item Successfully deleted', 'fluentform'),
490 'status' => $newStatus
491 ], 200);
492 }
493
494 public function deleteEntryById($entryId, $formId = false)
495 {
496 do_action('fluentform_before_entry_deleted', $entryId, $formId);
497
498 wpFluent()->table('fluentform_submissions')
499 ->where('id', $entryId)
500 ->delete();
501 wpFluent()->table('fluentform_submission_meta')
502 ->where('response_id', $entryId)
503 ->delete();
504
505 wpFluent()->table('fluentform_logs')
506 ->where('source_id', $entryId)
507 ->where('source_type', 'submission_item')
508 ->delete();
509
510 wpFluent()->table('fluentform_entry_details')
511 ->where('submission_id', $entryId)
512 ->delete();
513
514 ob_start();
515 if (defined('FLUENTFORMPRO')) {
516 try {
517 if($formId) {
518 if(is_numeric($formId)) {
519 $form = wpFluent()->table('fluentform_forms')->find($formId);
520 } else {
521 $form = $formId;
522 }
523 $deletableFiles = $this->getSubmissionAttachments($entryId, $form);
524 if ($deletableFiles) {
525 foreach ($deletableFiles as $eachFile) {
526 $file = wp_upload_dir()['basedir'].FLUENTFORM_UPLOAD_DIR.'/'.basename($eachFile);
527 if(is_readable($file) && !is_dir($file)) {
528 vddd(unlink($file));
529 }
530 }
531 }
532 }
533
534 wpFluent()->table('fluentform_order_items')
535 ->where('submission_id', $entryId)
536 ->delete();
537
538 wpFluent()->table('fluentform_subscriptions')
539 ->where('submission_id', $entryId)
540 ->delete();
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
566 private function getSubmissionAttachments($submissionId, $form)
567 {
568 $fields = FormFieldsParser::getAttachmentInputFields($form, ['element', 'attributes']);
569
570 $deletableFiles = [];
571
572 if ($fields) {
573 $submission = wpFluent()->table('fluentform_submissions')
574 ->where('id', $submissionId)
575 ->first();
576
577 $data = json_decode($submission->response, true);
578
579 foreach ($fields as $field) {
580 if (!empty($data[$field['attributes']['name']])) {
581
582 $files = $data[$field['attributes']['name']];
583
584 if (is_array($files)) {
585 $deletableFiles = array_merge($deletableFiles, $files);
586 } else {
587 $deletableFiles = $files;
588 }
589
590 }
591 }
592 }
593
594 return $deletableFiles;
595 }
596
597 public function favoriteChange()
598 {
599 $formId = intval($this->request->get('form_id'));
600 $entryId = intval($this->request->get('entry_id'));
601 $newStatus = intval($this->request->get('is_favourite'));
602 if ($newStatus) {
603 $message = __('Item has been added to favorites', 'fluentform');
604 } else {
605 $message = __('Item has been removed from favorites', 'fluentform');
606 }
607 $this->responseModel
608 ->where('form_id', $formId)
609 ->where('id', $entryId)
610 ->update(['is_favourite' => $newStatus]);
611
612 wp_send_json_success([
613 'message' => $message,
614 'is_favourite' => $newStatus
615 ], 200);
616 }
617
618 public function handleBulkAction()
619 {
620 $formId = intval($this->request->get('form_id'));
621 $entries = fluentFormSanitizer($this->request->get('entries', []));
622
623 $actionType = sanitize_text_field($this->request->get('action_type'));
624
625 // check if it's status change or not
626 $statuses = Helper::getEntryStatuses($formId);
627
628 if (!$formId || !count($entries)) {
629 wp_send_json_error([
630 'message' => __('Please select entries first', 'fluentform')
631 ], 400);
632 }
633
634 $bulkQuery = wpFluent()->table('fluentform_submissions')
635 ->where('form_id', $formId)
636 ->whereIn('id', $entries);
637
638 if (isset($statuses[$actionType])) {
639 // it's status change
640 $bulkQuery->update([
641 'status' => $actionType,
642 'updated_at' => current_time('mysql')
643 ]);
644
645 wp_send_json_success([
646 'message' => 'Selected entries successfully marked as ' . $statuses[$actionType]
647 ], 200);
648 }
649
650 // now other action handler
651 if ($actionType == 'other.delete_permanently') {
652 $form = $form = wpFluent()->table('fluentform_forms')->find($formId);
653 foreach ($entries as $entryId) {
654 $this->deleteEntryById($entryId, $form);
655 }
656 $message = __('Selected entries successfully deleted', 'fluentform');
657
658 } elseif ($actionType == 'other.make_favorite') {
659 $bulkQuery->update([
660 'is_favourite' => 1
661 ]);
662 $message = __('Selected entries successfully marked as Favorite', 'fluentform');
663 } elseif ($actionType == 'other.unmark_favorite') {
664 $bulkQuery->update([
665 'is_favourite' => 0
666 ]);
667 $message = __('Selected entries successfully remove from favorite', 'fluentform');
668 }
669
670 wp_send_json_success([
671 'message' => $message
672 ], 200);
673 }
674
675 public function recordEntryDetails($entryId, $formId, $data)
676 {
677 $formData = ArrayHelper::except($data, [
678 '__fluent_form_embded_post_id',
679 '_fluentform_' . $formId . '_fluentformnonce',
680 '_wp_http_referer'
681 ]);
682
683 $entryItems = [];
684 foreach ($formData as $dataKey => $dataValue) {
685 if (!$dataValue) {
686 continue;
687 }
688
689 if (is_array($dataValue)) {
690 foreach ($dataValue as $subKey => $subValue) {
691 $entryItems[] = [
692 'form_id' => $formId,
693 'submission_id' => $entryId,
694 'field_name' => $dataKey,
695 'sub_field_name' => $subKey,
696 'field_value' => maybe_serialize($subValue)
697 ];
698 }
699 } else {
700 $entryItems[] = [
701 'form_id' => $formId,
702 'submission_id' => $entryId,
703 'field_name' => $dataKey,
704 'sub_field_name' => '',
705 'field_value' => $dataValue
706 ];
707 }
708 }
709
710 foreach ($entryItems as $entryItem) {
711 wpFluent()->table('fluentform_entry_details')->insert($entryItem);
712 }
713
714 return true;
715 }
716
717 public function updateEntryDiffs($entryId, $formId, $formData)
718 {
719 wpFluent()->table('fluentform_entry_details')
720 ->where('submission_id', $entryId)
721 ->where('form_id', $formId)
722 ->whereIn('field_name', array_keys($formData))
723 ->delete();
724
725 $entryItems = [];
726 foreach ($formData as $dataKey => $dataValue) {
727 if (!$dataValue) {
728 continue;
729 }
730
731 if (is_array($dataValue)) {
732 foreach ($dataValue as $subKey => $subValue) {
733 $entryItems[] = [
734 'form_id' => $formId,
735 'submission_id' => $entryId,
736 'field_name' => $dataKey,
737 'sub_field_name' => $subKey,
738 'field_value' => maybe_serialize($subValue)
739 ];
740 }
741 } else {
742 $entryItems[] = [
743 'form_id' => $formId,
744 'submission_id' => $entryId,
745 'field_name' => $dataKey,
746 'sub_field_name' => '',
747 'field_value' => $dataValue
748 ];
749 }
750 }
751
752 foreach ($entryItems as $entryItem) {
753 wpFluent()->table('fluentform_entry_details')->insert($entryItem);
754 }
755
756 return true;
757 }
758 }
759