PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.11
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.11
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 / Api / Form.php

Form.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.11, at app/Api/Form.php

224 lines 7.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\Api;
4
5 use FluentForm\App\Helpers\Helper;
6 use FluentForm\App\Models\FormMeta;
7 use FluentForm\App\Models\Submission;
8 use FluentForm\App\Services\Manager\FormManagerService;
9 use FluentForm\Framework\Helpers\ArrayHelper;
10
11 class Form
12 {
13 public function forms($atts = [], $withFields = false)
14 {
15 $defaultAtts = [
16 'search' => '',
17 'status' => 'all',
18 'sort_column' => 'id',
19 'filter_by' => 'all',
20 'date_range' => [],
21 'sort_by' => 'DESC',
22 'per_page' => 10,
23 'page' => 1,
24 ];
25
26 $atts = wp_parse_args($atts, $defaultAtts);
27
28 $perPage = (int) ArrayHelper::get($atts, 'per_page', 10);
29 $search = sanitize_text_field(ArrayHelper::get($atts, 'search', ''));
30 $status = sanitize_text_field(ArrayHelper::get($atts, 'status', 'all'));
31 $filter_by = sanitize_text_field(ArrayHelper::get($atts, 'filter_by', 'all'));
32 $dateRange = ArrayHelper::get($atts, 'date_range', []);
33 $is_filter_by_conv_or_step_form = $filter_by && ('conv_form' == $filter_by || 'step_form' == $filter_by);
34
35 $shortColumn = sanitize_sql_orderby(ArrayHelper::get($atts, 'sort_column', 'id'));
36 $shortColumn = $shortColumn !== false && $shortColumn !== '' ? $shortColumn : 'id';
37 $sortBy = Helper::sanitizeOrderValue(ArrayHelper::get($atts, 'sort_by', 'DESC'));
38
39 $query = \FluentForm\App\Models\Form::orderBy($shortColumn, $sortBy)->getQuery();
40
41 if ($status && 'all' != $status) {
42 $query->where('status', $status);
43 }
44
45 if (false !== ($allowIds = FormManagerService::getUserAllowedFormsScope())) {
46 $query->whereIn('id', $allowIds ?: [0]);
47 }
48
49 if ($filter_by && !$is_filter_by_conv_or_step_form) {
50 switch ($filter_by) {
51 case 'published':
52 $query->where('status', 'published');
53 break;
54 case 'unpublished':
55 $query->where('status', 'unpublished');
56 break;
57 case 'post':
58 $query->where('type', 'post');
59 break;
60 case 'is_payment':
61 $query->where('has_payment', 1);
62 break;
63 default:
64 break;
65 }
66 }
67
68 if ($dateRange) {
69 $query->where('created_at', '>=', sanitize_text_field($dateRange[0] . ' 00:00:01'));
70 $query->where('created_at', '<=', sanitize_text_field($dateRange[1] . ' 23:59:59'));
71 }
72
73 if ($search) {
74 $query->where(function ($q) use ($search) {
75 $q->where('id', 'LIKE', '%' . $search . '%');
76 $q->orWhere('title', 'LIKE', '%' . $search . '%');
77 });
78 }
79
80 $currentPage = intval(ArrayHelper::get($atts, 'page', 1));
81 $total = $query->count();
82 $skip = $perPage * ($currentPage - 1);
83
84 if ($is_filter_by_conv_or_step_form) {
85 $data = $query->select('*')->get()->all();
86 } else {
87 if ($total < $skip) {
88 $skip = 0;
89 }
90 $data = $query->select('*')->limit($perPage)->offset($skip)->get()->all();
91 }
92
93 // Fetch all counts in bulk before the loop
94 $formIds = array_column($data, 'id');
95
96 // Get all submission counts in one query using Submission model
97 $submissionCounts = Submission::select([
98 'form_id',
99 wpFluent()->raw('COUNT(*) as total_submissions'),
100 wpFluent()->raw("SUM(CASE WHEN status = 'unread' THEN 1 ELSE 0 END) as unread_count")
101 ])
102 ->whereIn('form_id', $formIds)
103 ->where('status', '!=', 'trashed')
104 ->groupBy('form_id')
105 ->get();
106
107 // Map counts by form_id for quick lookup
108 $countsMap = [];
109 foreach ($submissionCounts as $count) {
110 $countsMap[$count->form_id] = $count;
111 }
112
113 // Get all view counts in one query using FormMeta model
114 $viewCounts = FormMeta::select(['form_id', 'value'])
115 ->where('meta_key', '_total_views')
116 ->whereIn('form_id', $formIds)
117 ->get();
118
119 // Map view counts by form_id for quick lookup
120 $viewsMap = [];
121 foreach ($viewCounts as $view) {
122 $viewsMap[$view->form_id] = intval($view->value);
123 }
124
125 $conversationOrStepForms = [];
126 foreach ($data as $form) {
127 $is_conv_form = Helper::isConversionForm($form->id);
128
129 // skip form if filter by conversation form but form is not conversational form
130 if ('conv_form' == $filter_by && !$is_conv_form) {
131 continue;
132 }
133 // skip form if filter by step form but form is not step form
134 if ('step_form' == $filter_by && !Helper::isMultiStepForm($form)) {
135 continue;
136 }
137 $formInstance = $this->form($form);
138 $form->preview_url = Helper::getPreviewUrl($form->id, 'classic');
139 $form->edit_url = Helper::getFormAdminPermalink('editor', $form);
140 $form->settings_url = Helper::getFormSettingsUrl($form);
141 $form->entries_url = Helper::getFormAdminPermalink('entries', $form);
142 $form->analytics_url = Helper::getFormAdminPermalink('analytics', $form);
143
144 // Use pre-fetched counts instead of individual queries
145 $form->total_views = $viewsMap[$form->id] ?? 0;
146 $counts = $countsMap[$form->id] ?? null;
147 $form->total_Submissions = $counts ? intval($counts->total_submissions) : 0;
148 $form->unread_count = $counts ? intval($counts->unread_count) : 0;
149
150 // Calculate conversion rate (same logic as FormProperties::conversionRate())
151 if ($form->total_Submissions && $form->total_views) {
152 $form->conversion = ceil(($form->total_Submissions / $form->total_views) * 100);
153 } else {
154 $form->conversion = 0;
155 }
156
157 if ($is_conv_form) {
158 $form->conversion_preview = Helper::getPreviewUrl($form->id, 'conversational');
159 }
160
161 if (!$withFields) {
162 unset($form->form_fields);
163 }
164 if ($is_filter_by_conv_or_step_form) {
165 $conversationOrStepForms[] = $form;
166 }
167 }
168 if ($is_filter_by_conv_or_step_form) {
169 $total = count($conversationOrStepForms);
170 if ($total < $skip) {
171 $skip = 0;
172 }
173 $conversationOrStepForms = array_slice($conversationOrStepForms, $skip, $perPage);
174 $dataCount = count($conversationOrStepForms);
175 } else {
176 $dataCount = count($data);
177 }
178
179 $from = $dataCount > 0 ? ($currentPage - 1) * $perPage + 1 : null;
180
181 $to = $dataCount > 0 ? $from + $dataCount - 1 : null;
182 $lastPage = (int) ceil($total / $perPage);
183 return [
184 'current_page' => $currentPage,
185 'per_page' => $perPage,
186 'from' => $from,
187 'to' => $to,
188 'last_page' => $lastPage,
189 'total' => $total,
190 'data' => $is_filter_by_conv_or_step_form ? $conversationOrStepForms : $data,
191 ];
192 }
193
194 public function find($formId)
195 {
196 return \FluentForm\App\Models\Form::where('id', $formId)->first();
197 }
198
199 /**
200 * Get Form Properties instance
201 *
202 * @param int|object $form
203 *
204 * @return \FluentForm\App\Api\FormProperties
205 */
206 public function form($form)
207 {
208 if (is_numeric($form)) {
209 $form = $this->find($form);
210 }
211
212 return (new FormProperties($form));
213 }
214
215 public function entryInstance($form)
216 {
217 if (is_numeric($form)) {
218 $form = $this->find($form);
219 }
220
221 return (new Entry($form));
222 }
223 }
224