PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.16.2
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.16.2
3.3.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 All 138 releases
← All changes | includes/Frontend/Form/FrontendFormManager.php +414 -226 2.02.16.2 View file →
@@ -22,11 +22,13 @@
22 22 use BitCode\BitForm\Core\Util\IpTool;
23 23 use BitCode\BitForm\Core\WorkFlow\WorkFlow;
24 24 use BitCode\BitForm\Core\WorkFlow\WorkFlowHandler;
25 25 use BitCode\BitForm\Frontend\Form\View\FormViewer;
26 +use BitCode\BitFormPro\Admin\FormSettings\FormAbandonment;
26 27 use WP_Error;
27 28
28 -final class FrontendFormManager extends FormManager {
29 +final class FrontendFormManager extends FormManager
30 +{
29 31 private $_form_identifier;
30 32 private $_form_token;
31 33 private $_form_id;
32 34 private $_work_flows;
@@ -32,9 +34,10 @@
32 34 private $_work_flows;
33 35 private $_conf_messages;
34 36
35 37 // private $_has_upload = false;
36 - public function __construct($form_id, $shortCodeCounter = null) {
38 + public function __construct($form_id, $shortCodeCounter = null)
39 + {
37 40 parent::__construct($form_id);
38 41 $this->_form_identifier = 'bitforms_' . $form_id;
39 42 $this->_form_identifier .= !empty(get_post()->ID) ? '_' . get_post()->ID : '';
40 43 $this->_form_identifier .= !empty($shortCodeCounter) ? "_$shortCodeCounter" : '';
@@ -41,32 +44,38 @@
41 44 $this->_form_token = wp_create_nonce('bitforms_' . $form_id);
42 45 $this->_form_id = $form_id;
43 46 }
44 47
45 - public function getFormIdentifier() {
48 + public function getFormIdentifier()
49 + {
46 50 return $this->_form_identifier;
47 51 }
48 52
49 - public function getFormID() {
53 + public function getFormID()
54 + {
50 55 return $this->_form_id;
51 56 }
52 57
53 - public function getFormToken() {
58 + public function getFormToken()
59 + {
54 60 return $this->_form_token;
55 61 }
56 62
57 - public function isSubmitted() {
63 + public function isSubmitted()
64 + {
58 65 // return isset($_POST[$this->_form_identifier]) ? true : false;
59 66 return (isset($_POST['bitforms_id']) && $_POST['bitforms_id'] === $this->_form_identifier) ? true : false;
60 67 }
61 68
62 - public function getSubmittedFields($submitted_data) {
69 + public function getSubmittedFields($submitted_data)
70 + {
63 71 unset($submitted_data[$this->_form_identifier]);
64 72 // unset($submitted_data['bit-form-submit-btn']);
65 73 return array_keys($submitted_data);
66 74 }
67 75
68 - public function formView($fields = null, $hasFile = false, $errorMessages = null, $previousValue = null) {
76 + public function formView($fields = null, $hasFile = false, $errorMessages = null, $previousValue = null)
77 + {
69 78 $formContents = $this->getFormContent();
70 79 $formAtomicClsMap = $this->getAtomicClsMap();
71 80 if (!empty($fields)) {
72 81 $formContents->fields = is_string($fields) ? json_decode($fields) : $fields;
@@ -78,24 +87,61 @@
78 87 );
79 88 $formContents->fields = empty($workFlowreturnedOnLoad['fields']) ? $formContents->fields : $workFlowreturnedOnLoad['fields'];
80 89 }
81 90 $formViewer = new FormViewer($this, $formContents, $formAtomicClsMap, $errorMessages, $previousValue);
82 - return $formViewer->getView($hasFile);
91 + $isRestricted = $this->checkSubmissionRestriction(false);
92 + $msg = !empty($isRestricted) ? $isRestricted[0] : '';
93 + return $formViewer->getView($hasFile, $msg);
83 94 }
84 95
85 - private function checkEmptySubmission($data, $file) {
96 + public function conversationalFormView($fields = null, $hasFile = false, $errorMessages = null, $previousValue = null)
97 + {
98 + $formContents = $this->getFormContent();
99 + $formAtomicClsMap = $this->getAtomicClsMap();
100 + if (!empty($fields)) {
101 + $formContents->fields = is_string($fields) ? json_decode($fields) : $fields;
102 + } else {
103 + $workFlowRunHelper = new WorkFlow($this->form_id);
104 + $workFlowreturnedOnLoad = $workFlowRunHelper->executeOnLoad(
105 + 'create',
106 + $formContents->fields
107 + );
108 + $formContents->fields = empty($workFlowreturnedOnLoad['fields']) ? $formContents->fields : $workFlowreturnedOnLoad['fields'];
109 + }
110 + $formViewer = new FormViewer($this, $formContents, $formAtomicClsMap, $errorMessages, $previousValue);
111 + $isRestricted = $this->checkSubmissionRestriction(false);
112 + $msg = !empty($isRestricted) ? $isRestricted[0] : '';
113 + return $formViewer->getConversationalView($hasFile, $msg);
114 + }
115 +
116 + public function checkEmptySubmission($data, $file)
117 + {
86 118 $formFields = $this->getFields();
87 119 foreach ($formFields as $key => $field) {
88 120 $fieldType = $field['type'];
121 + if ('button' === $fieldType) {
122 + continue;
123 + }
89 124 $fileUploadFieldTypes = ['file-up', 'advanced-file-up'];
125 + if ('decision-box' === $fieldType || 'gdpr' === $fieldType) {
126 + continue;
127 + }
90 128 $isFileType = in_array($fieldType, $fileUploadFieldTypes);
91 - if (!$isFileType && !empty($data[$key])) {
129 + if ($this->isRepeatedField($key)) {
130 + $fileData = !empty($file[$key]) ? $file[$key] : [];
131 + $dataVal = !empty($data[$key]) ? $data[$key] : [];
132 + if (!$this->checkRepeatedFieldEmptySubmission($isFileType, $dataVal, $fileData)) {
133 + return false;
134 + }
135 + continue;
136 + }
137 + if (!$isFileType && (!empty($data[$key]) || (isset($data[$key]) && is_numeric($data[$key])))) {
92 138 return false;
93 139 }
94 140 if ($isFileType && !empty($file[$key]['name']) && is_string($file[$key]['name'])) {
95 141 return false;
96 142 }
97 - if ($isFileType && is_array($file[$key]['name']) && !empty($file[$key]['name'][0])) {
143 + if ($isFileType && !empty($file[$key]['name'][0])) {
98 144 return false;
99 145 }
100 146 }
101 147 return true;
@@ -100,10 +146,33 @@
100 146 }
101 147 return true;
102 148 }
103 149
104 - private function getParams() {
105 - $url = parse_url(wp_get_referer());
150 + private function checkRepeatedFieldEmptySubmission($isFileType, $data, $file = [])
151 + {
152 + if (!$isFileType) {
153 + foreach ($data as $value) {
154 + if (!empty($value)) {
155 + return false;
156 + }
157 + }
158 + }
159 + if ($isFileType) {
160 + foreach ($file['name'] as $value) {
161 + if (!empty($value) && is_string($value)) {
162 + return false;
163 + }
164 + if (is_array($value) && !empty($value[0])) {
165 + return false;
166 + }
167 + }
168 + }
169 + return true;
170 + }
171 +
172 + private function getParams()
173 + {
174 + $url = wp_parse_url(wp_get_referer());
106 175 $parameter = [];
107 176 if (isset($url['query'])) {
108 177 $queries = explode('&', $url['query']);
109 178 foreach ($queries as $query) {
@@ -113,13 +182,17 @@
113 182 }
114 183 return $parameter;
115 184 }
116 185
117 - public function handleSubmission() {
186 + public function handleSubmission()
187 + {
118 188 $this->fieldNameReplaceOfPost();
189 +
119 190 $validated = $this->beforeSubmittedValidate();
191 + $validated = apply_filters('bitform_filter_form_validation', $validated, $this->_form_id);
120 192
121 193 if (true === $validated) {
194 + do_action('bitform_validation_success', $this->_form_id);
122 195 unset($_POST['hidden_fields']);
123 196
124 197 $redirectPage = '';
125 198 $regSuccMsg = '';
@@ -131,13 +204,17 @@
131 204
132 205 if (true === $existAuthFilter) {
133 206 $result = apply_filters('bf_wp_user_auth', $existAuth[0], $_POST, $parameter);
134 207
208 + $result = apply_filters('bitform_filter_wp_user_auth_response', $result, $this->_form_id, $_POST, $parameter);
209 +
210 + do_action('bitform_wp_user_auth_response', $result, $this->_form_id, $_POST, $parameter);
211 +
135 212 if (isset($result['auth_type']) && 'register' === $result['auth_type']) {
136 213 if (!$result['success']) {
137 214 return new WP_Error('errors', __($result['message'], 'bit-form'));
138 215 } elseif (isset($result['success'])) {
139 - $redirectPage = $result['redirect_url'];
216 + $redirectPage = $result['redirectPage'];
140 217 $regSuccMsg = $result['message'];
141 218 $newNonce = wp_create_nonce('bitforms_' . $this->_form_id);
142 219 }
143 220 } else {
@@ -157,8 +234,19 @@
157 234
158 235 $entryID = $saveResponse['entry_id'];
159 236 do_action('bitform_submit_success', $this->_form_id, $entryID, $_POST);
160 237
238 + // check and replace signature field value
239 + $formFields = $this->getFields();
240 + $uploadPath = BITFORMS_UPLOAD_BASE_URL . "/uploads/{$this->_form_id}/{$entryID}";
241 +
242 + foreach ($formFields as $key => $field) {
243 + if ('signature' === $field['type']) {
244 + $saveResponse['fields'][$key] = $uploadPath . '/' . $saveResponse['fields'][$key];
245 + break;
246 + }
247 + }
248 +
161 249 $captchaV3Settings = $this->getCaptchaV3Settings();
162 250 if ($captchaV3Settings) {
163 251 $token = $_POST['g-recaptcha-response'];
164 252 $integrationHandler = new IntegrationHandler(0);
@@ -191,8 +279,9 @@
191 279 }
192 280 if (!empty($regSuccMsg) && isset($saveResponse['dflt_message'])) {
193 281 $saveResponse['message'] = $regSuccMsg;
194 282 }
283 +
195 284 $saveResponse = IntegrationHandler::maybeSetCronForIntegration($saveResponse, 'create');
196 285 $entryId = $saveResponse['entry_id'];
197 286
198 287 $responseMsg = is_array($saveResponse) && !empty($saveResponse) ? $saveResponse : __('Form Submitted Successfully', 'bit-form');
@@ -206,17 +295,21 @@
206 295 do_action('bitform_validation_error', $this->_form_id, $validated);
207 296 return $validated;
208 297 }
209 298
210 - public function handleUpdateEntry() {
299 + public function handleUpdateEntry()
300 + {
211 301 $this->fieldNameReplaceOfPost();
212 302 $validated = $this->beforeSubmittedValidate();
303 + $validated = apply_filters('bitform_filter_form_validation', $validated, $this->_form_id);
213 304
214 - $entryID = $_POST['entryID'];
305 + $entryID = $_REQUEST['entryID'];
306 + $GLOBALS['bf_entry_id'] = $entryID;
215 307 if (is_null($entryID)) {
216 308 return new WP_Error('empty_form', __('Entries id is invalid', 'bit-form'));
217 309 }
218 310 if (true === $validated) {
311 + do_action('bitform_validation_success', $this->_form_id);
219 312 unset($_POST['hidden_fields'], $_POST['entryID']);
220 313
221 314 $redirectPage = '';
222 315 $regSuccMsg = '';
@@ -232,9 +325,9 @@
232 325 if (isset($result['auth_type']) && 'register' === $result['auth_type']) {
233 326 if (!$result['success']) {
234 327 return new WP_Error('errors', __($result['message'], 'bit-form'));
235 328 } elseif (isset($result['success'])) {
236 - $redirectPage = $result['redirect_url'];
329 + $redirectPage = $result['redirectPage'];
237 330 $regSuccMsg = $result['message'];
238 331 $newNonce = wp_create_nonce('bitforms_' . $this->_form_id);
239 332 }
240 333 } else {
@@ -302,9 +395,10 @@
302 395 do_action('bitform_validation_error', $this->_form_id, $validated);
303 396 return $validated;
304 397 }
305 398
306 - public function validateFormSubmission($submitted_data) {
399 + public function validateFormSubmission($submitted_data)
400 + {
307 401 $hidden_fields = isset($submitted_data['hidden_fields']) ? $submitted_data['hidden_fields'] : '';
308 402 $submitted_fields = $this->getSubmittedFields($submitted_data);
309 403 $form_fields = $this->getFields();
310 404 $form_fields_names = array_keys($form_fields);
@@ -310,9 +404,9 @@
310 404 $form_fields_names = array_keys($form_fields);
311 405 if ($this->isGCLIDEnabled()) {
312 406 array_push($form_fields_names, 'GCLID');
313 407 }
314 - foreach ($submitted_fields as $key => $field) {
408 + foreach ($submitted_fields as $field) {
315 409 if ('hidden_fields' !== $field && !in_array($field, $form_fields_names) || false !== strpos($hidden_fields, $field)) {
316 410 unset($submitted_data[$field]);
317 411 }
318 412 }
@@ -318,27 +412,10 @@
318 412 }
319 413 return $submitted_data;
320 414 }
321 415
322 - public function fieldNameReplaceOfPost() {
323 - $fields = $this->getFields();
324 - foreach ($fields as $fieldKey => $fieldData) {
325 - if (array_key_exists('name', $fieldData)) {
326 - $fldName = $fieldData['name'];
327 - if (array_key_exists($fldName, $_POST)) {
328 - $temp = $_POST[$fldName];
329 - unset($_POST[$fldName]);
330 - $_POST[$fieldKey] = $temp;
331 - } elseif (array_key_exists($fldName, $_FILES)) {
332 - $temp = $_FILES[$fldName];
333 - unset($_FILES[$fldName]);
334 - $_FILES[$fieldKey] = $temp;
335 - }
336 - }
337 - }
338 - }
339 -
340 - public function beforeSubmittedValidate() {
416 + public function beforeSubmittedValidate()
417 + {
341 418 if ($this->verifySubmissionNonce()) {
342 419 if ($this->isExist()) {
343 420 $isRestricted = $this->checkSubmissionRestriction();
344 421 if ($isRestricted && !empty($isRestricted)) {
@@ -346,53 +423,20 @@
346 423 }
347 424 if ($this->isTrappedInHoneypot()) {
348 425 return new WP_Error('spam_detection', __('Token verification failed', 'bit-form'));
349 426 }
350 - $captchaSettings = $this->getCaptchaSettings();
351 - $captchaV3Settings = $this->getCaptchaV3Settings();
352 - if ($captchaSettings || $captchaV3Settings) {
353 - $token = $_POST['g-recaptcha-response'];
354 - if (!isset($_POST['g-recaptcha-response'])) {
355 - return new WP_Error('spam_detection', __('Please verify reCAPTCHA', 'bit-form'));
356 - }
357 - $integrationHandler = new IntegrationHandler(0);
358 - $allFormIntegrations = $integrationHandler->getAllIntegration('app', $captchaSettings ? 'gReCaptcha' : 'gReCaptchaV3');
359 - if (!is_wp_error($allFormIntegrations)) {
360 - foreach ($allFormIntegrations as $integration) {
361 - if (!is_null($integration->integration_type) && $integration->integration_type === ($captchaSettings ? 'gReCaptcha' : 'gReCaptchaV3')) {
362 - $integrationDetails = json_decode($integration->integration_details);
363 - $integrationDetails->id = $integration->id;
364 - $reCAPTCHA = $integrationDetails;
365 - }
366 - }
367 - }
368 - if (!empty($reCAPTCHA->secretKey)) {
369 - $gRecaptchaResponse = HttpHelper::post(
370 - 'https://www.google.com/recaptcha/api/siteverify',
371 - ['secret' => $reCAPTCHA->secretKey, 'response' => $token]
372 - );
373 - $isgReCaptchaVerified = false;
374 - if (!is_wp_error($gRecaptchaResponse)) {
375 - if (
376 - $captchaV3Settings
377 - && !empty($gRecaptchaResponse->score)
378 - && ((float) $gRecaptchaResponse->score < (float) $captchaV3Settings->score)
379 - ) {
380 - wp_send_json_error(
381 - __(
382 - $captchaV3Settings->message,
383 - 'bit-form'
384 - )
385 - );
386 - }
427 + $formCurrentStep = isset($_POST['form-current-step']) ? $_POST['form-current-step'] : null;
387 428
388 - $isgReCaptchaVerified = $gRecaptchaResponse->success;
389 - }
390 - if (!$isgReCaptchaVerified) {
391 - return new WP_Error('spam_detection', __('Please verify reCAPTCHA', 'bit-form'));
392 - }
393 - }
429 + if (is_wp_error($this->verifyGRecaptcha())) {
430 + return $this->verifyGRecaptcha();
394 431 }
432 +
433 + /* Implement Turnstile Captcha start */
434 + if (is_wp_error($this->verifyTurnstileCaptcha())) {
435 + return $this->verifyTurnstileCaptcha();
436 + }
437 + /* Implement Turnstile Captcha end */
438 +
395 439 $existAuth = (new IntegrationHandler($this->_form_id))->getAllIntegration('wp_user_auth', 'wp_auth', 1);
396 440
397 441 // check if user is already logged in and form has auth integration
398 442 do_action('bitform_checked_exist_auth', $this->_form_id, $existAuth);
@@ -402,8 +446,30 @@
402 446 $validateForm = $this->validateFormSubmission($_POST);
403 447 $validateFormFiles = $this->validateFormSubmission($_FILES);
404 448 $validateForm = array_merge($validateForm, $validateFormFiles);
405 449 $form_fields = $this->getFields();
450 + // check if form-current-step is set and form is multi-step
451 + $formCurrentStep = isset($_POST['form-current-step']) ? $_POST['form-current-step'] : null;
452 + if (!is_null($formCurrentStep)) {
453 + $formContents = $this->getFormContent();
454 + $layout = $formContents->layout;
455 + $stepIndex = (int) $formCurrentStep - 1;
456 + $stepLayout = $layout[$stepIndex]->layout->lg;
457 + $nestedLayout = $formContents->nestedLayout;
458 + $step_fields = [];
459 + foreach ($stepLayout as $lay) {
460 + $fk = $lay->i;
461 + if (isset($nestedLayout->{$fk})) {
462 + $nestedLg = $nestedLayout->{$fk}->lg;
463 + foreach ($nestedLg as $nestedLay) {
464 + $nestedFk = $nestedLay->i;
465 + $step_fields[$nestedFk] = $form_fields[$nestedFk];
466 + }
467 + }
468 + $step_fields[$fk] = $form_fields[$fk];
469 + }
470 + $form_fields = $step_fields;
471 + }
406 472 $formFieldValidator = new FormFieldValidator($form_fields, $_POST, $_FILES);
407 473 $validUniuqFields = [];
408 474 $existFilter = has_filter('bf_check_duplicate_entry');
409 475 if (true === $existFilter) {
@@ -440,19 +506,111 @@
440 506 return new WP_Error('token_expired', __('Token expired', 'bit-form'));
441 507 }
442 508 }
443 509
444 - public function verifySubmissionNonce() {
445 - if (!isset($_POST['t_identy']) && !isset($_POST['csrf'])) {
510 + private function verifyGRecaptcha()
511 + {
512 + $captchaSettings = $this->getCaptchaSettings();
513 + $captchaV3Settings = $this->getCaptchaV3Settings();
514 + if ($captchaSettings || $captchaV3Settings) {
515 + $token = $_POST['g-recaptcha-response'];
516 + if (!isset($_POST['g-recaptcha-response'])) {
517 + return new WP_Error('spam_detection', __('Please verify reCAPTCHA', 'bit-form'));
518 + }
519 + $integrationHandler = new IntegrationHandler(0);
520 + $allFormIntegrations = $integrationHandler->getAllIntegration('app', $captchaSettings ? 'gReCaptcha' : 'gReCaptchaV3');
521 + if (!is_wp_error($allFormIntegrations)) {
522 + foreach ($allFormIntegrations as $integration) {
523 + if (!is_null($integration->integration_type) && $integration->integration_type === ($captchaSettings ? 'gReCaptcha' : 'gReCaptchaV3')) {
524 + $integrationDetails = json_decode($integration->integration_details);
525 + $integrationDetails->id = $integration->id;
526 + $reCAPTCHA = $integrationDetails;
527 + }
528 + }
529 + }
530 + if (!empty($reCAPTCHA->secretKey)) {
531 + $gRecaptchaResponse = HttpHelper::post(
532 + 'https://www.google.com/recaptcha/api/siteverify',
533 + ['secret' => $reCAPTCHA->secretKey, 'response' => $token]
534 + );
535 + $isgReCaptchaVerified = false;
536 + if (!is_wp_error($gRecaptchaResponse)) {
537 + if (
538 + $captchaV3Settings
539 + && !empty($gRecaptchaResponse->score)
540 + && ((float) $gRecaptchaResponse->score < (float) $captchaV3Settings->score)
541 + ) {
542 + wp_send_json_error(
543 + __(
544 + $captchaV3Settings->message,
545 + 'bit-form'
546 + )
547 + );
548 + }
549 +
550 + $isgReCaptchaVerified = $gRecaptchaResponse->success;
551 + }
552 + if (!$isgReCaptchaVerified) {
553 + return new WP_Error('spam_detection', __('Please verify reCAPTCHA', 'bit-form'));
554 + }
555 + }
556 + }
557 + }
558 +
559 + private function verifyTurnstileCaptcha()
560 + {
561 + $turnstileSetting = $this->getTurnstileSettings();
562 + if ($turnstileSetting) {
563 + if (!isset($_POST['cf-turnstile-response'])) {
564 + return new WP_Error('spam_detection', __('Please verify Cloudflare Turnstile Captcha', 'bit-form'));
565 + }
566 + $token = $_POST['cf-turnstile-response'];
567 + $turnstileCaptcha = null;
568 + $integrationHandler = new IntegrationHandler(0);
569 + $turnstileIntegration = $integrationHandler->getAllIntegration('app', 'turnstileCaptcha')[0];
570 + if (!is_wp_error($turnstileIntegration && !is_null($turnstileIntegration->integration_type))) {
571 + $turnstileCaptcha = json_decode($turnstileIntegration->integration_details);
572 + // $integrationDetails->id = $turnstileIntegration->id;
573 + // $turnstileCaptcha = $integrationDetails;
574 + }
575 + if (!is_null($turnstileCaptcha)) {
576 + $isTurnstileCaptchaVerified = false;
577 + $turnstileRecaptchaResponse = HttpHelper::post(
578 + 'https://challenges.cloudflare.com/turnstile/v0/siteverify',
579 + ['secret' => $turnstileCaptcha->secretKey, 'response' => $token]
580 + );
581 + if (!is_wp_error($turnstileRecaptchaResponse)) {
582 + if (!$turnstileRecaptchaResponse->success) {
583 + wp_send_json_error(
584 + __(
585 + 'Cloudflare Turnstile Validation Error: ' . implode(', ', $turnstileRecaptchaResponse->{'error-codes'}),
586 + 'bit-form'
587 + )
588 + );
589 + }
590 +
591 + $isTurnstileCaptchaVerified = $turnstileRecaptchaResponse->success;
592 + }
593 + if (!$isTurnstileCaptchaVerified) {
594 + return new WP_Error('spam_detection', __('Please verify Cloudflare Turnstile Captcha', 'bit-form'));
595 + }
596 + }
597 + }
598 + }
599 +
600 + public function verifySubmissionNonce()
601 + {
602 + if (!isset($_POST['t_identity']) && !isset($_POST['csrf'])) {
446 603 return false;
447 604 }
448 - $tIdenty = sanitize_text_field($_POST['t_identy']);
605 + $tIdenty = sanitize_text_field($_POST['t_identity']);
449 606 $csrf = sanitize_text_field($_POST['csrf']);
450 - unset($_POST['t_identy'], $_POST['action'], $_POST['bitforms_id'], $_POST['csrf']);
607 + unset($_POST['t_identity'], $_POST['action'], $_POST['bitforms_id'], $_POST['csrf']);
451 608 return Helpers::csrfDecrypted($tIdenty, $csrf);
452 609 }
453 610
454 - public function setViewCount() {
611 + public function setViewCount()
612 + {
455 613 if (!current_user_can('manage_options')) {
456 614 $update_status = $this->formModel->update(
457 615 [
458 616 'views' => intval(static::$form[0]->views) + 1
@@ -463,158 +621,160 @@
463 621 );
464 622 }
465 623 }
466 624
467 - public function checkSubmissionRestriction() {
468 - $formContents = $this->getFormContent();
469 - $fromRestrictionSetitingsEnabled = empty($formContents->additional->enabled) ? [] : $formContents->additional->enabled;
470 - $fromRestrictionSetitings = empty($formContents->additional->settings) ? null : $formContents->additional->settings;
471 - if (is_null($formContents->additional->enabled) || is_null($formContents->additional->settings)) {
472 - return false;
473 - }
474 - $restrictionMessage = [];
475 - $ipTool = new IpTool();
476 - $ipAddress = $ipTool->getIP();
477 - foreach ($fromRestrictionSetitingsEnabled as $restrictionKey => $isEnabled) {
478 - if ($isEnabled) {
479 - if ('entry_limit' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
480 - $formEntry = new FormEntryModel();
481 - $countResult = $formEntry->count(
482 - [
483 - 'form_id' => $this->form_id
484 - ]
485 - );
486 - $count = !empty($countResult[0]) && !empty($countResult[0]->count) ? $countResult[0]->count : false;
487 - if ($count && $count >= intval($fromRestrictionSetitings->{$restrictionKey})) {
488 - $restrictionMessage[] = __('Sorry!! Entry limit exceeded', 'bit-form');
489 - }
625 + public function checkSubmissionRestriction($checkedEmptySubmitted = true)
626 + {
627 + $formContents = $this->getFormContent();
628 + $fromRestrictionSetitingsEnabled = empty($formContents->additional->enabled) ? [] : $formContents->additional->enabled;
629 + $fromRestrictionSetitings = empty($formContents->additional->settings) ? null : $formContents->additional->settings;
630 + if (is_null($formContents->additional->enabled) || is_null($formContents->additional->settings)) {
631 + return false;
632 + }
633 + $restrictionMessage = [];
634 + $ipTool = new IpTool();
635 + $ipAddress = $ipTool->getIP();
636 + foreach ($fromRestrictionSetitingsEnabled as $restrictionKey => $isEnabled) {
637 + if ($isEnabled) {
638 + if ('entry_limit' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
639 + $formEntry = new FormEntryModel();
640 + $countResult = $formEntry->count(
641 + [
642 + 'form_id' => $this->form_id
643 + ]
644 + );
645 + $count = !empty($countResult[0]) && !empty($countResult[0]->count) ? $countResult[0]->count : false;
646 + if ($count && $count >= intval($fromRestrictionSetitings->{$restrictionKey})) {
647 + $restrictionMessage[] = __('Sorry!! Entry limit exceeded', 'bit-form');
490 648 }
491 - if ('onePerIp' === $restrictionKey) {
492 - $formEntry = new FormEntryModel();
493 - $countResult = $formEntry->count(
494 - [
495 - 'form_id' => $this->form_id,
496 - 'user_ip' => ip2long($ipAddress)
497 - ]
498 - );
499 - $count = !empty($countResult[0]) && !empty($countResult[0]->count) ? $countResult[0]->count : false;
649 + }
650 + if ('onePerIp' === $restrictionKey) {
651 + $formEntry = new FormEntryModel();
652 + $countResult = $formEntry->count(
653 + [
654 + 'form_id' => $this->form_id,
655 + 'user_ip' => ip2long($ipAddress)
656 + ]
657 + );
658 + $count = !empty($countResult[0]) && !empty($countResult[0]->count) ? $countResult[0]->count : false;
500 659
501 - if ($count && $count > 0) {
502 - $restrictionMessage[] = __('Sorry!! You have already submitted', 'bit-form');
503 - }
660 + if ($count && $count > 0) {
661 + $restrictionMessage[] = __('Sorry!! You have already submitted', 'bit-form');
504 662 }
505 - if ('is_login' === $restrictionKey && 0 === get_current_user_id()) {
506 - $restrictionMessage[] = __($fromRestrictionSetitings->is_login->message, 'bit-form');
663 + }
664 + if ('is_login' === $restrictionKey && 0 === get_current_user_id()) {
665 + $restrictionMessage[] = __($fromRestrictionSetitings->is_login->message, 'bit-form');
666 + }
667 + if ($checkedEmptySubmitted && 'empty_submission' === $restrictionKey) {
668 + $isEmpty = $this->checkEmptySubmission($_POST, $_FILES);
669 + if ($isEmpty) {
670 + $restrictionMessage[] = __($fromRestrictionSetitings->empty_submission->message, 'bit-form');
507 671 }
508 - if ('empty_submission' === $restrictionKey) {
509 - $isEmpty = $this->checkEmptySubmission($_POST, $_FILES);
510 - if ($isEmpty) {
511 - $restrictionMessage[] = __($fromRestrictionSetitings->empty_submission->message, 'bit-form');
672 + }
673 + if ('restrict_form' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
674 + $day = empty($fromRestrictionSetitings->{$restrictionKey}->day) ? null : $fromRestrictionSetitings->{$restrictionKey}->day;
675 + $date = empty($fromRestrictionSetitings->{$restrictionKey}->date) ? null : $fromRestrictionSetitings->{$restrictionKey}->date;
676 + $time = empty($fromRestrictionSetitings->{$restrictionKey}->time) ? null : $fromRestrictionSetitings->{$restrictionKey}->time;
677 +
678 + $isdayOk = $isdateOk = $istimeOk = true;
679 + $dayNotOkMsg = $dateNotOkMsg = $timeNotOkMsg = '';
680 + $dateTimeHelper = new DateTimeHelper();
681 + if (
682 + !empty($day)
683 + && is_array($day)
684 + && (in_array('Friday', $day)
685 + || in_array('Saturday', $day)
686 + || in_array('Sunday', $day)
687 + || in_array('Monday', $day)
688 + || in_array('Tuesday', $day)
689 + || in_array('Wednesday', $day)
690 + || in_array('Thursday', $day))
691 + && (!in_array($dateTimeHelper->getDay('full-name'), $day))
692 + ) {
693 + $isdayOk = false;
694 + $dayMsgVarsFormat = '';
695 + foreach ($day as $dayIndex => $dayValue) {
696 + if ($dayIndex > 0) {
697 + $dayMsgVarsFormat .= ', ';
698 + }
699 + $dayMsgVarsFormat .= '%s';
512 700 }
701 + $dayNotOkMsg = vsprintf(__("in $dayMsgVarsFormat", 'bit-form'), $day);
513 702 }
514 - if ('restrict_form' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
515 - $day = empty($fromRestrictionSetitings->{$restrictionKey}->day) ? null : $fromRestrictionSetitings->{$restrictionKey}->day;
516 - $date = empty($fromRestrictionSetitings->{$restrictionKey}->date) ? null : $fromRestrictionSetitings->{$restrictionKey}->date;
517 - $time = empty($fromRestrictionSetitings->{$restrictionKey}->time) ? null : $fromRestrictionSetitings->{$restrictionKey}->time;
518 -
519 - $isdayOk = $isdateOk = $istimeOk = true;
520 - $dayNotOkMsg = $dateNotOkMsg = $timeNotOkMsg = '';
521 - $dateTimeHelper = new DateTimeHelper();
522 - if (
523 - !empty($day)
524 - && is_array($day)
525 - && (in_array('Friday', $day)
526 - || in_array('Saturday', $day)
527 - || in_array('Sunday', $day)
528 - || in_array('Monday', $day)
529 - || in_array('Tuesday', $day)
530 - || in_array('Wednesday', $day)
531 - || in_array('Thursday', $day))
532 - && (!in_array($dateTimeHelper->getDay('full-name'), $day))
533 - ) {
534 - $isdayOk = false;
535 - $dayMsgVarsFormat = '';
536 - foreach ($day as $dayIndex => $dayValue) {
537 - if ($dayIndex > 0) {
538 - $dayMsgVarsFormat .= ', ';
539 - }
540 - $dayMsgVarsFormat .= '%s';
541 - }
542 - $dayNotOkMsg = vsprintf(__("in $dayMsgVarsFormat", 'bit-form'), $day);
703 + if (
704 + !empty($day)
705 + && is_array($day)
706 + && (in_array('Custom', $day))
707 + ) {
708 + $startDate = empty($date->from) ? '00-00-0000' : $date->from;
709 + $endDate = empty($date->to) ? '00-00-0000' : $date->to;
710 + $dateFormat = preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $startDate) ? 'Y-m-d' : 'm-d-Y';
711 + if (!empty($date->from) && false !== strpos($startDate, 'T')) {
712 + $startDate = $dateTimeHelper->getDate($startDate, false, null, $dateFormat);
543 713 }
544 - if (
545 - !empty($day)
546 - && is_array($day)
547 - && (in_array('Custom', $day))
548 - ) {
549 - $startDate = empty($date->from) ? '00-00-0000' : $date->from;
550 - $endDate = empty($date->to) ? '00-00-0000' : $date->to;
551 - if (!empty($date->from) && false !== strpos($startDate, 'T')) {
552 - $startDate = $dateTimeHelper->getDate($startDate, false, null, 'm-d-Y');
553 - }
554 - if (!empty($date->to) && false !== strpos($endDate, 'T')) {
555 - $endDate = $dateTimeHelper->getDate($endDate, false, null, 'm-d-Y');
556 - }
557 - $currentDate = $dateTimeHelper->getDate(null, null, null, 'm-d-Y');
558 - if (!($currentDate >= $startDate && $currentDate <= $endDate)) {
559 - $isdateOk = false;
560 - $dateNotOkMsg = sprintf(__('within %s to %s', 'bit-form'), $startDate, $endDate);
561 - }
714 + if (!empty($date->to) && false !== strpos($endDate, 'T')) {
715 + $endDate = $dateTimeHelper->getDate($endDate, false, null, $dateFormat);
562 716 }
717 + $currentDate = $dateTimeHelper->getDate(null, null, null, $dateFormat);
718 + if (!($currentDate >= $startDate && $currentDate <= $endDate)) {
719 + $isdateOk = false;
720 + $dateNotOkMsg = sprintf(__('within %s to %s', 'bit-form'), $startDate, $endDate);
721 + }
722 + }
563 723
564 - if (!empty($time)) {
565 - $startTime = empty($time->from) ? '00:00' : $time->from;
566 - $endTime = empty($time->to) ? '23:59.999' : $time->to;
567 - $currentTime = $dateTimeHelper->getTime(null, null, null, 'H:i');
568 - if (!($currentTime >= $startTime && $currentTime <= $endTime)) {
569 - $istimeOk = false;
570 - $startTime = $dateTimeHelper->getTime($startTime, 'H:i', null);
571 - $endTime = $dateTimeHelper->getTime($endTime, 'H:i', null);
572 - $isTimeOk = false;
573 - $timeNotOkMsg = sprintf(__('%s to %s', 'bit-form'), $startTime, $endTime);
574 - }
724 + if (!empty($time)) {
725 + $startTime = empty($time->from) ? '00:00' : $time->from;
726 + $endTime = empty($time->to) ? '23:59.999' : $time->to;
727 + $currentTime = $dateTimeHelper->getTime(null, null, null, 'H:i');
728 + if (!($currentTime >= $startTime && $currentTime <= $endTime)) {
729 + $istimeOk = false;
730 + $startTime = $dateTimeHelper->getTime($startTime, 'H:i', null);
731 + $endTime = $dateTimeHelper->getTime($endTime, 'H:i', null);
732 + $isTimeOk = false;
733 + $timeNotOkMsg = sprintf(__('%s to %s', 'bit-form'), $startTime, $endTime);
575 734 }
735 + }
576 736
577 - if (!($isdateOk && $isdayOk && $istimeOk)) {
578 - if (!$isdayOk) {
579 - $restrictionMessage[] = !empty($timeNotOkMsg) ? sprintf(__('Form is available %s From %s', 'bit-form'), $dayNotOkMsg, $timeNotOkMsg) :
580 - sprintf(__('Form is available %s', 'bit-form'), $dayNotOkMsg, $timeNotOkMsg);
581 - } elseif (!$isdateOk) {
582 - $restrictionMessage[] = !empty($timeNotOkMsg) ? sprintf(__('Form is available %s From %s', 'bit-form'), $dateNotOkMsg, $timeNotOkMsg) :
583 - sprintf(__('Form is available %s', 'bit-form'), $dateNotOkMsg, $timeNotOkMsg);
584 - } elseif (!$istimeOk) {
585 - $restrictionMessage[] = sprintf(__('Form is available on %s', 'bit-form'), $timeNotOkMsg);
586 - }
737 + if (!($isdateOk && $isdayOk && $istimeOk)) {
738 + if (!$isdayOk) {
739 + $restrictionMessage[] = !empty($timeNotOkMsg) ? sprintf(__('Form is available %s From %s', 'bit-form'), $dayNotOkMsg, $timeNotOkMsg) :
740 + sprintf(__('Form is available %s', 'bit-form'), $dayNotOkMsg, $timeNotOkMsg);
741 + } elseif (!$isdateOk) {
742 + $restrictionMessage[] = !empty($timeNotOkMsg) ? sprintf(__('Form is available %s From %s', 'bit-form'), $dateNotOkMsg, $timeNotOkMsg) :
743 + sprintf(__('Form is available %s', 'bit-form'), $dateNotOkMsg, $timeNotOkMsg);
744 + } elseif (!$istimeOk) {
745 + $restrictionMessage[] = sprintf(__('Form is available on %s', 'bit-form'), $timeNotOkMsg);
587 746 }
588 747 }
589 - if ('blocked_ip' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
590 - $isIpBlocked = false;
591 - foreach ($fromRestrictionSetitings->{$restrictionKey} as $ipIndex => $ipDetails) {
592 - if (!empty($ipDetails->status) && $ipDetails->status && !empty($ipDetails->ip) && $ipDetails->ip === $ipAddress) {
593 - $isIpBlocked = true;
594 - break;
595 - }
748 + }
749 + if ('blocked_ip' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
750 + $isIpBlocked = false;
751 + foreach ($fromRestrictionSetitings->{$restrictionKey} as $ipIndex => $ipDetails) {
752 + if (!empty($ipDetails->status) && $ipDetails->status && !empty($ipDetails->ip) && $ipDetails->ip === $ipAddress) {
753 + $isIpBlocked = true;
754 + break;
596 755 }
597 - if ($isIpBlocked) {
598 - $restrictionMessage[] = sprintf(__('Sorry!! Your IP address is %s, Blocked from submitting the form', 'bit-form'), $ipAddress);
756 + }
757 + if ($isIpBlocked) {
758 + $restrictionMessage[] = sprintf(__('Sorry!! Your IP address is %s, Blocked from submitting the form', 'bit-form'), $ipAddress);
759 + }
760 + }
761 + if ('private_ip' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
762 + $isIpWhiteListed = false;
763 + foreach ($fromRestrictionSetitings->{$restrictionKey} as $ipIndex => $ipDetails) {
764 + if (!empty($ipDetails->status) && $ipDetails->status && !empty($ipDetails->ip) && $ipDetails->ip === $ipAddress) {
765 + $isIpWhiteListed = true;
766 + break;
599 767 }
600 768 }
601 - if ('private_ip' === $restrictionKey && isset($fromRestrictionSetitings->{$restrictionKey})) {
602 - $isIpWhiteListed = false;
603 - foreach ($fromRestrictionSetitings->{$restrictionKey} as $ipIndex => $ipDetails) {
604 - if (!empty($ipDetails->status) && $ipDetails->status && !empty($ipDetails->ip) && $ipDetails->ip === $ipAddress) {
605 - $isIpWhiteListed = true;
606 - break;
607 - }
608 - }
609 - if (!$isIpWhiteListed) {
610 - $restrictionMessage[] = sprintf(__('Sorry!! Your IP address is %s, Blocked from submitting the form', 'bit-form'), $ipAddress);
611 - }
769 + if (!$isIpWhiteListed) {
770 + $restrictionMessage[] = sprintf(__('Sorry!! Your IP address is %s, Blocked from submitting the form', 'bit-form'), $ipAddress);
612 771 }
613 772 }
614 773 }
615 - return $restrictionMessage;
616 774 }
775 + return $restrictionMessage;
776 + }
617 777
618 778 /**
619 779 * Will check if form is submitted by a bot
620 780 *
@@ -619,9 +779,10 @@
619 779 * Will check if form is submitted by a bot
620 780 *
621 781 * @return Boolean true - if submitted by bot else false
622 782 */
623 - public function isTrappedInHoneypot() {
783 + public function isTrappedInHoneypot()
784 + {
624 785 $isHoneyPot = false;
625 786
626 787 if (!$this->isHoneypotActive()) {
627 788 return false;
@@ -649,9 +810,10 @@
649 810 unset($_POST['b_h_t']);
650 811 return $isHoneyPot;
651 812 }
652 813
653 - public function isHoneypotActive() {
814 + public function isHoneypotActive()
815 + {
654 816 $formContents = $this->getFormContent();
655 817 $enabled = empty($formContents->additional->enabled) ? null : $formContents->additional->enabled;
656 818 if (!empty($enabled->honeypot) && $enabled->honeypot) {
657 819 return true;
@@ -658,9 +820,10 @@
658 820 }
659 821 return false;
660 822 }
661 823
662 - public function checkPaymentFields() {
824 + public function checkPaymentFields()
825 + {
663 826 $formContents = $this->getFormContent();
664 827 $fields = $formContents->fields;
665 828
666 829 $payments = [];
@@ -674,9 +837,10 @@
674 837
675 838 return $payments;
676 839 }
677 840
678 - private function getClientKey($integID, $keyName) {
841 + private function getClientKey($integID, $keyName)
842 + {
679 843 $client = '';
680 844 if (!empty($integID)) {
681 845 $integrationHandler = new IntegrationHandler(0);
682 846 $integration = $integrationHandler->getAIntegration($integID, 'app', 'payments');
@@ -687,9 +851,10 @@
687 851 }
688 852 return $client;
689 853 }
690 854
691 - public function getSuccessMessageMarkups() {
855 + public function getSuccessMessageMarkups()
856 + {
692 857 if (is_null($this->_work_flows)) {
693 858 $workFlowManager = new WorkFlowHandler($this->form_id);
694 859 $this->_work_flows = $workFlowManager->getAllworkFlow();
695 860 }
@@ -732,9 +897,32 @@
732 897
733 898 return $messageMarkups;
734 899 }
735 900
736 - private function messageMarkup($msg) {
901 + public function getFormAbandonmentMessage()
902 + {
903 + if (class_exists('\BitCode\BitFormPro\Admin\FormSettings\FormAbandonment')) {
904 + $formAbandonmentSettings = FormAbandonment::getFormAbandonmentSettings($this->form_id);
905 + $msg = '';
906 + if (isset($formAbandonmentSettings->showWarningMsg) && $formAbandonmentSettings->showWarningMsg && !empty($formAbandonmentSettings->warningMsg)) {
907 + $msg = $formAbandonmentSettings->warningMsg;
908 + $msg = '<div class="bf-form-msg active warning">' . wp_kses_post($msg) . '</div>';
909 + }
910 + return $msg;
911 + }
912 + }
913 +
914 + public function getFormAbandonmentSettings()
915 + {
916 + if (class_exists('\BitCode\BitFormPro\Admin\FormSettings\FormAbandonment')) {
917 + $formAbandonmentSettings = FormAbandonment::getFormAbandonmentSettings($this->form_id);
918 + return $formAbandonmentSettings;
919 + }
920 + return null;
921 + }
922 +
923 + private function messageMarkup($msg)
924 + {
737 925 $msgId = $msg->id;
738 926 $msgConfig = json_decode($msg->message_config);
739 927 $scrollClass = 'below' === $msgConfig->msgType ? 'scroll' : '';
740 928
@@ -740,10 +928,10 @@
740 928
741 929 return <<<SUCCESSMSG
742 930 <div role="dialog" aria-hidden="true" data-modal-backdrop="true" class="{$this->getAtomicCls("msg-container-{$msgId}")} deactive {$scrollClass}">
743 931 <div data-contentid="{$this->getFormIdentifier()}" data-msgid="{$msgId}" role="button" class="{$this->getAtomicCls("msg-background-{$msgId}")} msg-backdrop">
744 - <div class="{$this->getAtomicCls("msg-content-{$msgId}")}">
745 - <button data-contentid="{$this->getFormIdentifier()}" data-msgid="{$msgId}" class="{$this->getAtomicCls("close-{$msgId}")} msg-close" type="button">
932 + <div class="bf-msg-content {$this->getAtomicCls("msg-content-{$msgId}")}">
933 + <button data-contentid="{$this->getFormIdentifier()}" data-msgid="{$msgId}" class="{$this->getAtomicCls("close-{$msgId}")} bf-msg-close" type="button">
746 934 <svg class="{$this->getAtomicCls("close-icn-{$msgId}")}" viewBox="0 0 30 30">
747 935 <line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" x1="4" y1="3.88" x2="26" y2="26.12"></line>
748 936 <line fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" x1="26" y1="3.88" x2="4" y2="26.12"></line>
749 937 </svg>