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
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 / Frontend / Form / FrontendFormHandler.php

FrontendFormHandler.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 2.16.2, at includes/Frontend/Form/FrontendFormHandler.php

756 lines 29.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace BitCode\BitForm\Frontend\Form;
4
5 use BitCode\BitForm\Admin\Form\FrontEndScriptGenerator;
6 use BitCode\BitForm\Admin\Form\Helpers;
7 use BitCode\BitForm\Core\Database\FormEntryMetaModel;
8 use BitCode\BitForm\Core\Database\FormModel;
9 use BitCode\BitForm\Core\Form\FormManager;
10 use BitCode\BitForm\Core\Integration\IntegrationHandler;
11 use BitCode\BitForm\Core\Util\FieldValueHandler;
12 use BitCode\BitForm\Core\Util\FileDownloadProvider;
13 use BitCode\BitForm\Core\Util\FrontendHelpers;
14 use BitCode\BitForm\Core\Util\SmartTags;
15 use BitCode\BitForm\Core\Util\Utilities;
16 use BitCode\BitForm\Core\WorkFlow\WorkFlow;
17 use BitCode\BitFormPro\Admin\FormSettings\FormAbandonment;
18
19 final class FrontendFormHandler
20 {
21 public function __construct()
22 {
23 // before markup load - formids [], posts [1,2]
24 add_action('wp_enqueue_scripts', [$this, 'loadAssets']);
25 // markup loads - formids []
26 add_shortcode('bitform', [$this, 'handleFrontendRenderRequest']);
27 // after markup load - formids [1,35,3]
28 add_action('wp_footer', [$this, 'generateJS']);
29 }
30
31 private function validPassowordResetToken($token, $userID, $formId)
32 {
33 $existResetInteg = (new IntegrationHandler($formId))->getAllIntegration('wp_user_auth', 'wp_auth', 1);
34 if (!is_wp_error($existResetInteg) && count($existResetInteg) > 0) {
35 if ('reset' === $existResetInteg[0]->integration_name) {
36 $user = get_userdata($userID);
37 if ($user) {
38 $validKey = check_password_reset_key($token, $user->user_login);
39 if (is_wp_error($validKey)) {
40 echo "<div id='bf-resp' style='display:grid;justify-content:center;color:#860000;'>This password reset token is invalid.</div>";
41 exit();
42 }
43 } else {
44 echo "<div id='bf-resp' style='display:grid;justify-content:center;color:#860000;'>Invalid User!!</div>";
45 exit();
46 }
47 }
48 }
49 }
50
51 private function getJSFileSrc($postId)
52 {
53 $formUpdateVersion = get_option('bit-form_form_update_version');
54 $formScriptSrc = BITFORMS_UPLOAD_BASE_URL . "/form-scripts/$postId/bitform-js-$postId.js?bfv=$formUpdateVersion";
55
56 return $formScriptSrc;
57 }
58
59 public function generateJs($formID = null, $entryID = null, $formType = null)
60 {
61 // return true;
62 $isFormPreview = get_transient('bitform_form_preview');
63 if ($isFormPreview && !$formID) {
64 delete_transient('bitform_form_preview');
65 return;
66 }
67 $frontendScriptGenObj = new FrontEndScriptGenerator();
68 $isPageBuilder = FrontendHelpers::checkIsPageBuilder($_SERVER);
69 $bfFrontendFormIds = FrontendHelpers::$bfFrontendFormIds;
70 if ($isPageBuilder || empty($bfFrontendFormIds)) {
71 return;
72 }
73 // for unique fields ids in the same form (e.g. multiple forms in the same page)
74 $allFields = [];
75 $formContents = [];
76 $contentIds = [];
77 $formIDs = [];
78 $previewMode = 'classic';
79 $postId = '';
80
81 $formUpdateVersion = get_option('bit-form_form_update_version');
82 if ($formID) {
83 $formIDs[] = $formID;
84 $FrontendFormManager = new FrontendFormManager($formID, 1);
85 $formInfo = $FrontendFormManager->getFormInfo();
86 $FormIdentifier = esc_js($FrontendFormManager->getFormIdentifier());
87 $formContent = $FrontendFormManager->getFormContentWithValue($this->getValuesFromQueryParams());
88 $formContent->formId = $formID;
89 $formContents[] = $formContent;
90 $workFlowRunType = $entryID ? 'edit' : 'create';
91 $fields = $formContent->fields;
92 if ($entryID) {
93 $fields = $this->setFieldsValue($fields, $formID, $entryID);
94 }
95 $fields = $this->triggerWorkflowOnLoad($formID, 1, $fields, $workFlowRunType);
96 array_push($contentIds, $FormIdentifier);
97
98 foreach ($fields as $fk => $field) {
99 $allFields[$field->typ][] = ['fk' => $fk, 'field' => $field, 'formID' => $formID, 'contentId' => $FormIdentifier];
100 }
101 //Generate JS file for conversational form
102 if (!empty($formInfo->conversationalSettings->enable) && $formInfo->conversationalSettings->enable) {
103 $frontendScriptGenObj->generateJsFile([$formContent], $allFields, [$FormIdentifier], $formID, [$formID], 'conversational');
104 }
105 $previewMode = 'preview';
106 $postId = $formID;
107 } else {
108 global $post;
109 if (!is_object($post) && !isset($post->ID)) {
110 return;
111 }
112 $bfFrontendFormIds = FrontendHelpers::$bfFrontendFormIds;
113 $bfUniqFormIds = FrontendHelpers::getAllUniqFormIdsInPage();
114 $formIDs = $bfUniqFormIds;
115 $regenerateScriptFlag = $this->regenerateScriptChecker($bfUniqFormIds);
116
117 $postId = $post->ID;
118 if (!$regenerateScriptFlag) {
119 $regenerateScriptFlag = $this->deleteUnusedFormPageIds($postId, $bfUniqFormIds);
120 }
121 $isJsGenerating = get_option('bitforms_frontend_js_generating');
122 if (!$regenerateScriptFlag && !$isJsGenerating && !empty($formIDs)) {
123 wp_enqueue_script('bit-form-all-script-test', $this->getJSFileSrc($postId), [], $formUpdateVersion, true);
124 return;
125 }
126 foreach ($bfFrontendFormIds as $index => $formId) {
127 $shortCodeCounter = $index + 1;
128 $FrontendFormManager = new FrontendFormManager($formId, $shortCodeCounter);
129 $formInfo = $FrontendFormManager->getFormInfo();
130 $FormIdentifier = esc_js($FrontendFormManager->getFormIdentifier());
131 $formContent = $FrontendFormManager->getFormContentWithValue($this->getValuesFromQueryParams());
132 $formContent->formId = $formId;
133 $formContents[] = $formContent;
134 $fields = $this->triggerWorkflowOnLoad($formId, $shortCodeCounter, $formContent->fields);
135 $contentIds[] = $FormIdentifier;
136 $formFields = []; // indivisual form fields array for conversational view
137 foreach ($fields as $fk => $field) {
138 $fieldArr = ['fk' => $fk, 'field' => $field, 'formID' => $formId, 'contentId' => $FormIdentifier];
139 $allFields[$field->typ][] = $fieldArr;
140 $formFields[$field->typ][] = $fieldArr;
141 }
142 //Generate JS file for conversational form
143 if (!empty($formInfo->conversationalSettings->enable) && $formInfo->conversationalSettings->enable) {
144 $frontendScriptGenObj->generateJsFile([$formContent], $formFields, [$FormIdentifier], $formId, [$formId], 'conversational');
145 }
146 }
147 }
148 if (empty($formIDs)) {
149 return;
150 }
151
152 $frontendScriptGenObj->generateJsFile($formContents, $allFields, $contentIds, $postId, $formIDs, $previewMode);
153 wp_enqueue_script('bit-form-all-script-test', $this->getJSFileSrc($postId), [], $formUpdateVersion, true);
154 }
155
156 private function deleteUnusedFormPageIds($postId, $formIDs)
157 {
158 global $post;
159 if (!is_object($post) && !isset($post->ID)) {
160 return;
161 }
162 $postId = $post->ID;
163 $formModel = new FormModel();
164 $forms = $formModel->get(
165 ['id', 'generated_script_page_ids']
166 );
167 $regenerateScriptFlag = false;
168 foreach ($forms as $form) {
169 $formId = $form->id;
170 $generatedScriptPageIdsDecoded = json_decode($form->generated_script_page_ids, true);
171 $generatedScriptPageIds = is_array($generatedScriptPageIdsDecoded) ? array_keys($generatedScriptPageIdsDecoded) : [];
172 if (!empty($generatedScriptPageIds) && !in_array($formId, $formIDs) && in_array($postId, $generatedScriptPageIds)) {
173 unset($generatedScriptPageIdsDecoded[$postId]);
174 if (empty($generatedScriptPageIdsDecoded)) {
175 $generatedScriptPageIdsDecoded = new \stdClass();
176 }
177 $regenerateScriptFlag = true;
178 $formModel->update(['generated_script_page_ids' => wp_json_encode($generatedScriptPageIdsDecoded)], ['id' => $formId]);
179 }
180 }
181 if ($regenerateScriptFlag) {
182 $formUpdateVersion = get_option('bit-form_form_update_version');
183 if (!$formUpdateVersion) {
184 $formUpdateVersion = 1;
185 } else {
186 $formUpdateVersion = (int) $formUpdateVersion + 1;
187 }
188 update_option('bit-form_form_update_version', $formUpdateVersion);
189 }
190 return $regenerateScriptFlag;
191 }
192
193 private function regenerateScriptChecker($formsIds)
194 {
195 global $post;
196 if (!is_a($post, 'WP_Post') && !isset($post->ID)) {
197 return;
198 }
199 $postId = $post->ID;
200 $regenerateScriptFlag = false;
201 $formModel = new FormModel();
202 foreach ($formsIds as $formId) {
203 $formInstance = new FormManager($formId);
204 if (!$formInstance->isExist()) {
205 continue;
206 }
207 $generatedPages = $formInstance->getFormData('generated_script_page_ids');
208 if (empty($generatedPages)) {
209 $regenerateScriptFlag = true;
210 } elseif (is_object($generatedPages) && (!isset($generatedPages->{$postId}) || (isset($generatedPages->{$postId}) && false === $generatedPages->{$postId}))) {
211 $regenerateScriptFlag = true;
212 }
213 if (!$regenerateScriptFlag) {
214 continue;
215 }
216 if (!is_object($generatedPages)) {
217 $generatedPages = (object) [];
218 }
219 $generatedPages->{$postId} = true;
220 $formModel->update(
221 [
222 'generated_script_page_ids' => \wp_json_encode($generatedPages)
223 ],
224 [
225 'id' => $formId,
226 ]
227 );
228 }
229 return $regenerateScriptFlag;
230 }
231
232 private function addInlineScript($code, $handle = '', $position = 'after')
233 {
234 $scriptHandle = !empty($handle) ? $handle : 'bf-inline-script';
235 if (!wp_script_is($scriptHandle)) {
236 wp_register_script($scriptHandle, '', [], '', true);
237 wp_enqueue_script($scriptHandle);
238 }
239 wp_add_inline_script($scriptHandle, $code, $position);
240 }
241
242 private function addInlineStyle($code, $handle = '')
243 {
244 $styleHandle = !empty($handle) ? $handle : 'bf-inline-style';
245 if (!wp_style_is($styleHandle)) {
246 wp_register_style($styleHandle, '', [], '', true);
247 wp_enqueue_style($styleHandle);
248 }
249 wp_add_inline_style($styleHandle, $code);
250 }
251
252 private function triggerWorkflowOnLoad($formID, $shortCodeCounter, $fields, $workFlowRunType = 'create')
253 {
254 $FrontendFormManager = new FrontendFormManager($formID, $shortCodeCounter);
255 $previousValue = $this->getValuesFromQueryParams();
256 $formContent = $FrontendFormManager->getFormContentWithValue($previousValue);
257 if (!empty($formContent->workFlowExist)) {
258 $workFlowRunHelper = new WorkFlow($formID);
259 if (!empty($formContent->workFlowExist->onload)) {
260 $workFlowreturnedOnLoad = $workFlowRunHelper->executeOnLoad(
261 $workFlowRunType,
262 $fields
263 );
264
265 if (!empty($workFlowreturnedOnLoad['fields'])) {
266 return $workFlowreturnedOnLoad['fields'];
267 }
268 }
269 }
270
271 return $fields;
272 }
273
274 private function executeOnUserInput($formID, $shortCodeCounter, $fields)
275 {
276 $FrontendFormManager = new FrontendFormManager($formID, $shortCodeCounter);
277 $previousValue = $this->getValuesFromQueryParams();
278 $formContent = $FrontendFormManager->getFormContentWithValue($previousValue);
279 $customCodesExist = strpos(FrontEndScriptGenerator::getCustomCodes($formID)['JavaScript'], 'bfVars');
280 if ($customCodesExist || (!empty($formContent->workFlowExist) && !empty($formContent->workFlowExist->oninput))) {
281 $workFlowRunHelper = new WorkFlow($formID);
282 return $workFlowRunHelper->executeOnUserInput('create', $fields);
283 }
284 }
285
286 private function getValuesFromQueryParams()
287 {
288 $queryParamsValue = [];
289 if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])) {
290 $reqField = $_SERVER['QUERY_STRING'];
291 foreach (explode('&', $reqField) as $keyValue) {
292 // $pattern = '/([a-zA-Z0-9])([a-zA-Z])\=+/';
293 $pattern = '/([^.]+)=(.*?)([^.]+)/';
294 $matches = preg_match($pattern, $keyValue, $matchFormat);
295 if ($matches) {
296 list($field, $value) = explode('=', $keyValue, 2);
297
298 if (!trim($value)) {
299 continue;
300 }
301
302 $queryParamsValue[$field][] = sanitize_text_field(urldecode($value));
303 }
304 }
305 }
306
307 return $queryParamsValue;
308 }
309
310 public function handleFrontendRenderRequest($atts)
311 {
312 $formType = isset($atts['type']) ? $atts['type'] : 'classic';
313 $formPreview = isset($atts['form_preview']) ? $atts['form_preview'] : false;
314 if (isset($atts['form_id'])) {
315 $formID = intval($atts['form_id']);
316 }
317 if (isset($atts['entry_id'])) {
318 $entryId = intval($atts['entry_id']);
319 } elseif (isset($_GET['bf_entry_id'])) {
320 $entryId = $_GET['bf_entry_id'];
321 } else {
322 $entryId = false;
323 }
324 if (isset($atts['id'])) {
325 $atts = shortcode_atts(['id' => 0], $atts);
326 $formID = intval($atts['id']);
327 }
328
329 if (!$formID) {
330 return __('Form ID cannot be empty', 'bit-form');
331 }
332
333 if (!$this->isExist($formID)) {
334 return sprintf(__('#%s no. Form doesn\'t exists', 'bit-form'), $formID);
335 }
336
337 // check for abandoned form entry id
338 $isAbandoned = false;
339 if (empty($entryId) && Utilities::isPro() && class_exists('\BitCode\BitFormPro\Admin\FormSettings\FormAbandonment')) {
340 $FormAbandonment = new FormAbandonment($formID);
341 $isAbandoned = $FormAbandonment->checkAbandonedFormEntryId();
342 }
343
344 FrontendHelpers::setBfFrontendFormIds($formID);
345 $bfFrontendFormIds = FrontendHelpers::$bfFrontendFormIds;
346 $shortCodeCounter = count($bfFrontendFormIds);
347 $FrontendFormManager = new FrontendFormManager($formID, $shortCodeCounter);
348
349 if (!$FrontendFormManager->checkStatus()) {
350 return sprintf(__('#%s no. Form is not active', 'bit-form'), $formID);
351 }
352 ob_start();
353 $this->loadAssets($formID, $formType);
354
355 $font = $FrontendFormManager->getFont();
356
357 if ($font && !$formPreview) {
358 wp_enqueue_style('bf-google-font', $font, '1.0.0', true);
359 }
360
361 if (!empty($_GET['token']) && !empty($_GET['id'])) {
362 $this->validPassowordResetToken($_GET['token'], $_GET['id'], $formID);
363 }
364
365 $previousValue = $this->getValuesFromQueryParams();
366 $errorMessages = []; // delete
367 $FormIdentifier = esc_js($FrontendFormManager->getFormIdentifier());
368 $nonce = $FrontendFormManager->getFormToken();
369 $file = count($FrontendFormManager->getUploadFields()) > 0 ? $FrontendFormManager->getUploadFields() : false;
370
371 $FrontendFormManager->setViewCount();
372
373 $formContent = $FrontendFormManager->getFormContentWithValue($previousValue);
374 $fields = $formContent->fields;
375 $layout = $formContent->layout;
376 $nestedLayout = isset($formContent->nestedLayout) ? $formContent->nestedLayout : (object) [];
377 $buttons = !empty($formContent->buttons) ? $formContent->buttons : '';
378 $additional = $formContent->additional;
379
380 // $workFlowRunType = $entryId ? 'edit' : 'create';
381 if ($entryId && (get_current_user_id() || is_admin())) {
382 // return sprintf(__('Sorry!, You cannot edit #%s no form.', 'bit-form'), $formID);
383 $workFlowRunType = 'edit';
384 $fields = $this->setFieldsValue($fields, $formID, $entryId);
385 } else {
386 $workFlowRunType = 'create';
387 }
388
389 // if ($entryId) {
390 // $fields = $this->setFieldsValue($fields, $formID, $entryId);
391 // }
392
393 $fields = apply_filters('bitform_filter_before_workflow_onload_fields', $fields, $formID);
394 $fields = $this->triggerWorkflowOnLoad($formID, $shortCodeCounter, $fields, $workFlowRunType);
395 $fields = apply_filters('bitform_filter_after_workflow_onload_fields', $fields, $formID);
396 do_action('bitform_onload_fields', $fields, $formID);
397 $workFlowreturnedOnUserInput = $this->executeOnUserInput($formID, $shortCodeCounter, $fields);
398
399 // test for form before remove
400 $noLabel = ['decision-box', 'gdpr', 'html', 'shortcode', 'button', 'paypal', 'razorpay', 'recaptcha'];
401 foreach ($fields as $fldKey => $field) {
402 if (!in_array($field->typ, $noLabel) && isset($field->lbl)) {
403 $lblReplaceToBackslash = str_replace('$_bf_$', '\\', $field->lbl);
404 $fields->{$fldKey}->lbl = FieldValueHandler::replaceSmartTagWithValue($lblReplaceToBackslash);
405 }
406 }
407 $fieldsKey = $FrontendFormManager->getFieldsKey();
408
409 $captchaV3Settings = $FrontendFormManager->getCaptchaV3Settings();
410 if ($FrontendFormManager->getCaptchaSettings() || $captchaV3Settings || $FrontendFormManager->getTurnstileSettings()) {
411 $integrationHandler = new IntegrationHandler(0);
412 $allFormIntegrations = $integrationHandler->getAllIntegration('app');
413 if (!is_wp_error($allFormIntegrations)) {
414 foreach ($allFormIntegrations as $integration) {
415 if (
416 $FrontendFormManager->getCaptchaSettings()
417 && !is_null($integration->integration_type)
418 && 'gReCaptcha' === $integration->integration_type
419 ) {
420 $integrationDetails = json_decode($integration->integration_details);
421 $integrationDetails->id = $integration->id;
422 $reCAPTCHA = $integrationDetails;
423 $reCAPTCHAVersion = 'v2';
424 }
425
426 if (
427 $FrontendFormManager->getTurnstileSettings()
428 && !is_null($integration->integration_type)
429 && 'turnstileCaptcha' === $integration->integration_type
430 ) {
431 $integrationDetails = json_decode($integration->integration_details);
432 $turnstileSiteKey = $integrationDetails->siteKey;
433 }
434
435 if ($captchaV3Settings) {
436 if (!is_null($integration->integration_type) && 'gReCaptchaV3' === $integration->integration_type) {
437 $integrationDetails = json_decode($integration->integration_details);
438 $integrationDetails->id = $integration->id;
439 $reCAPTCHA = $integrationDetails;
440 $reCAPTCHAVersion = 'v3';
441 }
442 }
443 }
444 }
445 }
446
447 if ($captchaV3Settings && !empty($reCAPTCHA->siteKey)) {
448 // DANGER: no matter what, DONT CHANGE THE SCRIPT ID OF THIS SCRIPT
449 $scriptId = BITFORMS_PREFIX . 'recaptcha';
450 wp_enqueue_script($scriptId, "https://www.google.com/recaptcha/api.js?render={$reCAPTCHA->siteKey}");
451 }
452
453 $configs = [
454 'bf_separator' => BITFORMS_BF_SEPARATOR,
455 ];
456
457 // check if fields has paypal or razorpay
458 $paymentFields = ['paypal', 'razorpay', 'stripe'];
459 $paymentFieldData = [];
460 foreach ($fields as $key => $field) {
461 if (in_array($field->typ, $paymentFields)) {
462 $paymentFieldData[$key] = $field;
463 }
464 }
465
466 if (!empty($paymentFieldData)) {
467 $integrationHandler = new IntegrationHandler(0);
468 foreach ($paymentFieldData as $fldKey => $fldData) {
469 $paymentIntegration = $integrationHandler->getAIntegration($fldData->payIntegID);
470 if (is_wp_error($paymentIntegration)) {
471 continue;
472 }
473 if ('paypal' === $fldData->typ) {
474 $integrationDetails = json_decode($paymentIntegration[0]->integration_details);
475 $clientID = $integrationDetails->clientID;
476 $fields->{$fldKey}->clientId = $clientID;
477 } elseif ('razorpay' === $fldData->typ) {
478 $integrationDetails = json_decode($paymentIntegration[0]->integration_details);
479 $clientID = $integrationDetails->apiKey;
480 $fields->{$fldKey}->clientId = $clientID;
481 } elseif ('stripe' === $fldData->typ) {
482 $integrationDetails = json_decode($paymentIntegration[0]->integration_details);
483 $publishableKey = $integrationDetails->publishableKey;
484 $fields->{$fldKey}->publishableKey = $publishableKey;
485 }
486 }
487 }
488
489 $bitFormFrontArr = [
490 'ajaxURL' => admin_url('admin-ajax.php'),
491 'nonce' => $nonce,
492 'version' => BITFORMS_VERSION,
493 'layout' => $layout,
494 'nestedLayout' => $nestedLayout,
495 'fields' => $fields,
496 'buttons' => $buttons,
497 'fieldsKey' => $fieldsKey,
498 'file' => $file,
499 'configs' => $configs,
500 'formId' => $formID,
501 'appID' => "bitforms_{$formID}",
502 'GCLID' => $FrontendFormManager->isGCLIDEnabled(),
503 'assetUrl' => BITFORMS_ASSET_URI,
504 'onfieldCondition' => !empty($workFlowreturnedOnUserInput['onfield_input_conditions']) ? $workFlowreturnedOnUserInput['onfield_input_conditions'] : false,
505 'smartTags' => SmartTags::smartTags(SmartTags::getPostUserData()),
506 'paymentCallbackUrl' => get_rest_url() . 'bitform/v1/payments/razorpay',
507 'gRecaptchaSiteKey' => !empty($reCAPTCHA->siteKey) ? $reCAPTCHA->siteKey : null,
508 'gRecaptchaVersion' => !empty($reCAPTCHAVersion) ? $reCAPTCHAVersion : null,
509 'turnstileSiteKey' => !empty($turnstileSiteKey) ? $turnstileSiteKey : null
510 ];
511
512 if ($entryId) {
513 $bitFormFrontArr['entryId'] = $entryId;
514 }
515
516 if (isset($additional->enabled->validateFocusLost)) {
517 $bitFormFrontArr['validateFocusLost'] = true;
518 }
519
520 if (!empty($isAbandoned)) {
521 $bitFormFrontArr['oldValues'] = $this->getFieldsValue($formID, $isAbandoned);
522 if (empty($entryId)) {
523 $bitFormFrontArr['entryId'] = $isAbandoned;
524 }
525 }
526
527 $formInfo = $FrontendFormManager->getFormInfo();
528 if (is_array($layout) && count($layout) > 1) {
529 $multiStepSettings = isset($formInfo->multiStepSettings) ? $formInfo->multiStepSettings : null;
530 $newTempSettings = (object) [
531 'validateOnStepChange' => isset($multiStepSettings->validateOnStepChange) ? $multiStepSettings->validateOnStepChange : false,
532 'maintainStepHistory' => isset($multiStepSettings->maintainStepHistory) ? $multiStepSettings->maintainStepHistory : false,
533 'saveProgress' => isset($multiStepSettings->saveProgress) ? $multiStepSettings->saveProgress : false,
534 'showPercentage' => isset($multiStepSettings->progressSettings->showPercentage) ? $multiStepSettings->progressSettings->showPercentage : false,
535 ];
536 $bitFormFrontArr['formInfo'] = (object) [
537 'multiStepSettings' => $newTempSettings
538 ];
539 }
540
541 if (Helpers::property_exists_nested($formInfo, 'conversationalSettings->enable', true)) {
542 if (!isset($bitFormFrontArr['formInfo'])) {
543 $bitFormFrontArr['formInfo'] = new \stdClass();
544 }
545 $bitFormFrontArr['formInfo']->conversationalSettings = $formInfo->conversationalSettings;
546 }
547
548 $formAbandonmentSettings = $FrontendFormManager->getFormAbandonmentSettings();
549 if (Helpers::property_exists_nested($formAbandonmentSettings, 'active', true)) {
550 $bitFormFrontArr['formSettings'] = (object)[
551 'formAbandonment' => $formAbandonmentSettings
552 ];
553 }
554
555 $bitFormsFront = apply_filters(
556 'bitforms_localized_script',
557 $bitFormFrontArr
558 );
559
560 $layout = wp_json_encode($layout);
561 $buttons = wp_json_encode($buttons);
562 $frontArr = wp_json_encode($bitFormFrontArr);
563
564 $bfGlobals = <<<BFGLOBALS
565 if(!window.bf_globals) {
566 window.bf_globals = {}
567 } if(!window.bf_globals.{$FormIdentifier}) {
568 window.bf_globals.{$FormIdentifier} = {}
569 }
570 if(document.getElementById('{$FormIdentifier}')) {
571 window.bf_globals.{$FormIdentifier} = {...window.bf_globals.{$FormIdentifier}, ...{$frontArr}};
572 }
573 BFGLOBALS;
574
575 if ('conversational' === $formType
576 && isset($formContent->formInfo->conversationalSettings->enable)
577 && $formContent->formInfo->conversationalSettings->enable) {
578 $html = $FrontendFormManager->conversationalFormView($fields, $file, $errorMessages);
579 } else {
580 $html = $FrontendFormManager->formView($fields, $file, $errorMessages);
581 }
582
583 // if form preview then return html otherwise echo with output buffer
584 if ($formPreview) {
585 ob_clean();
586 $formViewObject = new \stdClass();
587 $formViewObject->html = $html;
588 $formViewObject->font = $font;
589 $formViewObject->bfGlobals = $bfGlobals;
590 return $formViewObject;
591 }
592 $html .= <<<BFGLOBALSSCRIPT
593 <script id="bit-form-bf-globals-{$FormIdentifier}">{$bfGlobals}</script>
594 BFGLOBALSSCRIPT;
595 echo trim($html);
596 return ob_get_clean();
597 }
598
599 private function isExist($formID)
600 {
601 $formModel = new FormModel();
602 $form = $formModel->get(
603 [
604 'id'
605 ],
606 [
607 'id' => $formID,
608 ]
609 );
610 if (!is_wp_error($form)) {
611 return true;
612 }
613 return false;
614 }
615
616 private function getFieldsValue($formID, $entryID)
617 {
618 $formEntryModel = new FormEntryMetaModel();
619 $metaValues = $formEntryModel->get(
620 [
621 'meta_key',
622 'meta_value'
623 ],
624 [
625 'bitforms_form_entry_id' => $entryID,
626 ]
627 );
628 $fldsData = (object) [];
629 if (!is_wp_error($metaValues)) {
630 foreach ($metaValues as $metaValue) {
631 $metaKey = $metaValue->meta_key;
632 $metaVal = $metaValue->meta_value;
633 // if meta value is array then convert to string
634 if (preg_match('/^\[.*\]$/', $metaVal)) {
635 $metaVal = json_decode($metaVal);
636 //check is it array of objects
637 if (is_array($metaVal) && is_object($metaVal[0])) {
638 $metaVal = $metaValue->meta_value;
639 } else {
640 $metaVal = implode(BITFORMS_BF_SEPARATOR, $metaVal);
641 }
642 }
643 if (!isset($fldsData->{$metaKey})) {
644 $fldsData->{$metaKey} = '';
645 }
646 $fldsData->{$metaKey} = $metaVal;
647 }
648 }
649
650 return $fldsData;
651 }
652
653 public function setFieldsValue($fields, $formID, $entryID)
654 {
655 $formEntryModel = new FormEntryMetaModel();
656 $metaValues = $formEntryModel->get(
657 [
658 'meta_key',
659 'meta_value'
660 ],
661 [
662 'bitforms_form_entry_id' => $entryID,
663 ]
664 );
665 if (!is_wp_error($metaValues)) {
666 foreach ($metaValues as $metaValue) {
667 $metaKey = $metaValue->meta_key;
668 $metaVal = $metaValue->meta_value;
669 // if meta value is array then convert to string
670 if (preg_match('/^\[.*\]$/', $metaVal)) {
671 $metaVal = json_decode($metaVal);
672 //check is it array of objects
673 if (is_array($metaVal) && is_object($metaVal[0])) {
674 $metaVal = $metaValue->meta_value;
675 } else {
676 $metaVal = implode(BITFORMS_BF_SEPARATOR, $metaVal);
677 }
678 }
679 if (property_exists($fields, $metaKey)) {
680 $fields->{$metaKey}->val = $metaVal;
681 if ('file-up' === $fields->{$metaKey}->typ || 'advanced-file-up' === $fields->{$metaKey}->typ) {
682 $fields->{$metaKey}->val = $metaValue->meta_value;
683 $fields->{$metaKey}->config->oldFiles = $metaValue->meta_value;
684 $urlQuery = wp_parse_url(FileDownloadProvider::getBaseDownloadURL(), PHP_URL_QUERY);
685 $baseDLURL = FileDownloadProvider::getBaseDownloadURL();
686 $baseDLURL = empty($urlQuery) ? $baseDLURL . '?' : $baseDLURL . '&';
687 $fields->{$metaKey}->config->baseDLURL = $baseDLURL . "formID={$formID}&entryID={$entryID}";
688 }
689 }
690 }
691 }
692 return $fields;
693 }
694
695 public function loadAssets($formID = 0, $fromType = 'classic')
696 {
697 $bfUniqFormIds = FrontendHelpers::getAllFormIdsInPage();
698 $isPageBuilder = FrontendHelpers::$isPageBuilder;
699 $bfMultipleFormsExists = $isPageBuilder ? true : count($bfUniqFormIds) > 1;
700
701 if (!empty($formID)) {
702 $formIds = [$formID];
703 } else {
704 $formIds = $bfUniqFormIds;
705 }
706 foreach ($formIds as $formID) {
707 global $bitform_dequeued_styles;
708 if (is_array($bitform_dequeued_styles) && in_array($formID, $bitform_dequeued_styles)) {
709 continue;
710 }
711 if ($bfMultipleFormsExists) {
712 $newFormId = $formID . '-formid';
713 } else {
714 $newFormId = $formID;
715 }
716 $formUpdateVersion = get_option('bit-form_form_update_version');
717 if (!wp_style_is('bitform-style-' . $newFormId) && is_readable(BITFORMS_CONTENT_DIR . '/form-styles/bitform-' . $newFormId . '.css')) {
718 wp_enqueue_style(
719 'bitform-style-' . $newFormId,
720 BITFORMS_UPLOAD_BASE_URL . "/form-styles/bitform-{$newFormId}.css",
721 [],
722 $formUpdateVersion
723 );
724 if ($isPageBuilder) {
725 $formStyle = file_get_contents(BITFORMS_CONTENT_DIR . '/form-styles/bitform-' . $newFormId . '.css');
726 echo sprintf("<style id='bitform-style-{$newFormId}'>%s</style>", $formStyle);
727 }
728 }
729 if (!wp_style_is('bitform-style-custom-' . $formID) && is_readable(BITFORMS_CONTENT_DIR . '/form-styles/bitform-custom-' . $formID . '.css')) {
730 wp_enqueue_style(
731 'bitform-style-custom-' . $formID,
732 BITFORMS_UPLOAD_BASE_URL . "/form-styles/bitform-custom-{$formID}.css",
733 [],
734 $formUpdateVersion
735 );
736 if ($isPageBuilder) {
737 $formStyle = file_get_contents(BITFORMS_CONTENT_DIR . '/form-styles/bitform-custom-' . $formID . '.css');
738 echo sprintf("<style id='bitform-style-custom-{$formID}'>%s</style>", $formStyle);
739 }
740 }
741 // load conversational form css
742 if ('conversational' === $fromType) {
743 if (!wp_style_is('bitform-conversational-style-' . $formID) &&
744 is_readable(BITFORMS_CONTENT_DIR . "/form-styles/bitform-conversational-{$formID}.css")) {
745 wp_enqueue_style(
746 'bitform-conversational-style',
747 BITFORMS_UPLOAD_BASE_URL . "/form-styles/bitform-conversational-{$formID}.css",
748 [],
749 $formUpdateVersion
750 );
751 }
752 }
753 }
754 }
755 }
756