PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.9.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.9.1
V-3.3.0 3.2.2 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 V3.0.3 V3.0.2 -3.0.1 V_3.0.0 1.1.1 1.1.8 1.2 1.3 1.4 1.4.18 1.5.2 1.9 2.0 2.10.0 2.10.1 2.10.2 All 137 releases
← All changes | includes/Core/Database/FormEntryMetaModel.php +210 -305 3.1.22.9.1 View file →
@@ -5,12 +5,10 @@
5 5 */
6 6
7 7 namespace BitCode\BitForm\Core\Database;
8 8
9 -use BitCode\BitForm\Core\Util\FileHandler;
10 -
11 9 /**
12 - * Manages entry meta (per-field values) for each form submission.
10 + * Undocumented class
13 11 */
14 12
15 13 class FormEntryMetaModel extends Model
16 14 {
@@ -20,10 +18,10 @@
20 18 {
21 19 $values[] = $data['duplicateID'];
22 20 $values[] = $data['entryID'];
23 21 $sql = "INSERT INTO $this->table_name (bitforms_form_entry_id,meta_key,meta_value)"
24 - . ' SELECT %d as bitforms_form_entry_id,meta_key,meta_value'
25 - . " FROM `$this->table_name` WHERE bitforms_form_entry_id = %d";
22 + . ' SELECT %d as bitforms_form_entry_id,meta_key,meta_value'
23 + . " FROM `$this->table_name` WHERE bitforms_form_entry_id = %d";
26 24 return $this->execute($sql, $values)->getResult();
27 25 }
28 26
29 27 public function update(array $data, array $condition)
@@ -31,9 +29,8 @@
31 29 $entryID = $condition['bitforms_form_entry_id'];
32 30 if (empty($entryID)) {
33 31 return false;
34 32 }
35 - // Form entry meta lookup; meta_key/meta_value query required to map dynamic field keys per entry.
36 33 $formEntryMeta = $this->get(
37 34 [
38 35 'meta_key',
39 36 'meta_value',
@@ -49,11 +46,11 @@
49 46 $updatedData = [];
50 47 $oldEntriesKey = array_keys($oldEntries);
51 48 foreach ($data as $upKey => $upValue) {
52 49 $updatedData[$upKey] = is_string($upValue) ?
53 - $upValue :
54 - wp_json_encode($upValue);
55 - if (!in_array($upKey, $oldEntriesKey, true)) {
50 + $upValue :
51 + wp_json_encode($upValue);
52 + if (!\in_array($upKey, $oldEntriesKey)) {
56 53 $this->insert(
57 54 [
58 55 'bitforms_form_entry_id' => $entryID,
59 56 'meta_key' => $upKey,
@@ -75,9 +72,9 @@
75 72 $condition['meta_key'] = array_keys($data);
76 73 foreach ($data as $key => $value) {
77 74 $value = is_string($value) ? $value : wp_json_encode($value);
78 75 $case_part .= "
79 - WHEN '" . esc_sql($key) . "' THEN " . $this->getFieldFormat($value);
76 + WHEN '$key' THEN " . $this->getFieldFormat($value);
80 77 $all_values[] = $value;
81 78 }
82 79 $formattedCondition = $this->getFormatedCondition($condition);
83 80 if ($formattedCondition) {
@@ -119,17 +116,11 @@
119 116
120 117 $dateQuery = $dbHelper->dateQueryList();
121 118
122 119 $validCondtions = $this->validQueryCondition($conditions);
123 - $safeOperators = ['=', '!=', '>', '<', '>=', '<=', 'LIKE', 'NOT LIKE'];
124 120
125 121 foreach ($validCondtions as $condition) {
126 122 if (is_object($condition)) {
127 - $field = sanitize_key($condition->field);
128 - if (empty($field)) {
129 - continue;
130 - }
131 -
132 123 if (is_array($condition->val)) {
133 124 $value = $dbHelper->arrValueModifyByLogic($condition->logic, $condition->val);
134 125 } else {
135 126 $value = $dbHelper->strValueModifyByLogic($condition->logic, $condition->val);
@@ -135,23 +126,20 @@
135 126 $value = $dbHelper->strValueModifyByLogic($condition->logic, $condition->val);
136 127 }
137 128
138 129 $operator = $dbHelper->convertToSqlOperator($condition->logic);
139 - if (!in_array($operator, $safeOperators, true)) {
140 - continue;
141 - }
142 130
143 - if (!is_array($condition->val) && isset($dateQuery[$condition->val])) {
144 - $sql .= $dbHelper->fieldQueryByDate($field, $operator, $value, $condition->logic);
131 + if (isset($dateQuery[$condition->val])) {
132 + $sql .= $dbHelper->fieldQueryByDate($condition->field, $operator, $value, $condition->logic);
145 133 } else {
146 134 if (!is_int($value)) {
147 - $value = "'" . esc_sql($value) . "'";
135 + $value = "'" . $value . "'";
148 136 }
149 137
150 - $sql .= "`{$field}` $operator $value";
138 + $sql .= "`$condition->field` $operator $value";
151 139 }
152 - } elseif (in_array(strtoupper(trim((string) $condition)), ['AND', 'OR'], true)) {
153 - $sql .= ' ' . strtoupper(trim((string) $condition));
140 + } else {
141 + $sql .= ' ' . $condition;
154 142 }
155 143 }
156 144
157 145 return trim($sql);
@@ -168,14 +156,12 @@
168 156 $countResult = $this->execute($sql, $all_values)->getResult();
169 157 return $countResult[0]->count;
170 158 }
171 159
172 - public function selectedEntryMeta($formFields, $fieldCount, $filter = null)
160 + public function selectedEntryMeta($formFields, $fieldCount)
173 161 {
174 162 $all_values = [];
175 163 $formFieldsNames = [];
176 - $globalFilterString = '';
177 - $globalFilterValues = [];
178 164 $metaChecker = 0;
179 165 $selectedMeta = '`bitforms_form_entry_id` as entry_id,';
180 166 $selectedMeta .= "e.user_id as '__user_id',";
181 167 $selectedMeta .= "e.user_ip as '__user_ip',";
@@ -190,10 +176,9 @@
190 176 $selectedMeta .= ',';
191 177 }
192 178
193 179 foreach ($formFields as $fieldDetails) {
194 - $safeFieldKey = sanitize_key($fieldDetails['key']);
195 - $fieldFormat = $this->getFieldFormat($safeFieldKey);
180 + $fieldFormat = $this->getFieldFormat($fieldDetails['key']);
196 181 $selectedMeta .= "GROUP_CONCAT(
197 182 CASE
198 183 `meta_key`
199 184 WHEN '$fieldFormat' THEN `meta_value`
@@ -199,33 +184,32 @@
199 184 WHEN '$fieldFormat' THEN `meta_value`
200 185 END
201 186 ) AS '$fieldFormat'";
202 187 $metaChecker += 1;
203 - $all_values[] = $safeFieldKey;
204 - $all_values[] = $safeFieldKey;
205 - $formFieldsNames[] = $safeFieldKey;
188 + $all_values[] = $fieldDetails['key'];
189 + $all_values[] = $fieldDetails['key'];
190 + $formFieldsNames[] = $fieldDetails['key'];
206 191 if ($metaChecker < $fieldCount) {
207 192 $selectedMeta .= ',';
208 193 }
209 - if (!empty($filter['global'])) {
210 - $globalFilterString .= ' `' . $safeFieldKey . '` LIKE %s ';
211 - if ($metaChecker < $fieldCount) {
212 - $globalFilterString .= ' OR ';
213 - }
214 - $globalFilterValues[] = '%' . $this->app_db->esc_like($filter['global']) . '%';
215 - }
194 + //#unused code commented by me##
195 + // if ( !empty( $filter['global'] ) ) {
196 + // $globalFilterString .= " `" . $fieldDetails['key'] . "` LIKE '%%" . $this->getFieldFormat( $filter['global'] ) . "%%' ";
197 + // if ( $metaChecker < $fieldCount ) {
198 + // $globalFilterString .= " OR ";
199 + // }
200 + // $globalFilterValues[] = $filter['global'];
201 + // }
216 202 }
217 203
218 204 return [
219 - 'selected_meta' => $selectedMeta,
220 - 'form_fields_names' => $formFieldsNames,
221 - 'all_values' => $all_values,
222 - 'global_filter_string' => $globalFilterString,
223 - 'global_filter_values' => $globalFilterValues,
205 + 'selected_meta' => $selectedMeta,
206 + 'form_fields_names' => $formFieldsNames,
207 + 'all_values' => $all_values,
224 208 ];
225 209 }
226 210
227 - public function groupedCondition($condition, $all_values, $fieldConditions, $filter = null, $globalFilterString = '', $globalFilterValues = [])
211 + public function groupedCondition($condition, $all_values, $fieldConditions)
228 212 {
229 213 $isFldCondition = false;
230 214 $formattedCondition = $this->getFormatedCondition($condition);
231 215 if ($formattedCondition) {
@@ -234,23 +218,51 @@
234 218 $all_values = array_merge($all_values, $formattedCondition['values']);
235 219 } else {
236 220 $groupedCondition = null;
237 221 }
238 - if (!empty($filter['global']) && !empty($globalFilterString) && !empty($globalFilterValues)) {
239 - $isFldCondition = true;
240 - if ($groupedCondition && false !== strpos($groupedCondition, 'HAVING')) {
241 - $groupedCondition .= ' AND (' . $globalFilterString . ') ';
242 - } else {
243 - $groupedCondition .= ' HAVING (' . $globalFilterString . ') ';
244 - }
245 - $all_values = array_merge($all_values, $globalFilterValues);
246 - }
222 + //#unused code commented by me##
223 + //$isRecount = false;
247 224
225 + // if ( !empty( $filter['field'] ) ) {
226 + // $isRecount = true;
227 + // $filterFieldCount = count( $filter['field'] );
228 + // $filterFieldChecker = 0;
229 + // if ( $filterFieldCount > 0 ) {
230 + // $groupedCondition .= " HAVING ";
231 + // }
232 + // foreach ( $filter['field'] as $filterFieldKey => $filterFieldDetails ) {
233 + // $groupedCondition .= " `$filterFieldDetails->id` ='%%" . $this->getFieldFormat( $filterFieldDetails->value ) . "%%'";
234 + // $all_values[] = $filterFieldDetails->value;
235 + // if ( $filterFieldChecker < $filterFieldCount ) {
236 + // $groupedCondition .= " AND ";
237 + // }
238 + // }
239 + // }
240 +
241 + // if ( !empty( $filter['global'] ) && !empty( $globalFilterString ) && !empty( $globalFilterValues ) ) {
242 + // $isRecount = true;
243 + // if ( !empty( $filter['field'] ) ) {
244 + // $groupedCondition .= " AND (" . $globalFilterString . ") ";
245 + // } else {
246 + // $groupedCondition .= " HAVING $globalFilterString ";
247 + // }
248 + // $offset = 0;
249 + // $all_values = array_merge( $all_values, $globalFilterValues );
250 + // }
251 +
252 + // if ( !empty( $dateBetweenFilter ) && !empty( $dateBetweenFilter->start_date ) && !empty( $dateBetweenFilter->end_date ) ) {
253 + // if ( strpos( $groupedCondition, 'HAVING' ) !== false ) {
254 + // $groupedCondition .= " AND `__created_at` BETWEEN '" . $dateBetweenFilter->start_date . "' AND '" . $dateBetweenFilter->end_date . "' ";
255 + // } else {
256 + // $groupedCondition .= " HAVING `__created_at` BETWEEN '" . $dateBetweenFilter->start_date . "' AND '" . $dateBetweenFilter->end_date . "' ";
257 + // }
258 + // }
259 +
248 260 $sqlQryByFldCondtion = $this->sqlQryGenerateByFldCondition($fieldConditions);
249 261
250 262 if (!empty($sqlQryByFldCondtion)) {
251 263 $isFldCondition = true;
252 - if ($groupedCondition && false !== strpos($groupedCondition, 'HAVING')) {
264 + if (false !== strpos($groupedCondition, 'HAVING')) {
253 265 $groupedCondition .= ' AND (' . $sqlQryByFldCondtion . ') ';
254 266 } else {
255 267 $groupedCondition .= ' HAVING (' . $sqlQryByFldCondtion . ') ';
256 268 }
@@ -272,12 +284,12 @@
272 284 $orderCondition .= ' ORDER BY ';
273 285 }
274 286 $orderList = '';
275 287 foreach ($sortBy as $sortableFieldKey => $sortableFieldDetails) {
288 + // $orderCondition .=" ".$this->getFieldFormat($sortableFieldDetails->id);
276 289 $sortableFieldChecker += 1;
277 - if (in_array($sortableFieldDetails->id, $formFieldsNames, true)) {
278 - $safeId = sanitize_key($sortableFieldDetails->id);
279 - $orderList .= " `$safeId` ";
290 + if (in_array($sortableFieldDetails->id, $formFieldsNames)) {
291 + $orderList .= " `$sortableFieldDetails->id` ";
280 292 $orderFollow = $sortableFieldDetails->desc ? ' DESC ' : ' ASC ';
281 293 $orderList .= ' ' . $orderFollow;
282 294 if ($sortableFieldChecker < $sortableFieldCount) {
283 295 $orderList .= ', ';
@@ -312,18 +324,20 @@
312 324 public function getEntryMeta($formFields, $entries, $limit = null, $offset = null, $filter = null, $sortBy = null, $fieldConditions = null, $dateBetweenFilter = null)
313 325 {
314 326 $entry_table = $this->app_db->prefix . 'bitforms_form_entries';
315 327 $fieldCount = count($formFields);
316 - $getSelectedMetaFldValue = $this->selectedEntryMeta($formFields, $fieldCount, $filter);
328 + $getSelectedMetaFldValue = $this->selectedEntryMeta($formFields, $fieldCount);
329 +
317 330 $selectedMeta = $getSelectedMetaFldValue['selected_meta'];
318 331 $formFieldsNames = $getSelectedMetaFldValue['form_fields_names'];
319 332 $all_values = $getSelectedMetaFldValue['all_values'];
320 - $globalFilterString = $getSelectedMetaFldValue['global_filter_string'];
321 - $globalFilterValues = $getSelectedMetaFldValue['global_filter_values'];
322 333 $entryIDs = [];
323 334 $entryCount = count($entries);
335 + // $paginateEntry = empty($sortBy) && empty($filter['field']) && empty($filter['global']);
336 + // $entries = $paginateEntry ? array_slice($entries, $offset, $limit) : $entries;
337 + $paginateEntry = false;
324 338 foreach ($entries as $entryDetail) {
325 - $entryIDs[] = $entryDetail->id ?? $entryDetail;
339 + $entryIDs[] = $entryDetail->id;
326 340 }
327 341 if (empty($entryIDs)) {
328 342 return [
329 343 'count' => 0,
@@ -330,36 +344,34 @@
330 344 'entries' => [],
331 345 ];
332 346 }
333 347 $condition['bitforms_form_entry_id'] = $entryIDs;
334 - $group = $this->groupedCondition($condition, $all_values, $fieldConditions, $filter, $globalFilterString, $globalFilterValues);
348 + $group = $this->groupedCondition($condition, $all_values, $fieldConditions);
335 349 $groupedCondition = $group['groupedCondition'];
336 350 $all_values = $group['all_values'];
337 351 $isFldCondition = $group['isFldCondition'];
338 - $orderCondition = $this->orderCondition($formFieldsNames, (array) $sortBy);
352 + $orderCondition = $this->orderCondition($formFieldsNames, $sortBy);
339 353
340 354 $paginate = null;
341 - if (!is_null($limit)) {
342 - $limit = intval($limit);
355 + if (!\is_null($limit)) {
356 + $limit = \intval($limit);
343 357 $paginate .= " LIMIT $limit ";
344 358 }
345 - if (!is_null($offset)) {
346 - $offset = intval($offset);
347 - $paginate .= " OFFSET $offset ";
359 + if (!\is_null($offset)) {
360 + $offset = \intval($offset);
361 + $paginate .= " OFFSET $offset ";
348 362 }
349 -
350 363 $sql = "SELECT $selectedMeta FROM `$this->table_name` em";
351 364 $sql .= " INNER JOIN $entry_table e on e.id = em.bitforms_form_entry_id ";
352 365 if ($dateBetweenFilter) {
353 - $startDate = sanitize_text_field($dateBetweenFilter->start_date ?? '');
354 - $endDate = sanitize_text_field($dateBetweenFilter->end_date ?? '');
355 -
366 + $startDate = $dateBetweenFilter->start_date;
367 + $endDate = $dateBetweenFilter->end_date;
356 368 if ($startDate && $endDate) {
357 - $sql .= $this->app_db->prepare(' AND e.created_at BETWEEN %s AND %s', $startDate . ' 00:00:00', $endDate . ' 23:59:59');
369 + $sql .= " AND DATE(e.created_at) BETWEEN '$startDate' AND '$endDate' ";
358 370 } elseif ($startDate) {
359 - $sql .= $this->app_db->prepare(' AND e.created_at >= %s', $startDate . ' 00:00:00');
371 + $sql .= " AND DATE(e.created_at) >= '$startDate' ";
360 372 } elseif ($endDate) {
361 - $sql .= $this->app_db->prepare(' AND e.created_at <= %s', $endDate . ' 23:59:59');
373 + $sql .= " AND DATE(e.created_at) <= '$endDate' ";
362 374 }
363 375 }
364 376 $sql .= $groupedCondition . $orderCondition . $paginate;
365 377 $result = $this->execute($sql, $all_values)->getResult();
@@ -364,15 +376,18 @@
364 376 $sql .= $groupedCondition . $orderCondition . $paginate;
365 377 $result = $this->execute($sql, $all_values)->getResult();
366 378 if (is_wp_error($result)) {
367 379 return [
368 - 'count' => 0,
380 + 'count' => $paginateEntry ? $entryCount : 0,
369 381 'entries' => [],
370 382 'error' => $result->get_error_message()
371 383 ];
372 384 }
373 385 if ($isFldCondition) {
374 - $entryCount = $this->queryRecount($selectedMeta, $groupedCondition, $orderCondition, $all_values);
386 + $condition['bitforms_form_entry_id'] = $entryIDs;
387 + $group = $this->groupedCondition($condition, $all_values, $fieldConditions);
388 + $all_values = $group['all_values'];
389 + $entryCount = $this->queryRecount($selectedMeta, $group['groupedCondition'], $orderCondition, $all_values);
375 390 }
376 391 $resultedEntries = [
377 392 'count' => $entryCount,
378 393 'entries' => $result,
@@ -379,256 +394,146 @@
379 394 ];
380 395 return $resultedEntries;
381 396 }
382 397
383 - public function getSingleEntryMeta($formFields, $entryId)
384 - {
385 - $entry_table = $this->app_db->prefix . 'bitforms_form_entries';
386 - $fieldCount = count($formFields);
387 - $getSelectedMetaFldValue = $this->selectedEntryMeta($formFields, $fieldCount);
388 - $selectedMeta = $getSelectedMetaFldValue['selected_meta'];
389 - $formFieldsNames = $getSelectedMetaFldValue['form_fields_names'];
390 - $all_values = $getSelectedMetaFldValue['all_values'];
391 - $condition['bitforms_form_entry_id'] = [$entryId];
392 - $group = $this->groupedCondition($condition, $all_values, []);
393 - $groupedCondition = $group['groupedCondition'];
394 - $all_values = $group['all_values'];
395 - $orderCondition = $this->orderCondition($formFieldsNames, null);
396 - $sql = "SELECT $selectedMeta FROM `$this->table_name` em";
397 - $sql .= " INNER JOIN $entry_table e on e.id = em.bitforms_form_entry_id ";
398 - $sql .= $groupedCondition . $orderCondition;
399 - $result = $this->execute($sql, $all_values)->getResult();
398 + private function csvInjectionPrevent($value)
399 + {
400 + $formula = ['=', '-', '+', '@', "\t", "\r"];
401 + $valueFilter = preg_replace('/[\]["]/i', '', $value);
402 + if (\in_array(substr($value, 0, 1), $formula, true)) {
403 + $valueFilter = "'" . trim($valueFilter);
404 + }
400 405
401 - if (is_wp_error($result)) {
402 - return [];
406 + return $valueFilter;
403 407 }
404 - return $result;
405 - }
406 408
407 - private static function csvInjectionPrevent($value)
408 - {
409 - $formula = ['=', '-', '+', '@', "\t", "\r"];
410 - $valueFilter = preg_replace('/[\]["]/i', '', $value);
411 - if (in_array(substr($value, 0, 1), $formula, true)) {
412 - $valueFilter = "'" . trim($valueFilter);
413 - }
409 + public function getExportEntry($formFields, $entries, $formId, $fieldLabels, $limit = null, $sortBy = null, $sortByField = null)
410 + {
411 + $entry_table = $this->app_db->prefix . 'bitforms_form_entries';
412 + $selectedEntryMeta = '`bitforms_form_entry_id` as entry_id,';
413 + $selectedEntryMeta .= "e.user_id as '__user_id',";
414 + $selectedEntryMeta .= "e.status as '__entry_status',";
415 + $selectedEntryMeta .= "e.user_ip as '__user_ip',";
416 + $selectedEntryMeta .= "e.user_location as '__user_location',";
417 + $selectedEntryMeta .= "e.user_device as '__user_device',";
418 + $selectedEntryMeta .= "e.referer as '__referer',";
419 + $selectedEntryMeta .= "e.created_at as '__created_at',";
420 + $selectedEntryMeta .= "e.updated_at as '__updated_at',";
421 + $metaChecker = 0;
414 422
415 - return $valueFilter;
416 - }
417 -
418 - private static function unescapeString($str)
419 - {
420 - if (is_string($str) && '' !== $str) {
421 - $decoded = json_decode('"' . str_replace('"', '\\"', $str) . '"');
422 - return (null !== $decoded) ? $decoded : $str;
423 - }
424 - return $str;
425 - }
426 -
427 - private static function formatRepeaterValue($rawValue, $fieldMap)
428 - {
429 - if (empty($rawValue)) {
430 - return '';
431 - }
432 - $rows = [];
433 - preg_match_all('/\{([^}]+)\}/', $rawValue, $matches);
434 -
435 - foreach ($matches[1] as $row) {
436 - $pairs = explode(',', $row);
437 - $formattedPairs = [];
438 -
439 - foreach ($pairs as $pair) {
440 - if (false === strpos($pair, ':')) {
423 + $entryInfo = ['__user_id', '__user_ip', /* '__user_location', */'__user_device',
424 + '__referer', '__created_at', '__updated_at'];
425 + $all_values = [];
426 + if ([] === $formFields) {
427 + $data = [
428 + 'count' => 0,
429 + 'entries' => [],
430 + ];
431 + wp_send_json_success($data, 200);
432 + }
433 + $fieldCount = count($formFields) - count(array_intersect($formFields, $entryInfo));
434 + $formFieldsNames = [];
435 + foreach ($formFields as $fldKey) {
436 + $formFieldsNames[] = $fldKey;
437 + if (in_array($fldKey, $entryInfo)) {
441 438 continue;
442 439 }
443 - [$childKey, $value] = explode(':', $pair, 2);
444 - $childKey = trim($childKey);
445 - $value = trim($value);
446 -
447 - // Get label from fieldMap or use key
448 - $label = $fieldMap[$childKey]['adminLbl'] ?? $childKey;
449 - $formattedPairs[] = "$label: " . self::unescapeString($value);
450 - }
451 -
452 - $rows[] = implode(', ', $formattedPairs);
453 - }
454 -
455 - return implode('; ', $rows);
456 - }
457 -
458 - public function getExportEntry($formFields, $entries, $formId, $fieldLabels, $limit = null, $sortBy = null, $sortByField = null, $offset = null, $entryConditions = null)
459 - {
460 - $entry_table = $this->app_db->prefix . 'bitforms_form_entries';
461 - $selectedEntryMeta = '`bitforms_form_entry_id` as entry_id,';
462 - $selectedEntryMeta .= 'e.user_id as `__user_id`,';
463 - $selectedEntryMeta .= 'e.status as `__entry_status`,';
464 - $selectedEntryMeta .= 'e.user_ip as `__user_ip`,';
465 - $selectedEntryMeta .= 'e.user_location as `__user_location`,';
466 - $selectedEntryMeta .= 'e.user_device as `__user_device`,';
467 - $selectedEntryMeta .= 'e.referer as `__referer`,';
468 - $selectedEntryMeta .= 'e.created_at as `__created_at`,';
469 - $selectedEntryMeta .= 'e.updated_at as `__updated_at`,';
470 - $metaChecker = 0;
471 -
472 - $entryInfo = [
473 - '__user_id',
474 - '__user_ip', /* '__user_location', */
475 - '__user_device',
476 - '__entry_status',
477 - '__referer',
478 - '__created_at',
479 - '__updated_at'
480 - ];
481 - $all_values = [];
482 - if ([] === $formFields) {
483 - return [
484 - 'count' => 0,
485 - 'entries' => [],
486 - ];
487 - }
488 - $fieldCount = count($formFields) - count(array_intersect($formFields, $entryInfo));
489 - $formFieldsNames = [];
490 - foreach ($formFields as $fldKey) {
491 - $formFieldsNames[] = $fldKey;
492 - if (in_array($fldKey, $entryInfo, true)) {
493 - continue;
494 - }
495 - $fieldFormat = $this->getFieldFormat($fldKey);
496 - $selectedEntryMeta .= "GROUP_CONCAT(
440 + $fieldFormat = $this->getFieldFormat($fldKey);
441 + $selectedEntryMeta .= "GROUP_CONCAT(
497 442 CASE
498 443 `meta_key`
499 444 WHEN '$fieldFormat' THEN `meta_value`
500 445 END
501 446 ) AS '$fieldFormat'";
502 - $metaChecker += 1;
503 - $all_values[] = $fldKey;
504 - $all_values[] = $fldKey;
505 - if ($metaChecker < $fieldCount) {
506 - $selectedEntryMeta .= ',';
447 + $metaChecker += 1;
448 + $all_values[] = $fldKey;
449 + $all_values[] = $fldKey;
450 + if ($metaChecker < $fieldCount) {
451 + $selectedEntryMeta .= ',';
452 + }
507 453 }
508 - }
509 - $entryIDs = [];
510 - foreach ($entries as $entryDetail) {
511 - $entryIDs[] = $entryDetail->id;
512 - }
513 - if (empty($entryIDs)) {
514 - return [
515 - 'count' => 0,
516 - 'entries' => [],
517 - ];
518 - }
519 - $condition['bitforms_form_entry_id'] = $entryIDs;
520 - $grpCon = $this->groupedCondition($condition, $all_values, $entryConditions);
521 - $groupedCondition = $grpCon['groupedCondition'];
522 - $all_values = $grpCon['all_values'];
523 -
524 - $order = 'DESC' === $sortBy ? 'DESC ' : 'ASC ';
525 - $validSortFields = array_column($fieldLabels, 'key');
526 - $orderField = (!is_null($sortByField) && in_array($sortByField, $validSortFields, true))
527 - ? '`' . sanitize_key($sortByField) . '`'
528 - : '`bitforms_form_entry_id`';
529 -
530 - $orderCondition = "ORDER BY $orderField $order ";
531 - $limitClause = '';
532 - if (!is_null($limit)) {
533 - $limitInt = intval($limit);
534 - $limitClause = " LIMIT $limitInt ";
535 - if (!is_null($offset)) {
536 - $offsetInt = intval($offset);
537 - $limitClause .= " OFFSET $offsetInt ";
454 + $entryIDs = [];
455 + foreach ($entries as $entryDetail) {
456 + $entryIDs[] = $entryDetail->id;
538 457 }
539 - }
540 -
541 - $this->app_db->query('SET SESSION group_concat_max_len = 10000');
542 - $sql = "SELECT $selectedEntryMeta FROM `$this->table_name` em";
543 - $sql .= " INNER JOIN $entry_table e on e.id = em.bitforms_form_entry_id ";
544 - $sql .= $groupedCondition . $orderCondition . $limitClause;
545 - $result = $this->execute($sql, $all_values)->getResult();
546 - if (is_wp_error($result)) {
547 - return new \WP_Error('db_error', 'Internal server error');
548 - }
549 -
550 - $allData = [];
551 - $entryStatus = [
552 - '0' => 'Read',
553 - '1' => 'Unread',
554 - '2' => 'Unconfirmed',
555 - '3' => 'Confirmed',
556 - '9' => 'Draft',
557 - ];
558 - $userIds = array_unique(array_filter(
559 - array_map(static fn ($row) => (int) $row->__user_id, (array) $result),
560 - static fn ($id) => $id > 0
561 - ));
562 - $userNames = [];
563 - if (!empty($userIds)) {
564 - $users = get_users(['include' => $userIds, 'fields' => ['ID', 'display_name']]);
565 - foreach ($users as $user) {
566 - $userNames[$user->ID] = $user->display_name;
458 + if (empty($entryIDs)) {
459 + return [
460 + 'count' => 0,
461 + 'entries' => [],
462 + ];
567 463 }
568 - }
569 - foreach ($result as $key => $value) {
570 - foreach ($formFieldsNames as $formFieldName) {
571 - $allData[$key]['entry_id'] = preg_replace('/[\]["]/i', '', $value->entry_id);
572 - if ('__user_id' === $formFieldName && intval($value->$formFieldName) > 0) {
573 - $allData[$key][$formFieldName] = $userNames[$value->$formFieldName] ?? '';
574 - } elseif ('__user_ip' === $formFieldName) {
575 - $allData[$key][$formFieldName] = long2ip((int) $value->$formFieldName);
576 - } elseif ('__entry_status' === $formFieldName) {
577 - $allData[$key][$formFieldName] = $entryStatus[$value->{$formFieldName}] ?? '';
578 - } else {
579 - $allData[$key][$formFieldName] = preg_replace('/[\]["]/i', '', $value->$formFieldName);
580 - }
464 + $condition['bitforms_form_entry_id'] = $entryIDs;
465 + $formattedCondition = $this->getFormatedCondition($condition);
466 + $groupedCondition = null;
467 + if ($formattedCondition) {
468 + $groupedCondition = $formattedCondition['conditions'] . ' GROUP BY
469 + `bitforms_form_entry_id` ';
470 + $all_values = array_merge($all_values, $formattedCondition['values']);
581 471 }
582 - }
472 + $order = \is_null($sortBy) ? 'DESC ' : "$sortBy";
473 + $orderField = \is_null($sortByField) ? 'bitforms_form_entry_id' : "`$sortByField`";
583 474
584 - $fieldMap = [];
585 - $repeaterFields = [];
586 - $fileFields = [];
587 - $downloadableFieldType = ['file-up', 'signature', 'advanced-file-up'];
475 + $orderCondition = "ORDER BY $orderField $order ";
476 + if (!\is_null($limit)) {
477 + $limitInt = \intval($limit);
478 + $limit = " LIMIT $limitInt ";
479 + }
480 + $sql = "SELECT $selectedEntryMeta FROM `$this->table_name` em";
481 + $sql .= " INNER JOIN $entry_table e on e.id = em.bitforms_form_entry_id ";
482 + $sql .= $groupedCondition . $orderCondition . $limit;
588 483
589 - foreach ($fieldLabels as $field) {
590 - $key = $field['key'];
591 - $fieldMap[$key] = $field;
592 - if ('repeater' === $field['type']) {
593 - $repeaterFields[] = $key;
594 - } elseif (in_array($field['type'], $downloadableFieldType, true)) {
595 - $fileFields[] = $key;
484 + $result = $this->execute($sql, $all_values)->getResult();
485 + $allData = [];
486 + $entry_id = 'entry_id';
487 + $users = get_users(['fields' => ['ID', 'display_name']]);
488 + $userNames = [];
489 + foreach ($users as $key => $value) {
490 + $userNames[$value->ID] = $value->display_name;
596 491 }
597 - }
598 -
599 - foreach ($allData as &$entry) {
600 - foreach ($entry as $key => &$value) {
601 - if (is_string($value)) {
602 - $value = self::csvInjectionPrevent(self::unescapeString($value));
492 + foreach ($result as $key => $value) {
493 + foreach ($formFieldsNames as $formFieldName) {
494 + $allData[$key]['entry_id'] = preg_replace('/[\]["]/i', '', $value->$entry_id);
495 + if ('__user_id' === $formFieldName && intval($value->$formFieldName) > 0) {
496 + $allData[$key][$formFieldName] = $userNames[$value->$formFieldName];
497 + } elseif ('__user_ip' === $formFieldName) {
498 + $allData[$key][$formFieldName] = long2ip($value->$formFieldName);
499 + } else {
500 + $allData[$key][$formFieldName] = preg_replace('/[\]["]/i', '', $value->$formFieldName);
501 + }
603 502 }
604 - if (in_array($key, $repeaterFields, true)) {
605 - $value = self::formatRepeaterValue($value, $fieldMap);
606 - }
607 503 }
608 - unset($value);
609 - }
610 - unset($entry, $value);
611 504
612 - foreach ($allData as &$entry) {
613 - $entryId = $entry['entry_id'];
614 - $_upload_dir = FileHandler::getEntriesFileUploadDir($formId, $entryId);
615 - foreach ($fileFields as $fileKey) {
616 - if (empty($entry[$fileKey])) {
617 - continue;
618 - }
619 - $fileIds = explode(',', $entry[$fileKey]);
620 - $urls = [];
621 - foreach ($fileIds as $fileId) {
622 - $path = "bitforms/bitforms-file/?formID=$formId&entryID=$entryId&fileID=$fileId";
623 - if (file_exists($_upload_dir . DIRECTORY_SEPARATOR . $fileId)) {
624 - $urls[] = site_url($path);
505 + if (is_wp_error($result)) {
506 + wp_send_json_error('Internal server error', 500);
507 + } else {
508 + foreach ($fieldLabels as $field) {
509 + foreach ($allData as $index => $entry) {
510 + if (array_key_exists($field['key'], $entry) && 'file-up' === $field['type']) {
511 + $key = $field['key'];
512 + if (empty($entry[$key])) {
513 + continue;
514 + }
515 + $_upload_dir = BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $formId . DIRECTORY_SEPARATOR . $entry['entry_id'];
516 + if (is_array(explode(',', $entry[$key]))) {
517 + $fileData = [];
518 + foreach (explode(',', $entry[$key]) as $file) {
519 + $uploadedFile = explode('_', $file);
520 + $path = "bitforms/bitforms-file/?formID=$formId&entryID=" . $entry['entry_id'] . "&fileID=$uploadedFile[0]";
521 + if (file_exists($_upload_dir . DIRECTORY_SEPARATOR . $uploadedFile[0])) {
522 + $fileData[] = site_url($path, null);
523 + }
524 + }
525 + $allData[$index][$key] = implode(',', $fileData);
526 + } else {
527 + $uploadedFile = explode('_', $entry[$key]);
528 + $path = "bitforms/bitforms-file/?formID=$formId&entryID=" . $entry['entry_id'] . '&fileID=' . $uploadedFile[0];
529 + if (file_exists($_upload_dir . DIRECTORY_SEPARATOR . $uploadedFile[0])) {
530 + $allData[$index][$key] = site_url($path, null);
531 + }
532 + }
533 + }
625 534 }
626 535 }
627 - $entry[$fileKey] = implode(',', $urls);
536 + wp_send_json_success($allData, 200);
628 537 }
629 538 }
630 - unset($entry);
631 -
632 - return $allData;
633 - }
634 539 }