PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.21.4
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.21.4
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
bit-form / includes / Core / Form / FormManager.php

FormManager.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 2.21.4, at includes/Core/Form/FormManager.php

1,377 lines 50.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Get set Form,fields
5 */
6
7 namespace BitCode\BitForm\Core\Form;
8
9 /**
10 * FrontendFormManager class
11 */
12
13 use BitCode\BitForm\Admin\Form\CustomFieldHandler;
14 use BitCode\BitForm\Admin\Form\Helpers;
15 use BitCode\BitForm\Core\Database\FormEntryLogModel;
16 use BitCode\BitForm\Core\Database\FormEntryMetaModel;
17 use BitCode\BitForm\Core\Database\FormEntryModel;
18 use BitCode\BitForm\Core\Database\FormModel;
19 use BitCode\BitForm\Core\Integration\IntegrationHandler;
20 use BitCode\BitForm\Core\Messages\SuccessMessageHandler;
21 use BitCode\BitForm\Core\Util\FieldValueHandler;
22 use BitCode\BitForm\Core\Util\FileHandler;
23 use BitCode\BitForm\Core\Util\FrontendHelpers;
24 use BitCode\BitForm\Core\Util\IpTool;
25 use BitCode\BitForm\Core\Util\Log;
26 use BitCode\BitForm\Core\WorkFlow\WorkFlow;
27 use BitCode\BitForm\Core\WorkFlow\WorkFlowHandler;
28 use stdClass;
29 use WP_Error;
30
31 class FormManager
32 {
33 // Cache for instances of FormManager by form_id
34 private static $formManagerCache = [];
35 protected static $form;
36 protected $formModel;
37 protected $form_id;
38 private $_has_upload;
39 private $_field_label;
40 private $_fields;
41 private $_repeaterFields;
42 private $_work_flows;
43 private $_conf_messages;
44 private $_atomic_class_map;
45 private $_saveFormAsDraft;
46
47 public function __construct($form_id)
48 {
49 $this->form_id = $form_id;
50 $this->formModel = new FormModel();
51
52 static::$form = $this->formModel->get(
53 [
54 'id',
55 'form_content',
56 'form_name',
57 'created_at',
58 'views',
59 'entries',
60 'status',
61 'builder_helper_state',
62 'atomic_class_map',
63 'generated_script_page_ids',
64 ],
65 [
66 'id' => $form_id,
67 ]
68 );
69 if (!is_wp_error(static::$form)) {
70 $this->_atomic_class_map = json_decode(static::$form[0]->atomic_class_map);
71 $bfMultipleFormsExists = FrontendHelpers::hasMultipleForms();
72 if ($bfMultipleFormsExists && isset($this->_atomic_class_map->atomic_class_map_with_form_id)) {
73 $this->_atomic_class_map = $this->_atomic_class_map->atomic_class_map_with_form_id;
74 } elseif (isset($this->_atomic_class_map->atomic_class_map)) {
75 $this->_atomic_class_map = $this->_atomic_class_map->atomic_class_map;
76 }
77 } else {
78 // Log the error if needed
79 Log::debug_log('Error fetching form: ' . "Form Id = ($form_id)" . static::$form->get_error_message());
80 }
81 }
82
83 // Static method to get the instance of FormManager
84 public static function getInstance($form_id)
85 {
86 // Check if an instance of FormManager is already cached
87 if (!isset(self::$formManagerCache[$form_id])) {
88 // Create and cache the FormManager instance if not found
89 self::$formManagerCache[$form_id] = new self($form_id);
90 }
91
92 // Return the cached instance
93 return self::$formManagerCache[$form_id];
94 }
95
96 public function isExist()
97 {
98 return (!static::$form || is_wp_error(static::$form)) ? false : true;
99 }
100
101 public function checkStatus()
102 {
103 return '1' === static::$form[0]->status ? true : false;
104 }
105
106 public function getFieldsContent()
107 {
108 return self::$form[0]->form_content;
109 }
110
111 public function getFont()
112 {
113 $atomicClassMap = $this->_atomic_class_map;
114 $font = isset($atomicClassMap->font) ? $atomicClassMap->font : '';
115 return $font;
116 }
117
118 public function getStyle()
119 {
120 $builerState = \json_decode(static::$form[0]->builder_helper_state);
121 $style = '';
122 $themeVars = $builerState->themeVars;
123 $themeColors = $builerState->themeColors;
124
125 if (!empty($themeVars)) {
126 $style .= ':root {';
127 foreach ($themeVars->lgLightThemeVars as $key => $value) {
128 $style .= "$key: $value; ";
129 }
130 $style .= '} ';
131 }
132 if (!empty($themeColors)) {
133 $style .= ' :root {';
134 foreach ($themeColors->lightThemeColors as $k => $v) {
135 $style .= "$k:$v; ";
136 }
137 $style .= '} ';
138 }
139
140 $field = $builerState->style->lgLightStyles->fields;
141 foreach ($field as $value) {
142 $classes = $value->classes;
143 foreach ($classes as $key => $value) {
144 $style .= "{$key} {";
145 foreach ($value as $k => $v) {
146 $style .= "$k:$v; ";
147 }
148 $style .= '} ';
149 }
150 }
151 return $style;
152 }
153
154 public function getCustomStyle()
155 {
156 $customCssCodes = '';
157 $customCSSPath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles' . DIRECTORY_SEPARATOR . "bitform-custom-{$this->form_id}.css";
158
159 if (file_exists($customCSSPath)) {
160 $file = fopen($customCSSPath, 'r');
161 $customCssCodes = fread($file, filesize($customCSSPath));
162 fclose($file);
163 }
164
165 return $customCssCodes;
166 }
167
168 public function getCustomJS()
169 {
170 $customJSCodes = '';
171 $customJsPath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-scripts' . DIRECTORY_SEPARATOR . "bitform-custom-{$this->form_id}.js";
172 if (file_exists($customJsPath)) {
173 $file = fopen($customJsPath, 'r');
174 $customJSCodes = fread($file, filesize($customJsPath));
175 fclose($file);
176 }
177
178 return $customJSCodes;
179 }
180
181 public function getFormContentWithValue($defaultValues = [])
182 {
183 $form_content = \json_decode(static::$form[0]->form_content);
184 // this filter just use private purpose
185 $form_content->fields = apply_filters('bitform_dynamic_field_filter', $form_content->fields);
186 if (!is_array($defaultValues) || 0 === count($defaultValues)) {
187 return $form_content;
188 }
189 foreach ($form_content->fields as $fieldKey => $fieldDetails) {
190 // $field_name = empty($fieldDetails->lbl) ? null : \preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\!]/', '_', $fieldDetails->lbl);
191 $fieldName = $fieldDetails->fieldName;
192 $defaultValue = isset($defaultValues[$fieldName]) ? $defaultValues[$fieldName] : null;
193 $defaultValue = isset($defaultValues[$fieldKey]) ? $defaultValues[$fieldKey] : $defaultValue;
194 if ((isset($fieldDetails->mul) || 'check' === $fieldDetails->typ) && isset($defaultValue)) {
195 // if (is_array($defaultValue)) {
196 // $fieldDetails->val =
197 // wp_json_encode(
198 // array_map('sanitize_text_field', $defaultValue)
199 // );
200 // } else {
201 // $fieldDetails->val = sanitize_text_field($defaultValue);
202 // }
203 if ((isset($fieldDetails->mul) && true === $fieldDetails->mul) || is_array($defaultValue)) {
204 $fieldDetails->val = wp_json_encode(array_map('sanitize_text_field', $defaultValue));
205 } elseif (!is_array($defaultValue)) {
206 $fieldDetails->val = sanitize_text_field($defaultValue);
207 }
208 } elseif (!is_null($defaultValue)) {
209 $fieldDetails->val = is_string($defaultValue) ?
210 sanitize_text_field($defaultValue) :
211 sanitize_text_field($defaultValue[count($defaultValue) - 1]);
212 }
213 }
214 return $form_content;
215 }
216
217 public function getFormContent()
218 {
219 $formContent = json_decode(static::$form[0]->form_content);
220 $types = ['check', 'radio', 'select'];
221 $filter = false;
222 foreach ($formContent->fields as $field) {
223 if (in_array($field->typ, $types) && property_exists($field, 'customType')) {
224 $filter = true;
225 break; // reduce unnecessary loop
226 }
227 }
228 if (true === $filter) {
229 $updateFields = apply_filters('bitform_dynamic_field_filter', $formContent->fields);
230 $formContent->fields = $updateFields;
231 }
232 return $formContent;
233 }
234
235 public function getFormInfo()
236 {
237 $formContent = json_decode(static::$form[0]->form_content);
238 $formInfo = isset($formContent->formInfo) ? $formContent->formInfo : null;
239 return $formInfo;
240 }
241
242 public function getFormPermission()
243 {
244 $formContent = json_decode(static::$form[0]->form_content);
245 $formPermission = isset($formContent->formPermissions) ? $formContent->formPermissions : null;
246 return $formPermission;
247 }
248
249 public function getFormHelperStates()
250 {
251 $formHelperStates = json_decode(static::$form[0]->builder_helper_state);
252 return $formHelperStates;
253 }
254
255 public function getAtomicClsMap()
256 {
257 return $this->_atomic_class_map;
258 }
259
260 private function is_json($str)
261 {
262 $json = json_decode($str);
263 return $json && $str !== $json;
264 }
265
266 public function getFormData($columnName = '')
267 {
268 if (empty($columnName)) {
269 return null;
270 }
271
272 $form = static::$form[0];
273 if (!isset($form->{$columnName})) {
274 return null;
275 }
276
277 $data = $form->{$columnName};
278 if ($this->is_json($data)) {
279 return json_decode($data);
280 }
281
282 return $data;
283 }
284
285 public function getFormName()
286 {
287 return static::$form[0]->form_name;
288 }
289
290 public function getFormLayout()
291 {
292 $formContent = $this->getFormContent();
293 return $formContent->layout;
294 }
295
296 public function getFormNestedLayout()
297 {
298 $formContent = $this->getFormContent();
299 return $formContent->nestedLayout;
300 }
301
302 private function mergeNestedLayout(&$layout, $nestedLayout)
303 {
304 foreach ($nestedLayout as $key => $brkpnts) {
305 foreach ($brkpnts as $brkpnt=>$nLayout) {
306 $layout->{$brkpnt} = array_merge($layout->{$brkpnt}, $nLayout);
307 }
308 }
309 }
310
311 public function flatMultistepFormLayout()
312 {
313 $formLayout = $this->getFormLayout();
314 $multistepLayout = new stdClass();
315 foreach ($formLayout as $stpLayout) {
316 $lyout = $stpLayout->layout;
317
318 foreach ($lyout as $brkpnt=>$fields) {
319 $multistepLayout->{$brkpnt} = array_merge($multistepLayout->{$brkpnt} ?? [], $fields);
320 }
321 }
322
323 return $multistepLayout;
324 }
325
326 public function getFlatenFormLayout()
327 {
328 $layout = $this->getFormLayout();
329 $nestedLayout = $this->getFormNestedLayout();
330 if ('array' === gettype($layout)) {
331 // multi step form layout
332 $layout = $this->flatMultistepFormLayout();
333 }
334 if (!empty(get_object_vars($nestedLayout))) {
335 $this->mergeNestedLayout($layout, $nestedLayout);
336 }
337
338 return $layout;
339 }
340
341 public function getFieldsBasedOnLayout()
342 {
343 $layout = $this->getFlatenFormLayout();
344
345 $fieldKeyOrderbasedOnLayout = array_map(function ($fld) {
346 return $fld->i;
347 }, $layout->lg);
348 $orderedFields = [];
349 $fields = $this->getFields();
350
351 foreach ($fieldKeyOrderbasedOnLayout as $key) {
352 if (array_key_exists($key, $fields)) {
353 $orderedFields[$key] = $fields[$key];
354 }
355 }
356
357 foreach ($fields as $k=>$v) {
358 if (!array_key_exists($k, $fieldKeyOrderbasedOnLayout)) {
359 $orderedFields[$k] = $fields[$k];
360 }
361 }
362
363 return $orderedFields;
364 }
365
366 public function getFields()
367 {
368 if (!is_null($this->_fields)) {
369 return $this->_fields;
370 }
371 $form_content = \json_decode(static::$form[0]->form_content);
372 $layout = $form_content->layout;
373 $fields = $form_content->fields;
374 $field_details = [];
375 foreach ($fields as $key => $field) {
376 if ('recaptcha' === $field->typ || 'hcaptcha' === $field->typ) {
377 continue;
378 }
379 // $field_name = empty($field->lbl) ? null : \preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\\!]/', '_', $field->lbl);
380 $field_type = $field->typ;
381 $field_details[$key]['label'] = empty($field->lbl) ? null : $field->lbl;
382 $field_details[$key]['type'] = $field_type;
383 $field_details[$key]['key'] = $key;
384 $field_details[$key]['name'] = isset($field->fieldName) ? $field->fieldName : '';
385 if (isset($field->customType)) {
386 $field_details[$key]['customType'] = $field->customType;
387 }
388
389 if (isset($field->err)) {
390 if (isset($field->err->entryUnique)) {
391 $field_details[$key]['entryUnique'] = $field->err->entryUnique;
392 }
393 if (isset($field->err->userUnique)) {
394 $field_details[$key]['userUnique'] = $field->err->userUnique;
395 }
396 }
397
398 if (isset($field->mul)) {
399 $field_details[$key]['mul'] = $field->mul;
400 }
401 if ('file-up' === $field_type && isset($field->exts)) {
402 $field_details[$key]['valid']['type'] = $field->exts;
403 }
404 if ('file-up' === $field_type && isset($field->mxUp)) {
405 $field_details[$key]['valid']['upload_size'] = (int) $field->mxUp;
406 }
407 if (isset($field->valid) && !is_null($field->valid)) {
408 if (isset($field->valid->req)) {
409 $field_details[$key]['valid']['req'] = $field->valid->req;
410 }
411 if (isset($field->valid->reqMsg)) {
412 $field_details[$key]['valid']['reqMsg'] = $field->valid->reqMsg;
413 }
414 if (isset($field->valid->typMsg)) {
415 $field_details[$key]['valid']['typMsg'] = $field->valid->typMsg;
416 }
417 if (isset($field->valid->hide)) {
418 $field_details[$key]['valid']['hide'] = $field->valid->hide;
419 }
420 }
421 if ($this->isRepeatedField($key)) {
422 $field_details[$key]['repeated'] = true;
423 }
424 }
425 if ($this->isGCLIDEnabled()) {
426 $field_details['GCLID']['name'] = 'GCLID';
427 $field_details['GCLID']['adminLbl'] = 'GCLID';
428 $field_details['GCLID']['key'] = 'GCLID';
429 $field_details['GCLID']['type'] = 'hidden';
430 }
431 $this->_fields = $field_details;
432 return $field_details;
433 }
434
435 public function getFieldsKey()
436 {
437 $form_content = \json_decode(static::$form[0]->form_content);
438 $fields = $form_content->fields;
439 $field_details = [];
440 foreach ($fields as $key => $field) {
441 if ('recaptcha' === $field->typ || 'hcaptcha' === $field->typ) {
442 continue;
443 }
444 // $field_name = empty($field->lbl) ? null : \preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\\!]/', '_', $field->lbl);
445 $field_details[$key] = $key;
446 }
447 if ($this->isGCLIDEnabled()) {
448 $field_details['GCLID'] = 'GCLID';
449 }
450 return $field_details;
451 }
452
453 public function getFieldLabel($forQuery = false)
454 {
455 if (!is_null($this->_field_label)) {
456 return $this->_field_label;
457 }
458 $form_content = \json_decode(static::$form[0]->form_content);
459 $fields = $form_content->fields;
460 $field_details = [];
461 $fieldCounter = 0;
462 foreach ($fields as $key => $field) {
463 if ('recaptcha' === $field->typ || 'turnstile' === $field->typ || 'html' === $field->typ || 'button' === $field->typ) {
464 continue;
465 }
466 $field_details[$fieldCounter]['name'] = empty($field->lbl) ? null : $field->lbl;
467 $field_details[$fieldCounter]['adminLbl'] = empty($field->adminLbl) ? $field_details[$fieldCounter]['name'] : $field->adminLbl;
468 $field_details[$fieldCounter]['key'] = $key;
469 $field_details[$fieldCounter]['type'] = $field->typ;
470 $fieldCounter += 1;
471 }
472 if ($this->isGCLIDEnabled()) {
473 $field_details[$fieldCounter]['name'] = 'GCLID';
474 $field_details[$fieldCounter]['adminLbl'] = 'GCLID';
475 $field_details[$fieldCounter]['key'] = 'GCLID';
476 $field_details[$fieldCounter]['type'] = 'hidden';
477 $fieldCounter += 1;
478 }
479 if (!$forQuery) {
480 $field_details = (array) $this->addEntryInfo($field_details, $fieldCounter);
481 }
482 $this->_field_label = $field_details;
483 return $field_details;
484 }
485
486 public function getUploadFields()
487 {
488 if (!is_null($this->_has_upload)) {
489 return $this->_has_upload;
490 }
491 $upload_fields = [];
492 $form_field_details = $this->getFields();
493 foreach ($form_field_details as $field_name => $__field_detail) {
494 if (isset($__field_detail['type']) && ('file-up' === $__field_detail['type'] || 'advanced-file-up' === $__field_detail['type'])) {
495 $upload_fields[] = $field_name;
496 }
497 }
498 $this->_has_upload = $upload_fields;
499 return $upload_fields;
500 }
501
502 public function getSignatureFilePath($blobLink, $form_id, $fieldKey, $entry_id, $imgType)
503 {
504 $imgTypes = [
505 'image/png' => 'png',
506 'image/jpeg' => 'jpg',
507 'image/svg+xml' => 'svg',
508 ];
509 try {
510 if (!isset($imgTypes[$imgType])) {
511 throw new \InvalidArgumentException("Unsupported image type: $imgType");
512 }
513 $parts = explode(',', $blobLink, 2);
514 if (2 !== count($parts) || false === ($decoded_image = base64_decode($parts[1]))) {
515 throw new \RuntimeException('Invalid or corrupt signature data URI');
516 }
517
518 $_upload_dir = FileHandler::getEntriesFileUploadDir($form_id, $entry_id);
519 FileHandler::createIndexFile($_upload_dir);
520
521 $filename = "{$entry_id}-{$fieldKey}.{$imgTypes[$imgType]}";
522 $fullPath = $_upload_dir . DIRECTORY_SEPARATOR . $filename;
523 if (false === file_put_contents($fullPath, $decoded_image)) {
524 throw new \RuntimeException("Failed to write image to $fullPath");
525 }
526 return $filename;
527 } catch (\Throwable $e) {
528 Log::debug_log("[Signature Error] Form: $form_id, Entry: $entry_id, Field: $fieldKey - " . $e->getMessage());
529 return 'signature-failed.png'; // or a default filename if appropriate
530 }
531 }
532
533 private function entryInsert($user_details)
534 {
535 $formEntryModel = new FormEntryModel();
536 $entryId = $formEntryModel->insert(
537 [
538 'form_id' => $this->form_id,
539 'user_id' => $user_details['id'],
540 'user_ip' => $user_details['ip'],
541 'user_device' => $user_details['device'],
542 'referer' => $user_details['page'],
543 'status' => $this->_saveFormAsDraft ? 9 : 1,
544 'created_at' => $user_details['time'],
545 ]
546 );
547 return $entryId;
548 }
549
550 private function submisionLog($user_details, $entry_id, $type)
551 {
552 $formEntryLogModel = new FormEntryLogModel();
553 $submissionLogData = [
554 'user_id' => $user_details['id'],
555 'action_type' => $type, // create, update
556 'log_type' => 'entry',
557 'ip' => $user_details['ip'],
558 'form_entry_id' => $entry_id,
559 'content' => ['user_device' => $user_details['device']],
560 'form_id' => $this->form_id,
561 'created_at' => $user_details['time'],
562 ];
563 $submissionLogData = apply_filters('bitform_filter_submission_log_data', $submissionLogData, $this->form_id, $type);
564 $logId = $formEntryLogModel->form_log_insert(
565 $submissionLogData
566 );
567 return $logId;
568 }
569
570 private function isArrayAllKeyInt($InputArray)
571 {
572 if (!is_array($InputArray)) {
573 return false;
574 }
575
576 if (count($InputArray) <= 0) {
577 return true;
578 }
579
580 return array_unique(array_map('is_int', array_keys($InputArray))) === [true];
581 }
582
583 public function formatSubmittedData($submitted_data)
584 {
585 $form_content = $this->getFormContent();
586 $form_fields = $form_content->fields;
587
588 foreach ($submitted_data as $key => $value) {
589 if (!isset($form_fields->{$key})) {
590 continue;
591 }
592 $field_data = $form_fields->{$key};
593 $field_type = $field_data->typ;
594 if ('select' === $field_type && !empty($field_data->config->multipleSelect)) {
595 $valueArr = [];
596 if ($this->isRepeatedField($key)) {
597 foreach ($value as $index => $v) {
598 $valueArr[$index] = explode(BITFORMS_BF_SEPARATOR, $v);
599 }
600 } else {
601 $valueArr = explode(BITFORMS_BF_SEPARATOR, $value);
602 }
603 $submitted_data[$key] = $valueArr;
604 }
605 }
606 $submitted_data = apply_filters('bitform_filter_format_submitted_data', $submitted_data, $this->form_id);
607 return $submitted_data;
608 }
609
610 private function addNewFilePathToFiles($form_id, $entry_id, $file_fields = [])
611 {
612 $common_file_path = Helpers::getWebPathWithEncryptedEntryId($form_id, $entry_id);
613 // Handle files and assign file_path
614 foreach ($_FILES as $field_key => $file_details) {
615 if (!($file_fields && in_array($field_key, $file_fields))) {
616 continue;
617 }
618
619 $isRepeaterFldKey = $this->isRepeatedField($field_key);
620 if ($isRepeaterFldKey && isset($file_details['new_name'])) {
621 // If 'new_name' is an array (i.e., for repeated fields)
622 foreach ($file_details['new_name'] as $slNo => $newFileNamesArray) {
623 if (is_array($newFileNamesArray)) {
624 foreach ($newFileNamesArray as $newFileName) {
625 $filePath = $common_file_path . DIRECTORY_SEPARATOR . $newFileName;
626 $_FILES[$field_key]['file_path'][$slNo][] = $filePath;
627 }
628 } else {
629 // Generate the file path for each file
630 $filePath = $common_file_path . DIRECTORY_SEPARATOR . $newFileNamesArray;
631 $_FILES[$field_key]['file_path'][$slNo] = $filePath;
632 }
633 }
634 } elseif (isset($file_details['new_name'])) {
635 // If 'new_name' is an array (i.e., for repeated fields)
636 if (is_array($file_details['new_name'])) {
637 foreach ($file_details['new_name'] as $slNo => $newFileName) {
638 // Generate the file path for each file
639 $filePath = $common_file_path . DIRECTORY_SEPARATOR . $newFileName;
640 $_FILES[$field_key]['file_path'][$slNo] = $filePath;
641 }
642 } else {
643 $filePath = $common_file_path . DIRECTORY_SEPARATOR . $file_details['new_name'];
644 $_FILES[$field_key]['file_path'] = $filePath;
645 }
646 }
647 }
648 }
649
650 private function formatRepeateFieldData($submitted_data, $form_fields)
651 {
652 $repeaterFields = $this->getRepeaterFields();
653 foreach ($repeaterFields as $repeaterFldKey => $repeatedFields) {
654 $repeatIndexes = $submitted_data["{$form_fields[$repeaterFldKey]['name']}-repeat-index"];
655 $repeatIndexes = explode(',', $repeatIndexes);
656 foreach ($repeatIndexes as $slNo => $repeatIndex) {
657 foreach ($repeatedFields as $repeatedField) {
658 if (!isset($submitted_data[$repeatedField][$repeatIndex])) {
659 continue;
660 }
661 if (!isset($submitted_data[$repeaterFldKey][$slNo])) {
662 $submitted_data[$repeaterFldKey][$slNo] = [];
663 }
664 if (!isset($submitted_data[$repeaterFldKey][$slNo][$repeatedField])) {
665 $submitted_data[$repeaterFldKey][$slNo][$repeatedField] = [];
666 }
667 $submitted_data[$repeaterFldKey][$slNo][$repeatedField] = $submitted_data[$repeatedField][$repeatIndex];
668 }
669 }
670 foreach ($repeatedFields as $repeatedField) {
671 unset($submitted_data[$repeatedField]);
672 }
673 unset($submitted_data["{$form_fields[$repeaterFldKey]['name']}-repeat-index"]);
674 }
675
676 return $submitted_data;
677 }
678
679 private function saveEntryMeta($submitted_data, $entry_id)
680 {
681 $errorInEntryMetaInsert = false;
682 $entryMeta = new FormEntryMetaModel();
683 foreach ($submitted_data as $key => $value) {
684 $value = $submitted_data[$key];
685 if (is_string($value)) {
686 $value = wp_unslash($value);
687 } elseif ($this->isArrayAllKeyInt($value)) {
688 $value = wp_json_encode(array_values($value));
689 } else {
690 $value = wp_json_encode($value);
691 }
692 $status = $entryMeta->insert(
693 [
694 'bitforms_form_entry_id' => $entry_id,
695 'meta_key' => $key,
696 'meta_value' => $value,
697 ]
698 );
699 if (is_wp_error($status)) {
700 $errorInEntryMetaInsert = true;
701 break;
702 }
703 }
704 return $errorInEntryMetaInsert;
705 }
706
707 public function setSaveFormAsDraft()
708 {
709 $this->_saveFormAsDraft = true;
710 }
711
712 public function saveFormEntry($submitted_data)
713 {
714 $submitted_data = $this->formatSubmittedData($submitted_data);
715 $submitted_data = apply_filters('bitform_filter_save_form_entry', $submitted_data, $this->form_id);
716 $form_content = \json_decode(static::$form[0]->form_content);
717 do_action('bitform_save_entry', $this, $submitted_data, $this->form_id);
718 $key = null;
719 $ipTool = new IpTool();
720 $fileHandler = new FileHandler();
721 $form_fields = $this->getFields();
722 $file_fields = $this->getUploadFields();
723
724 foreach ($_FILES as $file_name => $file_details) {
725 if ($file_fields && in_array($file_name, $file_fields)) {
726 $validation = $fileHandler->validation($file_name, $file_details, $this->form_id);
727 if (!empty($validation['error_type']) && !empty($validation['message'])) {
728 return new WP_Error($validation['error_type'], __($validation['message'], 'bit-form'));
729 }
730 }
731 }
732 $user_details = $ipTool->getUserDetail();
733 $user_details = apply_filters('bitform_filter_user_details', $user_details, $this->form_id);
734 $user_details = apply_filters('bitform_filter_save_entry_user_details', $user_details, $this->form_id);
735
736 $form_fields = $this->getFields();
737 $submitted_data = $this->passwordEncrypted($submitted_data, $form_fields);
738 $submitted_data = $this->formatRepeateFieldData($submitted_data, $form_fields);
739 global $wpdb;
740 $wpdb->query('START TRANSACTION');
741 $entry_id = $this->entryInsert($user_details);
742 $log_id = null;
743
744 $GLOBALS['bf_entry_id'] = $entry_id;
745
746 if (is_wp_error($entry_id)) {
747 return new WP_Error('insert_error', __('Sorry, Error occurred in saving form entry', 'bit-form'));
748 }
749 if ($entry_id) {
750 $log_id = $this->submisionLog($user_details, $entry_id, 'create', $key);
751 if (is_wp_error($log_id)) {
752 $wpdb->query('ROLLBACK');
753 return new WP_Error('error_entry_log', __('Sorry, error occurred in logging form entry', 'bit-form'));
754 }
755 }
756 if ($entry_id) {
757 $submitted_fields = $this->getFormContentWithValue($submitted_data)->fields;
758 $workFlowRunHelper = new WorkFlow($this->form_id);
759
760 $workFlowreturnedOnSubmit = $workFlowRunHelper->executeOnSubmit(
761 'create',
762 $submitted_fields,
763 $submitted_data,
764 $entry_id,
765 $log_id
766 );
767
768 if (!empty($workFlowreturnedOnSubmit['fields'])) {
769 $submitted_data = $workFlowreturnedOnSubmit['fields'];
770 }
771
772 $file_fields = $this->getUploadFields();
773 $formFields = $this->getFields();
774 $submitted_data = FileHandler::tempDirToUploadDir($submitted_data, $formFields, $this->form_id, $entry_id);
775 $fileHandler = new FileHandler();
776 foreach ($_FILES as $field_key => $file_details) {
777 if ($file_fields && in_array($field_key, $file_fields)) {
778 $fileNames = [];
779 $repeaterFldKey = $this->isRepeatedField($field_key);
780 if ($repeaterFldKey) {
781 foreach ($file_details['name'] as $slNo => $fileName) {
782 $repeateFileDetails = [
783 'name' => $file_details['name'][$slNo],
784 'type' => $file_details['type'][$slNo],
785 'tmp_name' => $file_details['tmp_name'][$slNo],
786 'error' => $file_details['error'][$slNo],
787 'size' => $file_details['size'][$slNo],
788 ];
789 $fileNames = $fileHandler->moveUploadedFiles($repeateFileDetails, $this->form_id, $entry_id);
790 if (!empty($fileNames)) {
791 $submitted_data[$repeaterFldKey][$slNo - 1][$field_key] = $fileNames;
792 $_FILES[$field_key]['new_name'][$slNo - 1] = $fileNames;
793 }
794 }
795 } else {
796 $fileNames = $fileHandler->moveUploadedFiles($file_details, $this->form_id, $entry_id);
797 if (!empty($fileNames)) {
798 $submitted_data[$field_key] = $fileNames;
799 $_FILES[$field_key]['new_name'] = $fileNames;
800 }
801 }
802 }
803 }
804
805 // Get the common path for file storage
806 $this->addNewFilePathToFiles($this->form_id, $entry_id, $file_fields);
807
808 foreach ($form_content->fields as $key => $field) {
809 /* ======== for Signature field ===========*/
810 if ('signature' === $field->typ) {
811 if (isset($submitted_data[$key])) {
812 $fld_data = $submitted_data[$key];
813 $img_type = $field->config->imgTyp;
814 $submitted_data[$key] = $this->getSignatureFilePath($fld_data, $this->form_id, $key, $entry_id, $img_type);
815 }
816 }
817
818 // for Signature field inside reepater
819 if ('repeater' === $field->typ) {
820 $rptr_data = $submitted_data[$key];
821 $formFields = $form_content->fields;
822 $this->setSignatureFilePathInRepeater($rptr_data, $key, $formFields, $entry_id, $submitted_data);
823 }
824 }
825
826 if (!isset($form_content->additional->enabled->submission)) {
827 $errorInEntryMetaInsert = $this->saveEntryMeta($submitted_data, $entry_id);
828 if ($errorInEntryMetaInsert) {
829 do_action('bitform_save_entry_error', $this, $submitted_data, $this->form_id);
830 $wpdb->query('ROLLBACK');
831 return new WP_Error('insert_error', __('Sorry, Error occured in saving form entry data', 'bit-form'));
832 }
833 do_action('bitform_after_save_entry_success', $this, $submitted_data, $this->form_id, $entry_id);
834 } else {
835 $wpdb->query('ROLLBACK');
836 }
837 $wpdb->query('COMMIT');
838 $this->setSubmissionCount();
839 $workFlowreturnedOnSubmit['entry_id'] = $entry_id;
840 $workFlowreturnedOnSubmit['fields'] = $submitted_data;
841 $workFlowreturnedOnSubmit = apply_filters('bitform_filter_return_submit_success', $workFlowreturnedOnSubmit, $this->form_id);
842
843 return $workFlowreturnedOnSubmit;
844 }
845 }
846
847 private function setSignatureFilePathInRepeater($repeaterData, $repeaterFieldKey, $formFields, $entry_id, &$submitted_data)
848 {
849 foreach ($repeaterData as $rptr_entry_index => $rptr_entries) {
850 foreach ($rptr_entries as $entry_key => $entry_value) {
851 $rptr_entry_info = $formFields->{$entry_key};
852
853 if ('signature' === $rptr_entry_info->typ) {
854 $imgType = $rptr_entry_info->config->imgTyp;
855 $signatureImage = $this->getSignatureFilePath($entry_value, $this->form_id, $repeaterFieldKey, $entry_id, $imgType);
856 $submitted_data[$repeaterFieldKey][$rptr_entry_index][$entry_key] = $signatureImage;
857 }
858 }
859 }
860 }
861
862 public function passwordEncrypted($updatedValue, $form_fields)
863 {
864 $integrationHandler = new IntegrationHandler($this->form_id);
865 $formIntegrations = $integrationHandler->getAllIntegration('wp_user_auth', 'wp_auth', 1);
866 if (!isset($formIntegrations->errors['result_empty'])) {
867 foreach ($form_fields as $field) {
868 if (array_key_exists($field['key'], $updatedValue) && 'password' === $field['type']) {
869 $updatedValue[$field['key']] = '**** (encrypted)';
870 }
871 }
872 }
873 return $updatedValue;
874 }
875
876 public function updateFormEntry($updatedValue, $formID, $entryID)
877 {
878 $updatedValue = $this->formatSubmittedData($updatedValue);
879 $updatedValue = apply_filters('bitform_filter_update_form_entry', $updatedValue, $this->form_id);
880 do_action('bitform_update_entry', $this, $updatedValue, $formID, $entryID);
881 $formEntryModel = new FormEntryModel();
882 $formEntryLogModel = new FormEntryLogModel();
883 $formOldData = $formEntryLogModel->get_form_value($entryID);
884 $key = null;
885 $entryMeta = new FormEntryMetaModel();
886 $ipTool = new IpTool();
887 $user_details = $ipTool->getUserDetail();
888 $user_details = apply_filters('bitform_filter_user_details', $user_details, $this->form_id);
889 $user_details = apply_filters('bitform_filter_update_entry_user_details', $user_details, $this->form_id);
890
891 $form_fields = $this->getFields();
892
893 $updatedValue = $this->passwordEncrypted($updatedValue, $form_fields);
894 $updatedValue = $this->formatRepeateFieldData($updatedValue, $form_fields);
895 $field_map = [];
896 foreach ($formOldData as $index => $data) {
897 foreach ($form_fields as $field_key => $field) {
898 if ($data->meta_key === $field['key']) {
899 $field_map[$field_key] = $field['key'];
900 }
901 }
902 }
903 $oldEntry = $formEntryModel->get('status', ['id' => $entryID])[0];
904 $formEntry = $formEntryModel->update(
905 [
906 'status' => ('9' === $oldEntry->status && !$this->_saveFormAsDraft) ? 1 : $oldEntry->status,
907 'updated_at' => $user_details['time'],
908 ],
909 [
910 'form_id' => $formID,
911 'id' => $entryID,
912 ]
913 );
914 $log_id = null;
915 if ($formEntry) {
916 $log_id = $this->submisionLog($user_details, $entryID, 'update');
917 }
918
919 if (is_wp_error($formEntry) || !$formEntry) {
920 return new WP_Error('empty_form', __('provided form entries does not exists', 'bit-form'));
921 }
922 $formFields = $this->getFields();
923 $updatedValue = FileHandler::tempDirToUploadDir($updatedValue, $formFields, $this->form_id, $entryID);
924 $file_fields = $this->getUploadFields();
925 if (count($file_fields) > 0) {
926 $fileHandler = new FileHandler();
927 foreach ($_FILES as $file_name => $file_details) {
928 if ($file_fields && in_array($file_name, $file_fields)) {
929 $validation = $fileHandler->validation($file_name, $file_details, $this->form_id);
930 if (!empty($validation['error_type']) && !empty($validation['message'])) {
931 return new WP_Error($validation['error_type'], __($validation['message'], 'bit-form'));
932 }
933 }
934 }
935 if (is_object($updatedValue)) {
936 $updatedValue = (array) $updatedValue;
937 }
938 foreach ($file_fields as $field_key) {
939 $repeaterFldKey = $this->isRepeatedField($field_key);
940 if (isset($updatedValue[$field_key . '_old'])) {
941 // Handle file deletion for repeater fields
942 if ($repeaterFldKey) {
943 $repeaterExistData = $entryMeta->get(
944 'meta_value',
945 [
946 'bitforms_form_entry_id' => $entryID,
947 'meta_key' => $repeaterFldKey,
948 ]
949 );
950 if (!is_wp_error($repeaterExistData)) {
951 // restructor json
952 $repeaterExistData = json_decode($repeaterExistData[0]->meta_value, true);
953 $repeaterExistFiles = [];
954 $repeaterDeleted_files = [];
955 $repeaterFiles_old = [];
956 foreach ($repeaterExistData as $index => $repeaterRow) {
957 $repeaterExistFiles[$index] = [];
958 if (isset($repeaterRow[$field_key]) && !empty($repeaterRow[$field_key])) {
959 $repeaterExistFiles[$index] = json_decode($repeaterRow[$field_key], true);
960 }
961 $repeaterFiles_old[$index] = empty($updatedValue[$field_key . '_old'][$index]) ? [] : explode(',', $updatedValue[$field_key . '_old'][$index]);
962 $repeaterDeleted_files[$index] = array_diff($repeaterExistFiles[$index], $repeaterFiles_old[$index]);
963 $fileHandler->deleteFiles($formID, $entryID, $repeaterDeleted_files[$index]);
964 }
965 }
966 } else {
967 // Handle file deletion for non-repeater fields
968 $file_exists = $entryMeta->get(
969 'meta_value',
970 [
971 'bitforms_form_entry_id' => $entryID,
972 'meta_key' => $field_key,
973 ]
974 );
975 if (!is_wp_error($file_exists) && count($file_exists) > 0) {
976 $files_in_db = json_decode($file_exists[0]->meta_value);
977 $files_old = empty($updatedValue[$field_key . '_old']) ? [] : explode(',', $updatedValue[$field_key . '_old']);
978 $deleted_file = array_diff($files_in_db, $files_old);
979 if (count($deleted_file) > 0) {
980 $fileHandler->deleteFiles($formID, $entryID, $deleted_file);
981 }
982 $updatedValue[$field_key] = wp_json_encode($files_old);
983 }
984 }
985 }
986 if (!empty($_FILES[$field_key]['name'])) {
987 if ($repeaterFldKey) {
988 // Handle repeater field files
989 $file_details = $_FILES[$field_key];
990 foreach ($file_details['name'] as $index => $file) {
991 // Retrieve existing old files for this specific repeater index
992 if (isset($repeaterFiles_old[$index - 1]) && count($repeaterFiles_old[$index - 1]) > 0) {
993 $old_meta_value = empty($repeaterFiles_old[$index - 1]) ? [] : $repeaterFiles_old[$index - 1];
994 $updatedValue[$repeaterFldKey][$index - 1][$field_key] = wp_json_encode($old_meta_value);
995 }
996 $repeateFileDetails = [
997 'name' => $file_details['name'][$index],
998 'type' => $file_details['type'][$index],
999 'tmp_name' => $file_details['tmp_name'][$index],
1000 'error' => $file_details['error'][$index],
1001 'size' => $file_details['size'][$index],
1002 ];
1003 $meta_value = $fileHandler->moveUploadedFiles($repeateFileDetails, $formID, $entryID, $index);
1004 if (!empty($meta_value)) {
1005 $mergedMetaValueWithOld = isset($old_meta_value) ? array_merge($old_meta_value, (array) $meta_value) : (array) $meta_value;
1006 $updatedValue[$repeaterFldKey][$index - 1][$field_key] = wp_json_encode($mergedMetaValueWithOld);
1007 $_FILES[$field_key]['new_name'][$index - 1] = $mergedMetaValueWithOld;
1008 // $_FILES[$field_key]['file_path'][$index - 1] = $common_file_path . DIRECTORY_SEPARATOR . $meta_value;
1009 }
1010 }
1011 } else {
1012 // Handle non-repeater field files
1013 $meta_value = $fileHandler->moveUploadedFiles($_FILES[$field_key], $formID, $entryID);
1014 if (!empty($meta_value)) {
1015 $_FILES[$field_key]['new_name'] = $meta_value;
1016 if (isset($updatedValue[$field_key . '_old']) && !is_wp_error($file_exists) && count($file_exists) > 0) {
1017 $meta_value = empty($files_old) ? $meta_value : array_merge($meta_value, $files_old);
1018 $updatedValue[$field_key] = $meta_value;
1019 } else {
1020 $updatedValue[$field_key] = $meta_value;
1021 }
1022 }
1023 }
1024 }
1025 }
1026
1027 // Get the common file path to avoid repetitive calculation
1028 $this->addNewFilePathToFiles($formID, $entryID, $file_fields);
1029 }
1030
1031 if (is_object($updatedValue)) {
1032 $updatedValue = (array) $updatedValue;
1033 }
1034 if (isset($updatedValue['_ajax_nonce']) && $_REQUEST['g-recaptcha-response']) {
1035 unset($updatedValue['_ajax_nonce'], $_REQUEST['g-recaptcha-response']);
1036 }
1037
1038 $toUpdateValues = [];
1039 foreach ($form_fields as $field) {
1040 if (isset($updatedValue[$field['key']])) {
1041 $toUpdateValues[$field['key']] = $updatedValue[$field['key']];
1042 }
1043 }
1044 $form_content = \json_decode(static::$form[0]->form_content);
1045
1046 foreach ($form_content->fields as $key => $field) {
1047 if ('signature' === $field->typ) {
1048 $fld_data = $updatedValue[$key];
1049 $img_type = $field->config->imgTyp;
1050 $toUpdateValues[$key] = $this->getSignatureFilePath($fld_data, $this->form_id, $key, $entryID, $img_type);
1051 }
1052 }
1053
1054 $workFlowRunHelper = new WorkFlow($formID);
1055 $workFlowreturnedOnSubmit = $workFlowRunHelper->executeOnSubmit(
1056 'edit',
1057 $this->getFormContentWithValue($toUpdateValues)->fields,
1058 $toUpdateValues,
1059 $entryID,
1060 $log_id
1061 );
1062
1063 if (!empty($workFlowreturnedOnSubmit['fields'])) {
1064 $updatedValue = $workFlowreturnedOnSubmit['fields'];
1065 }
1066
1067 $formEntryMetaUpdateStatus = $entryMeta->update(
1068 $toUpdateValues,
1069 [
1070 'bitforms_form_entry_id' => $entryID,
1071 ]
1072 );
1073 if (is_wp_error($formEntryMetaUpdateStatus) || isset($newFileInsertStatus) && is_wp_error($newFileInsertStatus)) {
1074 do_action('bitform_update_entry_error', $this, $toUpdateValues, $formEntryMetaUpdateStatus, $this->form_id);
1075 return $formEntryMetaUpdateStatus;
1076 }
1077 $toUpdateValues = array_merge($formEntryMetaUpdateStatus, ['entry_id' => $entryID]);
1078 do_action('bitform_after_update_entry_success', $this, $toUpdateValues, $formID, $entryID);
1079 if (empty($workFlowreturnedOnSubmit['message'])) {
1080 $workFlowreturnedOnSubmit['message'] = __('Entry Updated Successfully', 'bit-form');
1081 }
1082 $customFieldHandler = new CustomFieldHandler();
1083 $toUpdateValues = $customFieldHandler->updatedData($form_fields, $toUpdateValues);
1084
1085 $workFlowreturnedOnSubmit['updatedData'] = $toUpdateValues;
1086 $counter = 0;
1087 for ($i = 0; $i < count($formOldData); $i++) {
1088 if (array_key_exists($formOldData[$i]->meta_key . '_old', $toUpdateValues)) {
1089 unset($toUpdateValues[$formOldData[$i]->meta_key . '_old']);
1090 }
1091 if (in_array($formOldData[$i]->meta_key, $file_fields)) {
1092 if (
1093 empty($_FILES[$formOldData[$i]->meta_key]['name'])
1094 || (is_array($_FILES[$formOldData[$i]->meta_key]['name'])
1095 && 1 === count($_FILES[$formOldData[$i]->meta_key]['name'])
1096 && empty($_FILES[$formOldData[$i]->meta_key]['name'][0]))
1097 ) {
1098 unset($toUpdateValues[$formOldData[$i]->meta_key]);
1099 continue;
1100 }
1101 if (is_array($_FILES[$formOldData[$i]->meta_key]['name']) && !in_array($_FILES[$formOldData[$i]->meta_key]['name'], json_decode($formOldData[$i]->meta_value))) {
1102 $key[$i] = '${' . $formOldData[$i]->meta_key . '} file was Updated To ' . wp_json_encode($_FILES[$formOldData[$i]->meta_key]['name']);
1103 } elseif (!is_array($_FILES[$formOldData[$i]->meta_key]['name']) && !in_array($_FILES[$formOldData[$i]->meta_key]['name'], json_decode($formOldData[$i]->meta_value))) {
1104 $key[$i] = '${' . $formOldData[$i]->meta_key . '} file was Updated To ' . $_FILES[$formOldData[$i]->meta_key]['name'];
1105 }
1106 unset($toUpdateValues[$formOldData[$i]->meta_key]);
1107 } elseif (isset($toUpdateValues[$formOldData[$i]->meta_key])) {
1108 if (is_array($toUpdateValues[$formOldData[$i]->meta_key])) {
1109 if (json_decode($formOldData[$i]->meta_value) !== $toUpdateValues[$formOldData[$i]->meta_key]) {
1110 $key[$i] = '${' . $formOldData[$i]->meta_key . '} was Updated From ' . implode(',', json_decode($formOldData[$i]->meta_value)) . ' To ' . implode(',', $toUpdateValues[$formOldData[$i]->meta_key]);
1111 }
1112 } elseif (is_string($toUpdateValues[$formOldData[$i]->meta_key]) && !FieldValueHandler::isEmpty($toUpdateValues[$formOldData[$i]->meta_key])) {
1113 if ($formOldData[$i]->meta_value !== $toUpdateValues[$formOldData[$i]->meta_key]) {
1114 $key[$i] = '${' . $formOldData[$i]->meta_key . '} was Updated' . ($formOldData[$i]->meta_value ? ' From ' . $formOldData[$i]->meta_value : '') . ' To ' . $toUpdateValues[$formOldData[$i]->meta_key];
1115 }
1116 }
1117 }
1118 $counter++;
1119 }
1120
1121 $newField = array_keys(array_diff_key($formEntryMetaUpdateStatus, $field_map));
1122 for ($i = 0; $i < count($newField); $i++) {
1123 if (is_array($toUpdateValues[$newField[$i]]) && !empty($toUpdateValues[$newField[$i]])) {
1124 $key[$counter + $i] = '${' . $newField[$i] . '} Updated To ' . implode(',', $toUpdateValues[$newField[$i]]);
1125 } elseif (is_string($newField[$i]) && !FieldValueHandler::isEmpty($toUpdateValues[$newField[$i]])) {
1126 $key[$counter + $i] = '${' . $newField[$i] . '} Updated To ' . $toUpdateValues[$newField[$i]];
1127 }
1128 }
1129 if (null !== $key) {
1130 $logUpdate = implode('b::f', (array) $key);
1131 $formEntryLogUpdate = $formEntryLogModel->logUpdate($logUpdate, $log_id);
1132 }
1133 $workFlowreturnedOnSubmit['entry_id'] = $entryID;
1134 $workFlowreturnedOnSubmit = apply_filters('bitform_filter_return_edit_success', $workFlowreturnedOnSubmit, $this->form_id);
1135
1136 return $workFlowreturnedOnSubmit;
1137 }
1138
1139 public function getRepeaterFields()
1140 {
1141 if (!is_null($this->_repeaterFields)) {
1142 return $this->_repeaterFields;
1143 }
1144 $repeaterFields = [];
1145 $form_content = \json_decode(static::$form[0]->form_content);
1146 $fields = $form_content->fields;
1147 $nestedLayouts = !empty($form_content->nestedLayout) ? $form_content->nestedLayout : [];
1148 foreach ($nestedLayouts as $fieldKey => $repeatLayout) {
1149 if ('repeater' !== $fields->{$fieldKey}->typ) {
1150 continue;
1151 }
1152 $repeaterFields[$fieldKey] = [];
1153 foreach ($repeatLayout->lg as $fieldLayoutData) {
1154 $repeaterFields[$fieldKey][] = $fieldLayoutData->i;
1155 }
1156 }
1157 $this->_repeaterFields = $repeaterFields;
1158 return $repeaterFields;
1159 }
1160
1161 public function isRepeatedField($fieldKey)
1162 {
1163 $repeatedFields = $this->getRepeaterFields();
1164 foreach ($repeatedFields as $repeaterKey => $repeaterFields) {
1165 if (in_array($fieldKey, $repeaterFields)) {
1166 return $repeaterKey;
1167 }
1168 }
1169 return false;
1170 }
1171
1172 public function getParentRepeaterField($fieldKey)
1173 {
1174 $repeatedFields = $this->getRepeaterFields();
1175 foreach ($repeatedFields as $repeaterKey => $repeaterFields) {
1176 if (in_array($fieldKey, $repeaterFields)) {
1177 return $repeaterKey;
1178 }
1179 }
1180 return null;
1181 }
1182
1183 public function isRepeaterField($fieldKey)
1184 {
1185 $repeatedFields = $this->getRepeaterFields();
1186 if (array_key_exists($fieldKey, $repeatedFields)) {
1187 return true;
1188 }
1189 return false;
1190 }
1191
1192 public function fieldNameReplaceOfPost()
1193 {
1194 $fields = $this->getFields();
1195 foreach ($fields as $fieldKey => $fieldData) {
1196 if (array_key_exists('name', $fieldData)) {
1197 $fldName = $fieldData['name'];
1198 $fldName = str_replace(['.', ' '], '_', $fldName);
1199 if (array_key_exists($fldName, $_POST)) {
1200 $temp = $_POST[$fldName];
1201 unset($_POST[$fldName]);
1202 $_POST[$fieldKey] = $temp;
1203 } elseif (array_key_exists($fldName, $_FILES)) {
1204 $temp = $_FILES[$fldName];
1205 unset($_FILES[$fldName]);
1206 $_FILES[$fieldKey] = $temp;
1207 }
1208 }
1209 }
1210 }
1211
1212 public function setSubmissionCount($countStep = 1)
1213 {
1214 $update_status = $this->formModel->update(
1215 [
1216 'entries' => intval(static::$form[0]->entries) + $countStep,
1217 ],
1218 [
1219 'id' => $this->form_id,
1220 ]
1221 );
1222 }
1223
1224 public function resetSubmissionCount($countStep)
1225 {
1226 $update_status = $this->formModel->update(
1227 [
1228 'entries' => intval($countStep),
1229 ],
1230 [
1231 'id' => $this->form_id,
1232 ]
1233 );
1234 }
1235
1236 public function getCaptchaSettings()
1237 {
1238 $formContents = $this->getFormContent();
1239 $fieldStr = wp_json_encode($formContents->fields);
1240 if (false !== strpos($fieldStr, '"typ":"recaptcha"')) {
1241 return true;
1242 }
1243 }
1244
1245 public function getTurnstileSettings()
1246 {
1247 $formContents = $this->getFormContent();
1248 $fieldStr = wp_json_encode($formContents->fields);
1249 if (false !== strpos($fieldStr, '"typ":"turnstile"')) {
1250 return true;
1251 }
1252 }
1253
1254 public function isFieldTypeExist($fieldType)
1255 {
1256 $formContents = $this->getFormContent();
1257 $fieldStr = wp_json_encode($formContents->fields);
1258 if (false !== strpos($fieldStr, '"typ":"' . $fieldType . '"')) {
1259 return true;
1260 }
1261 }
1262
1263 public function getCaptchaV3Settings()
1264 {
1265 $formContents = $this->getFormContent();
1266 if (!empty($formContents->additional->enabled) && !empty($formContents->additional->enabled->recaptchav3)) {
1267 return $formContents->additional->settings->recaptchav3;
1268 }
1269 return false;
1270 }
1271
1272 // public function getSuccessMessageMarkups() {
1273 // if (is_null($this->_work_flows)) {
1274 // $workFlowManager = new WorkFlowHandler($this->form_id);
1275 // $this->_work_flows = $workFlowManager->getAllworkFlow();
1276 // }
1277
1278 // $ids = [];
1279 // foreach ($this->_work_flows as $msgItem) {
1280 // foreach ($msgItem['conditions'] as $condition) {
1281 // if (isset($condition->actions->success)) {
1282 // foreach ($condition->actions->success as $msg) {
1283 // if ('successMsg' === $msg->type && isset($msg->details->id)) {
1284 // $msgDetailsId = $msg->details->id;
1285 // $idObj = json_decode(stripslashes($msgDetailsId));
1286 // if (is_object($idObj) && !empty($idObj->id)) {
1287 // array_push($ids, $idObj->id);
1288 // }
1289 // }
1290 // }
1291 // }
1292 // if (isset($condition->actions->failure)) {
1293 // $idObj = json_decode(stripslashes($condition->actions->failure));
1294 // if (is_object($idObj) && !empty($idObj->id)) {
1295 // array_push($ids, $idObj->id);
1296 // }
1297 // }
1298 // }
1299 // }
1300 // $ids = array_unique($ids);
1301 // if (is_null($this->_conf_messages)) {
1302 // $successMsgHandler = new SuccessMessageHandler($this->form_id);
1303 // $this->_conf_messages = $successMsgHandler->getMessages($ids);
1304 // }
1305
1306 // $messageMarkups = '';
1307 // if (is_wp_error($this->_conf_messages)) {
1308 // return $messageMarkups;
1309 // }
1310
1311 // foreach ($this->_conf_messages as $key => $msgItem) {
1312 // $messageMarkups .= $this->messageMarkup($msgItem->id);
1313 // }
1314
1315 // return $messageMarkups;
1316 // }
1317
1318 // private function messageMarkup($msgId) {
1319 // return <<<SUCCESSMSG
1320 // <div role="dialog" aria-hidden="true" data-modal-backdrop="true" class="{$this->getAtomicCls("msg-container-{$msgId}")} deactive2 test">
1321 // <div role="button" class="{$this->getAtomicCls("msg-background-{$msgId}")} msg-backdrop">
1322 // <div class="bf-notification-message {$this->getAtomicCls("msg-content-{$msgId}")}">
1323 // <button class="{$this->getAtomicCls("close-{$msgId}")} bf-msg-close" type="button">
1324 // <svg class="{$this->getAtomicCls("close-icn-{$msgId}")}" viewBox="0 0 30 30">
1325 // <line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" x1="4" y1="3.88" x2="26" y2="26.12"></line>
1326 // <line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" x1="26" y1="3.88" x2="4" y2="26.12"></line>
1327 // </svg>
1328 // </button>
1329 // <div class="msg-content"></div>
1330 // </div>
1331 // </div>
1332 // </div>
1333 // SUCCESSMSG;
1334 // }
1335
1336 public function getAtomicCls($element)
1337 {
1338 $atomicClassMap = $this->getAtomicClsMap();
1339 if (is_object($atomicClassMap) && property_exists($atomicClassMap, ".$element")) {
1340 $getAtomicCls = $atomicClassMap->{".$element"};
1341 return implode(' ', $getAtomicCls) . " $element";
1342 }
1343 return $element;
1344 }
1345
1346 public function isGCLIDEnabled()
1347 {
1348 $formContents = $this->getFormContent();
1349 if (isset($formContents->additional->enabled->captureGCLID) && $formContents->additional->enabled->captureGCLID) {
1350 return true;
1351 }
1352 return false;
1353 }
1354
1355 protected function addEntryInfo($field_details, $counter)
1356 {
1357 $infos = [
1358 '__user_id' => __('User'),
1359 '__entry_status' => __('Status'),
1360 //'__user_location' => __(''),
1361 '__referer' => __('Refer URL'),
1362 '__user_device' => __('Device'),
1363 '__user_ip' => __('IP address'),
1364 '__created_at' => __('Created Time'),
1365 '__updated_at' => __('Modified Time'),
1366 ];
1367 foreach ($infos as $key => $value) {
1368 $field_details[$counter]['name'] = $value;
1369 $field_details[$counter]['key'] = $key;
1370 $field_details[$counter]['type'] = 'sys';
1371 $counter = $counter + 1;
1372 }
1373
1374 return $field_details;
1375 }
1376 }
1377