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

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