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
bit-form / includes / Core / Form / FormManager.php

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

1,069 lines 37.2 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\Core\Database\FormEntryLogModel;
15 use BitCode\BitForm\Core\Database\FormEntryMetaModel;
16 use BitCode\BitForm\Core\Database\FormEntryModel;
17 use BitCode\BitForm\Core\Database\FormModel;
18 use BitCode\BitForm\Core\Integration\IntegrationHandler;
19 use BitCode\BitForm\Core\Messages\SuccessMessageHandler;
20 use BitCode\BitForm\Core\Util\FieldValueHandler;
21 use BitCode\BitForm\Core\Util\FileHandler;
22 use BitCode\BitForm\Core\Util\FrontendHelpers;
23 use BitCode\BitForm\Core\Util\IpTool;
24 use BitCode\BitForm\Core\WorkFlow\WorkFlow;
25 use BitCode\BitForm\Core\WorkFlow\WorkFlowHandler;
26 use WP_Error;
27
28 class FormManager
29 {
30 protected static $form;
31 protected $formModel;
32 protected $form_id;
33 private $_has_upload;
34 private $_field_label;
35 private $_fields;
36 private $_repeaterFields;
37 private $_work_flows;
38 private $_conf_messages;
39 private $_atomic_class_map;
40 private $_saveFormAsDraft;
41
42 public function __construct($form_id)
43 {
44 $this->form_id = $form_id;
45 $this->formModel = new FormModel();
46
47 static::$form = $this->formModel->get(
48 [
49 'id',
50 'form_content',
51 'form_name',
52 'created_at',
53 'views',
54 'entries',
55 'status',
56 'builder_helper_state',
57 'atomic_class_map',
58 'generated_script_page_ids',
59 ],
60 [
61 'id' => $form_id,
62 ]
63 );
64 if (!is_wp_error(static::$form)) {
65 $this->_atomic_class_map = json_decode(static::$form[0]->atomic_class_map);
66 $bfMultipleFormsExists = FrontendHelpers::hasMultipleForms();
67 if ($bfMultipleFormsExists && isset($this->_atomic_class_map->atomic_class_map_with_form_id)) {
68 $this->_atomic_class_map = $this->_atomic_class_map->atomic_class_map_with_form_id;
69 } elseif (isset($this->_atomic_class_map->atomic_class_map)) {
70 $this->_atomic_class_map = $this->_atomic_class_map->atomic_class_map;
71 }
72 }
73 }
74
75 public function isExist()
76 {
77 return (!static::$form || is_wp_error(static::$form)) ? false : true;
78 }
79
80 public function checkStatus()
81 {
82 return '1' === static::$form[0]->status ? true : false;
83 }
84
85 public function getFieldsContent()
86 {
87 return self::$form[0]->form_content;
88 }
89
90 public function getFont()
91 {
92 $atomicClassMap = $this->_atomic_class_map;
93 $font = isset($atomicClassMap->font) ? $atomicClassMap->font : '';
94 return $font;
95 }
96
97 public function getStyle()
98 {
99 $builerState = \json_decode(static::$form[0]->builder_helper_state);
100 $style = '';
101 $themeVars = $builerState->themeVars;
102 $themeColors = $builerState->themeColors;
103
104 if (!empty($themeVars)) {
105 $style .= ':root {';
106 foreach ($themeVars->lgLightThemeVars as $key => $value) {
107 $style .= "$key: $value; ";
108 }
109 $style .= '} ';
110 }
111 if (!empty($themeColors)) {
112 $style .= ' :root {';
113 foreach ($themeColors->lightThemeColors as $k => $v) {
114 $style .= "$k:$v; ";
115 }
116 $style .= '} ';
117 }
118
119 $field = $builerState->style->lgLightStyles->fields;
120 foreach ($field as $value) {
121 $classes = $value->classes;
122 foreach ($classes as $key => $value) {
123 $style .= "{$key} {";
124 foreach ($value as $k => $v) {
125 $style .= "$k:$v; ";
126 }
127 $style .= '} ';
128 }
129 }
130 return $style;
131 }
132
133 public function getCustomStyle()
134 {
135 $customCssCodes = '';
136 $customCSSPath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-styles' . DIRECTORY_SEPARATOR . "bitform-custom-{$this->form_id}.css";
137
138 if (file_exists($customCSSPath)) {
139 $file = fopen($customCSSPath, 'r');
140 $customCssCodes = fread($file, filesize($customCSSPath));
141 fclose($file);
142 }
143
144 return $customCssCodes;
145 }
146
147 public function getCustomJS()
148 {
149 $customJSCodes = '';
150 $customJsPath = BITFORMS_CONTENT_DIR . DIRECTORY_SEPARATOR . 'form-scripts' . DIRECTORY_SEPARATOR . "bitform-custom-{$this->form_id}.js";
151 if (file_exists($customJsPath)) {
152 $file = fopen($customJsPath, 'r');
153 $customJSCodes = fread($file, filesize($customJsPath));
154 fclose($file);
155 }
156
157 return $customJSCodes;
158 }
159
160 public function getFormContentWithValue($defaultValues)
161 {
162 $form_content = \json_decode(static::$form[0]->form_content);
163 if (!is_array($defaultValues) || 0 === count($defaultValues)) {
164 return $form_content;
165 }
166 foreach ($form_content->fields as $fieldKey => $fieldDetails) {
167 // $field_name = empty($fieldDetails->lbl) ? null : \preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\!]/', '_', $fieldDetails->lbl);
168 $fieldName = $fieldDetails->fieldName;
169 $defaultValue = isset($defaultValues[$fieldName]) ? $defaultValues[$fieldName] : null;
170 $defaultValue = isset($defaultValues[$fieldKey]) ? $defaultValues[$fieldKey] : $defaultValue;
171 if ((isset($fieldDetails->mul) || 'check' === $fieldDetails->typ) && isset($defaultValue)) {
172 // if (is_array($defaultValue)) {
173 // $fieldDetails->val =
174 // wp_json_encode(
175 // array_map('sanitize_text_field', $defaultValue)
176 // );
177 // } else {
178 // $fieldDetails->val = sanitize_text_field($defaultValue);
179 // }
180 if ((isset($fieldDetails->mul) && true === $fieldDetails->mul) || is_array($defaultValue)) {
181 $fieldDetails->val = wp_json_encode(array_map('sanitize_text_field', $defaultValue));
182 }
183 } elseif (isset($defaultValue)) {
184 $fieldDetails->val = is_string($defaultValue) ?
185 sanitize_text_field($defaultValue) :
186 sanitize_text_field($defaultValue[count($defaultValue) - 1]);
187 }
188 }
189 return $form_content;
190 }
191
192 public function getFormContent()
193 {
194 $formContent = json_decode(static::$form[0]->form_content);
195 $types = ['check', 'radio', 'select'];
196 $filter = false;
197 foreach ($formContent->fields as $field) {
198 if (in_array($field->typ, $types) && property_exists($field, 'customType')) {
199 $filter = true;
200 break; // reduce unnecessary loop
201 }
202 }
203 if (true === $filter) {
204 $updateFields = apply_filters('bitform_dynamic_field_filter', $formContent->fields);
205 $formContent->fields = $updateFields;
206 }
207 return $formContent;
208 }
209
210 public function getFormInfo()
211 {
212 $formContent = json_decode(static::$form[0]->form_content);
213 $formInfo = isset($formContent->formInfo) ? $formContent->formInfo : null;
214 return $formInfo;
215 }
216
217 public function getFormHelperStates()
218 {
219 $formHelperStates = json_decode(static::$form[0]->builder_helper_state);
220 return $formHelperStates;
221 }
222
223 public function getAtomicClsMap()
224 {
225 return $this->_atomic_class_map;
226 }
227
228 private function is_json($str)
229 {
230 $json = json_decode($str);
231 return $json && $str !== $json;
232 }
233
234 public function getFormData($columnName = '')
235 {
236 if (empty($columnName)) {
237 return null;
238 }
239
240 $form = static::$form[0];
241 if (!isset($form->{$columnName})) {
242 return null;
243 }
244
245 $data = $form->{$columnName};
246 if ($this->is_json($data)) {
247 return json_decode($data);
248 }
249
250 return $data;
251 }
252
253 public function getFormName()
254 {
255 return static::$form[0]->form_name;
256 }
257
258 public function getFields()
259 {
260 if (!is_null($this->_fields)) {
261 return $this->_fields;
262 }
263 $form_content = \json_decode(static::$form[0]->form_content);
264 $layout = $form_content->layout;
265 $fields = $form_content->fields;
266 $field_details = [];
267 foreach ($fields as $key => $field) {
268 if ('recaptcha' === $field->typ) {
269 continue;
270 }
271 // $field_name = empty($field->lbl) ? null : \preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\\!]/', '_', $field->lbl);
272 $field_type = $field->typ;
273 $field_details[$key]['label'] = empty($field->lbl) ? null : $field->lbl;
274 $field_details[$key]['type'] = $field_type;
275 $field_details[$key]['key'] = $key;
276 $field_details[$key]['name'] = isset($field->fieldName) ? $field->fieldName : '';
277 if (isset($field->customType)) {
278 $field_details[$key]['customType'] = $field->customType;
279 }
280
281 if (isset($field->err)) {
282 if (isset($field->err->entryUnique)) {
283 $field_details[$key]['entryUnique'] = $field->err->entryUnique;
284 }
285 if (isset($field->err->userUnique)) {
286 $field_details[$key]['userUnique'] = $field->err->userUnique;
287 }
288 }
289
290 if (isset($field->mul)) {
291 $field_details[$key]['mul'] = $field->mul;
292 }
293 if ('file-up' === $field_type && isset($field->exts)) {
294 $field_details[$key]['valid']['type'] = $field->exts;
295 }
296 if ('file-up' === $field_type && isset($field->mxUp)) {
297 $field_details[$key]['valid']['upload_size'] = (int) $field->mxUp;
298 }
299 if (isset($field->valid) && !is_null($field->valid)) {
300 if (isset($field->valid->req)) {
301 $field_details[$key]['valid']['req'] = $field->valid->req;
302 }
303 if (isset($field->valid->reqMsg)) {
304 $field_details[$key]['valid']['reqMsg'] = $field->valid->reqMsg;
305 }
306 if (isset($field->valid->typMsg)) {
307 $field_details[$key]['valid']['typMsg'] = $field->valid->typMsg;
308 }
309 }
310 if ($this->isRepeatedField($key)) {
311 $field_details[$key]['repeated'] = true;
312 }
313 }
314 if ($this->isGCLIDEnabled()) {
315 $field_details['GCLID']['name'] = 'GCLID';
316 $field_details['GCLID']['adminLbl'] = 'GCLID';
317 $field_details['GCLID']['key'] = 'GCLID';
318 $field_details['GCLID']['type'] = 'hidden';
319 }
320 $this->_fields = $field_details;
321 return $field_details;
322 }
323
324 public function getFieldsKey()
325 {
326 $form_content = \json_decode(static::$form[0]->form_content);
327 $fields = $form_content->fields;
328 $field_details = [];
329 foreach ($fields as $key => $field) {
330 if ('recaptcha' === $field->typ) {
331 continue;
332 }
333 // $field_name = empty($field->lbl) ? null : \preg_replace('/[\`\~\!\@\#\$\'\.\s\?\+\-\*\&\|\/\\\!]/', '_', $field->lbl);
334 $field_details[$key] = $key;
335 }
336 if ($this->isGCLIDEnabled()) {
337 $field_details['GCLID'] = 'GCLID';
338 }
339 return $field_details;
340 }
341
342 public function getFieldLabel($forQuery = false)
343 {
344 if (!is_null($this->_field_label)) {
345 return $this->_field_label;
346 }
347 $form_content = \json_decode(static::$form[0]->form_content);
348 $fields = $form_content->fields;
349 $field_details = [];
350 $fieldCounter = 0;
351 foreach ($fields as $key => $field) {
352 if ('recaptcha' === $field->typ || 'turnstile' === $field->typ || 'html' === $field->typ || 'button' === $field->typ) {
353 continue;
354 }
355 $field_details[$fieldCounter]['name'] = empty($field->lbl) ? null : $field->lbl;
356 $field_details[$fieldCounter]['adminLbl'] = empty($field->adminLbl) ? $field_details[$fieldCounter]['name'] : $field->adminLbl;
357 $field_details[$fieldCounter]['key'] = $key;
358 $field_details[$fieldCounter]['type'] = $field->typ;
359 $fieldCounter += 1;
360 }
361 if ($this->isGCLIDEnabled()) {
362 $field_details[$fieldCounter]['name'] = 'GCLID';
363 $field_details[$fieldCounter]['adminLbl'] = 'GCLID';
364 $field_details[$fieldCounter]['key'] = 'GCLID';
365 $field_details[$fieldCounter]['type'] = 'hidden';
366 $fieldCounter += 1;
367 }
368 if (!$forQuery) {
369 $field_details = (array) $this->addEntryInfo($field_details, $fieldCounter);
370 }
371 $this->_field_label = $field_details;
372 return $field_details;
373 }
374
375 public function getUploadFields()
376 {
377 if (!is_null($this->_has_upload)) {
378 return $this->_has_upload;
379 }
380 $upload_fields = [];
381 $form_field_details = $this->getFields();
382 foreach ($form_field_details as $field_name => $__field_detail) {
383 if (isset($__field_detail['type']) && ('file-up' === $__field_detail['type'] || 'advanced-file-up' === $__field_detail['type'])) {
384 $upload_fields[] = $field_name;
385 }
386 }
387 $this->_has_upload = $upload_fields;
388 return $upload_fields;
389 }
390
391 public function getSignatureFilePath($blobLink, $form_id, $entry_id, $imgType)
392 {
393 $imgTypes = [
394 'image/png' => 'png',
395 'image/jpeg' => 'jpg',
396 'image/svg+xml' => 'svg',
397 ];
398 $data_uri = $blobLink;
399 $encoded_image = explode(',', $data_uri)[1];
400 $decoded_image = base64_decode($encoded_image);
401 $_upload_dir = BITFORMS_UPLOAD_DIR . DIRECTORY_SEPARATOR . $form_id . DIRECTORY_SEPARATOR . $entry_id;
402
403 wp_mkdir_p($_upload_dir);
404
405 $filename = "{$entry_id}-" . time() . ".{$imgTypes[$imgType]}";
406 $fullPath = $_upload_dir . DIRECTORY_SEPARATOR . $filename;
407 file_put_contents($fullPath, $decoded_image);
408
409 return $filename;
410 }
411
412 private function entryInsert($user_details)
413 {
414 $formEntryModel = new FormEntryModel();
415 $entryId = $formEntryModel->insert(
416 [
417 'form_id' => $this->form_id,
418 'user_id' => $user_details['id'],
419 'user_ip' => $user_details['ip'],
420 'user_device' => $user_details['device'],
421 'referer' => $user_details['page'],
422 'status' => $this->_saveFormAsDraft ? 9 : 1,
423 'created_at' => $user_details['time'],
424 ]
425 );
426 return $entryId;
427 }
428
429 private function submisionLog($user_details, $entry_id, $type)
430 {
431 $formEntryLogModel = new FormEntryLogModel();
432 $logId = $formEntryLogModel->form_log_insert(
433 [
434 'user_id' => $user_details['id'],
435 'action_type' => $type,
436 'log_type' => 'entry',
437 'ip' => $user_details['ip'],
438 'form_entry_id' => $entry_id,
439 'content' => null,
440 'form_id' => $this->form_id,
441 'created_at' => $user_details['time'],
442 ]
443 );
444 return $logId;
445 }
446
447 private function isArrayAllKeyInt($InputArray)
448 {
449 if (!is_array($InputArray)) {
450 return false;
451 }
452
453 if (count($InputArray) <= 0) {
454 return true;
455 }
456
457 return array_unique(array_map('is_int', array_keys($InputArray))) === [true];
458 }
459
460 public function formatSubmittedData($submitted_data)
461 {
462 $form_content = $this->getFormContent();
463 $form_fields = $form_content->fields;
464
465 foreach ($submitted_data as $key => $value) {
466 if (!isset($form_fields->{$key})) {
467 continue;
468 }
469 $field_data = $form_fields->{$key};
470 $field_type = $field_data->typ;
471 if ('select' === $field_type && !empty($field_data->config->multipleSelect)) {
472 $valueArr = [];
473 if ($this->isRepeatedField($key)) {
474 foreach ($value as $index => $v) {
475 $valueArr[$index] = explode(BITFORMS_BF_SEPARATOR, $v);
476 }
477 } else {
478 $valueArr = explode(BITFORMS_BF_SEPARATOR, $value);
479 }
480 $submitted_data[$key] = $valueArr;
481 }
482 }
483 return $submitted_data;
484 }
485
486 private function formatRepeateFieldData($submitted_data, $form_fields)
487 {
488 $repeaterFields = $this->getRepeaterFields();
489 foreach ($repeaterFields as $repeaterFldKey => $repeatedFields) {
490 $repeatIndexes = $submitted_data["{$form_fields[$repeaterFldKey]['name']}-repeat-index"];
491 $repeatIndexes = explode(',', $repeatIndexes);
492 foreach ($repeatIndexes as $slNo => $repeatIndex) {
493 foreach ($repeatedFields as $repeatedField) {
494 if (!isset($submitted_data[$repeaterFldKey][$slNo])) {
495 $submitted_data[$repeaterFldKey][$slNo] = [];
496 }
497 $submitted_data[$repeaterFldKey][$slNo][$repeatedField] = $submitted_data[$repeatedField][$repeatIndex];
498 }
499 }
500 foreach ($repeatedFields as $repeatedField) {
501 unset($submitted_data[$repeatedField]);
502 }
503 unset($submitted_data["{$form_fields[$repeaterFldKey]['name']}-repeat-index"]);
504 }
505
506 return $submitted_data;
507 }
508
509 private function saveEntryMeta($submitted_data, $entry_id)
510 {
511 $errorInEntryMetaInsert = false;
512 $entryMeta = new FormEntryMetaModel();
513 foreach ($submitted_data as $key => $value) {
514 $value = $submitted_data[$key];
515 if (is_string($value)) {
516 $value = wp_unslash($value);
517 } elseif ($this->isArrayAllKeyInt($value)) {
518 $value = wp_json_encode(array_values($value));
519 } else {
520 $value = wp_json_encode($value);
521 }
522 $status = $entryMeta->insert(
523 [
524 'bitforms_form_entry_id' => $entry_id,
525 'meta_key' => $key,
526 'meta_value' => $value,
527 ]
528 );
529 if (is_wp_error($status)) {
530 $errorInEntryMetaInsert = true;
531 break;
532 }
533 }
534 return $errorInEntryMetaInsert;
535 }
536
537 public function setSaveFormAsDraft()
538 {
539 $this->_saveFormAsDraft = true;
540 }
541
542 public function saveFormEntry($submitted_data)
543 {
544 $submitted_data = $this->formatSubmittedData($submitted_data);
545 $form_content = \json_decode(static::$form[0]->form_content);
546 do_action('bitform_save_entry', $this, $submitted_data);
547 $key = null;
548 $ipTool = new IpTool();
549 $fileHandler = new FileHandler();
550 $form_fields = $this->getFields();
551 $file_fields = $this->getUploadFields();
552
553 foreach ($_FILES as $file_name => $file_details) {
554 if ($file_fields && in_array($file_name, $file_fields)) {
555 $validation = $fileHandler->validation($file_name, $file_details, $this->form_id);
556 if (!empty($validation['error_type']) && !empty($validation['message'])) {
557 return new WP_Error($validation['error_type'], __($validation['message'], 'bit-form'));
558 }
559 }
560 }
561 $user_details = $ipTool->getUserDetail();
562 $form_fields = $this->getFields();
563 $submitted_data = $this->passwordEncrypted($submitted_data, $form_fields);
564 $submitted_data = $this->formatRepeateFieldData($submitted_data, $form_fields);
565 global $wpdb;
566 $wpdb->query('START TRANSACTION');
567 $entry_id = $this->entryInsert($user_details);
568 $log_id = null;
569 if (is_wp_error($entry_id)) {
570 return new WP_Error('insert_error', __('Sorry, Error occurred in saving form entry', 'bit-form'));
571 }
572 if ($entry_id) {
573 $log_id = $this->submisionLog($user_details, $entry_id, 'create', $key);
574 if (is_wp_error($log_id)) {
575 $wpdb->query('ROLLBACK');
576 return new WP_Error('error_entry_log', __('Sorry, error occurred in logging form entry', 'bit-form'));
577 }
578 }
579 if ($entry_id) {
580 $submitted_fields = $this->getFormContentWithValue($submitted_data)->fields;
581 $workFlowRunHelper = new WorkFlow($this->form_id);
582 $workFlowreturnedOnSubmit = $workFlowRunHelper->executeOnSubmit(
583 'create',
584 $submitted_fields,
585 $submitted_data,
586 $entry_id,
587 $log_id
588 );
589 if (!empty($workFlowreturnedOnSubmit['fields'])) {
590 $submitted_data = $workFlowreturnedOnSubmit['fields'];
591 }
592
593 $file_fields = $this->getUploadFields();
594 $formFields = $this->getFields();
595 $submitted_data = FileHandler::tempDirToUploadDir($submitted_data, $formFields, $this->form_id, $entry_id);
596 $fileHandler = new FileHandler();
597 foreach ($_FILES as $file_name => $file_details) {
598 if ($file_fields && in_array($file_name, $file_fields)) {
599 $filePath = [];
600 $repeaterFldKey = $this->isRepeatedField($file_name);
601 if ($repeaterFldKey) {
602 foreach ($file_details['name'] as $slNo => $fileName) {
603 $repeateFileDetails = [
604 'name' => $file_details['name'][$slNo],
605 'type' => $file_details['type'][$slNo],
606 'tmp_name' => $file_details['tmp_name'][$slNo],
607 'error' => $file_details['error'][$slNo],
608 'size' => $file_details['size'][$slNo],
609 ];
610 $filePath = $fileHandler->moveUploadedFiles($repeateFileDetails, $this->form_id, $entry_id);
611 if (!empty($filePath)) {
612 $submitted_data[$repeaterFldKey][$slNo - 1][$file_name] = $filePath;
613 }
614 }
615 } else {
616 $filePath = $fileHandler->moveUploadedFiles($file_details, $this->form_id, $entry_id);
617 if (!empty($filePath)) {
618 $submitted_data[$file_name] = $filePath;
619 }
620 }
621 }
622 }
623
624 /* ======== for Signature field ===========*/
625 foreach ($form_content->fields as $key => $field) {
626 if ('signature' === $field->typ) {
627 $fld_data = $submitted_data[$key];
628 $img_type = $field->config->imgTyp;
629 $submitted_data[$key] = $this->getSignatureFilePath($fld_data, $this->form_id, $entry_id, $img_type);
630 break;
631 }
632 }
633
634 if (!isset($form_content->additional->enabled->submission)) {
635 $errorInEntryMetaInsert = $this->saveEntryMeta($submitted_data, $entry_id);
636 if ($errorInEntryMetaInsert) {
637 $wpdb->query('ROLLBACK');
638 return new WP_Error('insert_error', __('Sorry, Error occured in saving form entry data', 'bit-form'));
639 }
640 }
641 $wpdb->query('COMMIT');
642 $this->setSubmissionCount();
643 $workFlowreturnedOnSubmit['entry_id'] = $entry_id;
644 $workFlowreturnedOnSubmit['fields'] = $submitted_data;
645
646 return $workFlowreturnedOnSubmit;
647 }
648 }
649
650 public function passwordEncrypted($updatedValue, $form_fields)
651 {
652 $integrationHandler = new IntegrationHandler($this->form_id);
653 $formIntegrations = $integrationHandler->getAllIntegration('wp_user_auth', 'wp_auth', 1);
654 if (!isset($formIntegrations->errors['result_empty'])) {
655 foreach ($form_fields as $field) {
656 if (array_key_exists($field['key'], $updatedValue) && 'password' === $field['type']) {
657 $updatedValue[$field['key']] = '**** (encrypted)';
658 }
659 }
660 }
661 return $updatedValue;
662 }
663
664 public function updateFormEntry($updatedValue, $formID, $entryID)
665 {
666 $updatedValue = $this->formatSubmittedData($updatedValue);
667 $formEntryModel = new FormEntryModel();
668 $formEntryLogModel = new FormEntryLogModel();
669 $formOldData = $formEntryLogModel->get_form_value($entryID);
670 $key = null;
671 $entryMeta = new FormEntryMetaModel();
672 $ipTool = new IpTool();
673 $user_details = $ipTool->getUserDetail();
674 $form_fields = $this->getFields();
675
676 $updatedValue = $this->passwordEncrypted($updatedValue, $form_fields);
677 $updatedValue = $this->formatRepeateFieldData($updatedValue, $form_fields);
678 $field_map = [];
679 foreach ($formOldData as $index => $data) {
680 foreach ($form_fields as $field_key => $field) {
681 if ($data->meta_key === $field['key']) {
682 $field_map[$field_key] = $field['key'];
683 }
684 }
685 }
686 $oldEntry = $formEntryModel->get('status', ['id' => $entryID])[0];
687 $formEntry = $formEntryModel->update(
688 [
689 'user_id' => $user_details['id'],
690 'user_ip' => $user_details['ip'],
691 'user_device' => $user_details['device'],
692 'status' => ('9' === $oldEntry->status && !$this->_saveFormAsDraft) ? 1 : $oldEntry->status,
693 'updated_at' => $user_details['time'],
694 ],
695 [
696 'form_id' => $formID,
697 'id' => $entryID,
698 ]
699 );
700 $log_id = null;
701 if ($formEntry) {
702 $log_id = $this->submisionLog($user_details, $entryID, 'update');
703 }
704
705 if (is_wp_error($formEntry) || !$formEntry) {
706 return new WP_Error('empty_form', __('provided form entries does not exists', 'bit-form'));
707 }
708
709 $file_fields = $this->getUploadFields();
710 if (count($file_fields) > 0) {
711 $fileHandler = new FileHandler();
712 foreach ($file_fields as $field_name) {
713 if (isset($updatedValue[$field_name . '_old'])) {
714 $file_exists = $entryMeta->get(
715 'meta_value',
716 [
717 'bitforms_form_entry_id' => $entryID,
718 'meta_key' => $field_name,
719 ]
720 );
721 if (!is_wp_error($file_exists) && count($file_exists) > 0) {
722 $files_in_db = json_decode($file_exists[0]->meta_value);
723 $files_old = empty($updatedValue[$field_name . '_old']) ? [] : explode(',', $updatedValue[$field_name . '_old']);
724 $deleted_file = array_diff($files_in_db, $files_old);
725 if (count($deleted_file) > 0) {
726 $fileHandler->deleteFiles($formID, $entryID, $deleted_file);
727 }
728 $updatedValue[$field_name] = wp_json_encode($files_old);
729 }
730 }
731 if (!empty($_FILES[$field_name]['name'])) {
732 $repeaterFldKey = $this->isRepeatedField($field_name);
733 if ($repeaterFldKey) {
734 $file_details = $_FILES[$field_name];
735 foreach ($file_details['name'] as $index => $file) {
736 $repeateFileDetails = [
737 'name' => $file_details['name'][$index],
738 'type' => $file_details['type'][$index],
739 'tmp_name' => $file_details['tmp_name'][$index],
740 'error' => $file_details['error'][$index],
741 'size' => $file_details['size'][$index],
742 ];
743 $meta_value = $fileHandler->moveUploadedFiles($repeateFileDetails, $formID, $entryID, $index);
744 if (!empty($meta_value)) {
745 $updatedValue[$repeaterFldKey][$index - 1][$field_name] = wp_json_encode($meta_value);
746 }
747 }
748 } else {
749 $meta_value = $fileHandler->moveUploadedFiles($_FILES[$field_name], $formID, $entryID);
750 if (!empty($meta_value)) {
751 if (isset($updatedValue[$field_name . '_old']) && !is_wp_error($file_exists) && count($file_exists) > 0) {
752 $meta_value = empty($files_old) ? $meta_value : array_merge($meta_value, $files_old);
753 $updatedValue[$field_name] = wp_json_encode($meta_value);
754 } else {
755 $updatedValue[$field_name] = wp_json_encode($meta_value);
756 }
757 }
758 }
759 }
760 }
761 }
762
763 unset($updatedValue['_ajax_nonce'], $_REQUEST['g-recaptcha-response']);
764
765 $workFlowRunHelper = new WorkFlow($formID);
766 $workFlowreturnedOnSubmit = $workFlowRunHelper->executeOnSubmit(
767 'edit',
768 $this->getFormContentWithValue($updatedValue)->fields,
769 $updatedValue,
770 $entryID,
771 $log_id
772 );
773 if (!empty($workFlowreturnedOnSubmit['fields'])) {
774 $updatedValue = $workFlowreturnedOnSubmit['fields'];
775 }
776
777 $toUpdateValues = [];
778 foreach ($form_fields as $field) {
779 if (isset($updatedValue[$field['key']])) {
780 $toUpdateValues[$field['key']] = $updatedValue[$field['key']];
781 }
782 }
783 $form_content = \json_decode(static::$form[0]->form_content);
784
785 foreach ($form_content->fields as $key => $field) {
786 if ('signature' === $field->typ) {
787 $fld_data = $updatedValue[$key];
788 $img_type = $field->config->imgTyp;
789 $toUpdateValues[$key] = $this->getSignatureFilePath($fld_data, $this->form_id, $entryID, $img_type);
790 break;
791 }
792 }
793
794 $formEntryMetaUpdateStatus = $entryMeta->update(
795 $toUpdateValues,
796 [
797 'bitforms_form_entry_id' => $entryID,
798 ]
799 );
800 if (is_wp_error($formEntryMetaUpdateStatus) || isset($newFileInsertStatus) && is_wp_error($newFileInsertStatus)) {
801 return $formEntryMetaUpdateStatus;
802 }
803 $toUpdateValues = array_merge($formEntryMetaUpdateStatus, ['entry_id' => $entryID]);
804 if (empty($workFlowreturnedOnSubmit['message'])) {
805 $workFlowreturnedOnSubmit['message'] = __('Entry Updated Successfully', 'bit-form');
806 }
807 $customFieldHandler = new CustomFieldHandler();
808 $toUpdateValues = $customFieldHandler->updatedData($form_fields, $toUpdateValues);
809
810 $workFlowreturnedOnSubmit['updatedData'] = $toUpdateValues;
811 $counter = 0;
812 for ($i = 0; $i < count($formOldData); $i++) {
813 if (array_key_exists($formOldData[$i]->meta_key . '_old', $toUpdateValues)) {
814 unset($toUpdateValues[$formOldData[$i]->meta_key . '_old']);
815 }
816 if (in_array($formOldData[$i]->meta_key, $file_fields)) {
817 if (
818 empty($_FILES[$formOldData[$i]->meta_key]['name'])
819 || (is_array($_FILES[$formOldData[$i]->meta_key]['name'])
820 && 1 === count($_FILES[$formOldData[$i]->meta_key]['name'])
821 && empty($_FILES[$formOldData[$i]->meta_key]['name'][0]))
822 ) {
823 unset($toUpdateValues[$formOldData[$i]->meta_key]);
824 continue;
825 }
826 if (is_array($_FILES[$formOldData[$i]->meta_key]['name']) && !in_array($_FILES[$formOldData[$i]->meta_key]['name'], json_decode($formOldData[$i]->meta_value))) {
827 $key[$i] = '${' . $formOldData[$i]->meta_key . '} file was Updated To ' . json_encode($_FILES[$formOldData[$i]->meta_key]['name']);
828 } elseif (!is_array($_FILES[$formOldData[$i]->meta_key]['name']) && !in_array($_FILES[$formOldData[$i]->meta_key]['name'], json_decode($formOldData[$i]->meta_value))) {
829 $key[$i] = '${' . $formOldData[$i]->meta_key . '} file was Updated To ' . $_FILES[$formOldData[$i]->meta_key]['name'];
830 }
831 unset($toUpdateValues[$formOldData[$i]->meta_key]);
832 } elseif (isset($toUpdateValues[$formOldData[$i]->meta_key])) {
833 if (is_array($toUpdateValues[$formOldData[$i]->meta_key])) {
834 if (json_decode($formOldData[$i]->meta_value) !== $toUpdateValues[$formOldData[$i]->meta_key]) {
835 $key[$i] = '${' . $formOldData[$i]->meta_key . '} was Updated From ' . implode(',', json_decode($formOldData[$i]->meta_value)) . ' To ' . implode(',', $toUpdateValues[$formOldData[$i]->meta_key]);
836 }
837 } elseif (is_string($toUpdateValues[$formOldData[$i]->meta_key]) && !FieldValueHandler::isEmpty($toUpdateValues[$formOldData[$i]->meta_key])) {
838 if ($formOldData[$i]->meta_value !== $toUpdateValues[$formOldData[$i]->meta_key]) {
839 $key[$i] = '${' . $formOldData[$i]->meta_key . '} was Updated' . ($formOldData[$i]->meta_value ? ' From ' . $formOldData[$i]->meta_value : '') . ' To ' . $toUpdateValues[$formOldData[$i]->meta_key];
840 }
841 }
842 }
843 $counter++;
844 }
845
846 $newField = array_keys(array_diff_key($formEntryMetaUpdateStatus, $field_map));
847 for ($i = 0; $i < count($newField); $i++) {
848 if (is_array($toUpdateValues[$newField[$i]]) && !empty($toUpdateValues[$newField[$i]])) {
849 $key[$counter + $i] = '${' . $newField[$i] . '} Updated To ' . implode(',', $toUpdateValues[$newField[$i]]);
850 } elseif (is_string($newField[$i]) && !FieldValueHandler::isEmpty($toUpdateValues[$newField[$i]])) {
851 $key[$counter + $i] = '${' . $newField[$i] . '} Updated To ' . $toUpdateValues[$newField[$i]];
852 }
853 }
854 if (null !== $key) {
855 $logUpdate = implode('b::f', (array) $key);
856 $formEntryLogUpdate = $formEntryLogModel->logUpdate($logUpdate, $log_id);
857 }
858 $workFlowreturnedOnSubmit['entry_id'] = $entryID;
859 return $workFlowreturnedOnSubmit;
860 }
861
862 public function getRepeaterFields()
863 {
864 if (!is_null($this->_repeaterFields)) {
865 return $this->_repeaterFields;
866 }
867 $repeaterFields = [];
868 $form_content = \json_decode(static::$form[0]->form_content);
869 $fields = $form_content->fields;
870 $nestedLayouts = !empty($form_content->nestedLayout) ? $form_content->nestedLayout : [];
871 foreach ($nestedLayouts as $fieldKey => $repeatLayout) {
872 if ('repeater' !== $fields->{$fieldKey}->typ) {
873 continue;
874 }
875 $repeaterFields[$fieldKey] = [];
876 foreach ($repeatLayout->lg as $fieldLayoutData) {
877 $repeaterFields[$fieldKey][] = $fieldLayoutData->i;
878 }
879 }
880 $this->_repeaterFields = $repeaterFields;
881 return $repeaterFields;
882 }
883
884 public function isRepeatedField($fieldKey)
885 {
886 $repeatedFields = $this->getRepeaterFields();
887 foreach ($repeatedFields as $repeaterKey => $repeaterFields) {
888 if (in_array($fieldKey, $repeaterFields)) {
889 return $repeaterKey;
890 }
891 }
892 return false;
893 }
894
895 public function fieldNameReplaceOfPost()
896 {
897 $fields = $this->getFields();
898 foreach ($fields as $fieldKey => $fieldData) {
899 if (array_key_exists('name', $fieldData)) {
900 $fldName = $fieldData['name'];
901 $fldName = str_replace(['.', ' '], '_', $fldName);
902 if (array_key_exists($fldName, $_POST)) {
903 $temp = $_POST[$fldName];
904 unset($_POST[$fldName]);
905 $_POST[$fieldKey] = $temp;
906 } elseif (array_key_exists($fldName, $_FILES)) {
907 $temp = $_FILES[$fldName];
908 unset($_FILES[$fldName]);
909 $_FILES[$fieldKey] = $temp;
910 }
911 }
912 }
913 }
914
915 public function setSubmissionCount($countStep = 1)
916 {
917 $update_status = $this->formModel->update(
918 [
919 'entries' => intval(static::$form[0]->entries) + $countStep,
920 ],
921 [
922 'id' => $this->form_id,
923 ]
924 );
925 }
926
927 public function resetSubmissionCount($countStep)
928 {
929 $update_status = $this->formModel->update(
930 [
931 'entries' => intval($countStep),
932 ],
933 [
934 'id' => $this->form_id,
935 ]
936 );
937 }
938
939 public function getCaptchaSettings()
940 {
941 $formContents = $this->getFormContent();
942 $fieldStr = wp_json_encode($formContents->fields);
943 if (false !== strpos($fieldStr, '"typ":"recaptcha"')) {
944 return true;
945 }
946 }
947 public function getTurnstileSettings()
948 {
949 $formContents = $this->getFormContent();
950 $fieldStr = wp_json_encode($formContents->fields);
951 if (false !== strpos($fieldStr, '"typ":"turnstile"')) {
952 return true;
953 }
954 }
955
956 public function getCaptchaV3Settings()
957 {
958 $formContents = $this->getFormContent();
959 if (!empty($formContents->additional->enabled) && !empty($formContents->additional->enabled->recaptchav3)) {
960 return $formContents->additional->settings->recaptchav3;
961 }
962 return false;
963 }
964
965 // public function getSuccessMessageMarkups() {
966 // if (is_null($this->_work_flows)) {
967 // $workFlowManager = new WorkFlowHandler($this->form_id);
968 // $this->_work_flows = $workFlowManager->getAllworkFlow();
969 // }
970
971 // $ids = [];
972 // foreach ($this->_work_flows as $msgItem) {
973 // foreach ($msgItem['conditions'] as $condition) {
974 // if (isset($condition->actions->success)) {
975 // foreach ($condition->actions->success as $msg) {
976 // if ('successMsg' === $msg->type && isset($msg->details->id)) {
977 // $msgDetailsId = $msg->details->id;
978 // $idObj = json_decode(stripslashes($msgDetailsId));
979 // if (is_object($idObj) && !empty($idObj->id)) {
980 // array_push($ids, $idObj->id);
981 // }
982 // }
983 // }
984 // }
985 // if (isset($condition->actions->failure)) {
986 // $idObj = json_decode(stripslashes($condition->actions->failure));
987 // if (is_object($idObj) && !empty($idObj->id)) {
988 // array_push($ids, $idObj->id);
989 // }
990 // }
991 // }
992 // }
993 // $ids = array_unique($ids);
994 // if (is_null($this->_conf_messages)) {
995 // $successMsgHandler = new SuccessMessageHandler($this->form_id);
996 // $this->_conf_messages = $successMsgHandler->getMessages($ids);
997 // }
998
999 // $messageMarkups = '';
1000 // if (is_wp_error($this->_conf_messages)) {
1001 // return $messageMarkups;
1002 // }
1003
1004 // foreach ($this->_conf_messages as $key => $msgItem) {
1005 // $messageMarkups .= $this->messageMarkup($msgItem->id);
1006 // }
1007
1008 // return $messageMarkups;
1009 // }
1010
1011 // private function messageMarkup($msgId) {
1012 // return <<<SUCCESSMSG
1013 // <div role="dialog" aria-hidden="true" data-modal-backdrop="true" class="{$this->getAtomicCls("msg-container-{$msgId}")} deactive2 test">
1014 // <div role="button" class="{$this->getAtomicCls("msg-background-{$msgId}")} msg-backdrop">
1015 // <div class="bf-notification-message {$this->getAtomicCls("msg-content-{$msgId}")}">
1016 // <button class="{$this->getAtomicCls("close-{$msgId}")} bf-msg-close" type="button">
1017 // <svg class="{$this->getAtomicCls("close-icn-{$msgId}")}" viewBox="0 0 30 30">
1018 // <line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" x1="4" y1="3.88" x2="26" y2="26.12"></line>
1019 // <line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" x1="26" y1="3.88" x2="4" y2="26.12"></line>
1020 // </svg>
1021 // </button>
1022 // <div class="msg-content"></div>
1023 // </div>
1024 // </div>
1025 // </div>
1026 // SUCCESSMSG;
1027 // }
1028
1029 public function getAtomicCls($element)
1030 {
1031 $atomicClassMap = $this->getAtomicClsMap();
1032 if (property_exists($atomicClassMap, ".$element")) {
1033 $getAtomicCls = $atomicClassMap->{".$element"};
1034 return implode(' ', $getAtomicCls) . " $element";
1035 }
1036 return $element;
1037 }
1038
1039 public function isGCLIDEnabled()
1040 {
1041 $formContents = $this->getFormContent();
1042 if (isset($formContents->additional->enabled->captureGCLID) && $formContents->additional->enabled->captureGCLID) {
1043 return true;
1044 }
1045 return false;
1046 }
1047
1048 protected function addEntryInfo($field_details, $counter)
1049 {
1050 $infos = [
1051 '__user_id' => __('User'),
1052 '__entry_status' => __('Status'),
1053 //'__user_location' => __(''),
1054 '__referer' => __('Refer URL'),
1055 '__user_device' => __('Device'),
1056 '__user_ip' => __('IP address'),
1057 '__created_at' => __('Created Time'),
1058 '__updated_at' => __('Modified Time'),
1059 ];
1060 foreach ($infos as $key => $value) {
1061 $field_details[$counter]['name'] = $value;
1062 $field_details[$counter]['key'] = $key;
1063 $field_details[$counter]['type'] = 'sys';
1064 $counter = $counter + 1;
1065 }
1066
1067 return $field_details;
1068 }
1069 }