PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 3.6.21
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v3.6.21
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 3.6.66 All 195 releases
fluentform / app / Modules / Entries / Entries.php

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

748 lines 24.3 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 // we should delete the entry attachment too.
484 // Check if any media type exist in the form
485 // if yes find them and the delete them
486 $form = wpFluent()->table('fluentform_forms')->find($formId);
487
488 $deletableFiles = $this->getSubmissionAttachments($entryId, $form);
489
490
491 wpFluent()->table('fluentform_submissions')
492 ->where('id', $entryId)
493 ->delete();
494 wpFluent()->table('fluentform_submission_meta')
495 ->where('response_id', $entryId)
496 ->delete();
497
498 wpFluent()->table('fluentform_entry_details')
499 ->where('submission_id', $entryId)
500 ->delete();
501
502 wpFluent()->table('fluentform_logs')
503 ->where('source_id', $entryId)
504 ->where('source_type', 'submission_item')
505 ->delete();
506
507 ob_start();
508 if (defined('FLUENTFORMPRO')) {
509 try {
510 wpFluent()->table('fluentform_order_items')
511 ->where('submission_id', $entryId)
512 ->delete();
513
514 wpFluent()->table('fluentform_subscriptions')
515 ->where('submission_id', $entryId)
516 ->delete();
517
518 wpFluent()->table('fluentform_transactions')
519 ->where('submission_id', $entryId)
520 ->delete();
521
522 wpFluent()->table('ff_scheduled_actions')
523 ->where('origin_id', $entryId)
524 ->where('type', 'submission_action')
525 ->delete();
526
527 if ($deletableFiles) {
528 foreach ($deletableFiles as $eachFile) {
529 $file = wp_upload_dir()['basedir'].FLUENTFORM_UPLOAD_DIR.'/'.basename($eachFile);
530 if(is_readable($file) && !is_dir($file)) {
531 unlink($file);
532 }
533 }
534 }
535
536 } catch (\Exception $exception) {
537 // ...
538 }
539 }
540 $errors = ob_get_clean();
541
542 do_action('fluentform_after_entry_deleted', $entryId, $formId);
543
544 return true;
545 }
546
547
548 private function getSubmissionAttachments($submissionId, $form)
549 {
550 $fields = FormFieldsParser::getAttachmentInputFields($form, ['element', 'attributes']);
551
552 $deletableFiles = [];
553
554 if ($fields) {
555 $submission = wpFluent()->table('fluentform_submissions')
556 ->where('id', $submissionId)
557 ->first();
558
559 $data = json_decode($submission->response, true);
560
561 foreach ($fields as $field) {
562 if (!empty($data[$field['attributes']['name']])) {
563
564 $files = $data[$field['attributes']['name']];
565
566 if (is_array($files)) {
567 $deletableFiles = array_merge($deletableFiles, $files);
568 } else {
569 $deletableFiles = $files;
570 }
571
572 }
573 }
574 }
575
576 return $deletableFiles;
577 }
578
579 public function favoriteChange()
580 {
581 $formId = intval($this->request->get('form_id'));
582 $entryId = intval($this->request->get('entry_id'));
583 $newStatus = intval($this->request->get('is_favourite'));
584 if ($newStatus) {
585 $message = __('Item has been added to favorites', 'fluentform');
586 } else {
587 $message = __('Item has been removed from favorites', 'fluentform');
588 }
589 $this->responseModel
590 ->where('form_id', $formId)
591 ->where('id', $entryId)
592 ->update(['is_favourite' => $newStatus]);
593
594 wp_send_json_success([
595 'message' => $message,
596 'is_favourite' => $newStatus
597 ], 200);
598 }
599
600 public function handleBulkAction()
601 {
602 $formId = intval($this->request->get('form_id'));
603 $entries = fluentFormSanitizer($this->request->get('entries', []));
604
605 $actionType = sanitize_text_field($this->request->get('action_type'));
606
607 // check if it's status change or not
608 $statuses = Helper::getEntryStatuses($formId);
609
610 if (!$formId || !count($entries)) {
611 wp_send_json_error([
612 'message' => __('Please select entries first', 'fluentform')
613 ], 400);
614 }
615
616 $bulkQuery = wpFluent()->table('fluentform_submissions')
617 ->where('form_id', $formId)
618 ->whereIn('id', $entries);
619
620 if (isset($statuses[$actionType])) {
621 // it's status change
622 $bulkQuery->update([
623 'status' => $actionType,
624 'updated_at' => current_time('mysql')
625 ]);
626
627 wp_send_json_success([
628 'message' => 'Selected entries successfully marked as ' . $statuses[$actionType]
629 ], 200);
630 }
631
632 // now other action handler
633 if ($actionType == 'other.delete_permanently') {
634 $bulkQuery->delete();
635 wpFluent()->table('fluentform_entry_details')
636 ->where('form_id', $formId)
637 ->whereIn('submission_id', $entries)
638 ->delete();
639
640 wpFluent()->table('fluentform_submission_meta')
641 ->where('form_id', $formId)
642 ->whereIn('response_id', $entries)
643 ->delete();
644
645 $message = __('Selected entries successfully deleted', 'fluentform');
646
647 } elseif ($actionType == 'other.make_favorite') {
648 $bulkQuery->update([
649 'is_favourite' => 1
650 ]);
651 $message = __('Selected entries successfully marked as Favorite', 'fluentform');
652 } elseif ($actionType == 'other.unmark_favorite') {
653 $bulkQuery->update([
654 'is_favourite' => 0
655 ]);
656 $message = __('Selected entries successfully remove from favorite', 'fluentform');
657 }
658
659 wp_send_json_success([
660 'message' => $message
661 ], 200);
662 }
663
664 public function recordEntryDetails($entryId, $formId, $data)
665 {
666 $formData = ArrayHelper::except($data, [
667 '__fluent_form_embded_post_id',
668 '_fluentform_' . $formId . '_fluentformnonce',
669 '_wp_http_referer'
670 ]);
671
672 $entryItems = [];
673 foreach ($formData as $dataKey => $dataValue) {
674 if (!$dataValue) {
675 continue;
676 }
677
678 if (is_array($dataValue)) {
679 foreach ($dataValue as $subKey => $subValue) {
680 $entryItems[] = [
681 'form_id' => $formId,
682 'submission_id' => $entryId,
683 'field_name' => $dataKey,
684 'sub_field_name' => $subKey,
685 'field_value' => maybe_serialize($subValue)
686 ];
687 }
688 } else {
689 $entryItems[] = [
690 'form_id' => $formId,
691 'submission_id' => $entryId,
692 'field_name' => $dataKey,
693 'sub_field_name' => '',
694 'field_value' => $dataValue
695 ];
696 }
697 }
698
699 foreach ($entryItems as $entryItem) {
700 wpFluent()->table('fluentform_entry_details')->insert($entryItem);
701 }
702
703 return true;
704 }
705
706 public function updateEntryDiffs($entryId, $formId, $formData)
707 {
708 wpFluent()->table('fluentform_entry_details')
709 ->where('submission_id', $entryId)
710 ->where('form_id', $formId)
711 ->whereIn('field_name', array_keys($formData))
712 ->delete();
713
714 $entryItems = [];
715 foreach ($formData as $dataKey => $dataValue) {
716 if (!$dataValue) {
717 continue;
718 }
719
720 if (is_array($dataValue)) {
721 foreach ($dataValue as $subKey => $subValue) {
722 $entryItems[] = [
723 'form_id' => $formId,
724 'submission_id' => $entryId,
725 'field_name' => $dataKey,
726 'sub_field_name' => $subKey,
727 'field_value' => maybe_serialize($subValue)
728 ];
729 }
730 } else {
731 $entryItems[] = [
732 'form_id' => $formId,
733 'submission_id' => $entryId,
734 'field_name' => $dataKey,
735 'sub_field_name' => '',
736 'field_value' => $dataValue
737 ];
738 }
739 }
740
741 foreach ($entryItems as $entryItem) {
742 wpFluent()->table('fluentform_entry_details')->insert($entryItem);
743 }
744
745 return true;
746 }
747 }
748