PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 3.3.1
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v3.3.1
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/Admin/Form/FrontEndScriptGenerator.php +157 -201 2.10.03.3.1 View file →
@@ -1,19 +1,14 @@
1 1 <?php
2 2
3 3 namespace BitCode\BitForm\Admin\Form;
4 4
5 -use BitCode\BitForm\Admin\Form\InitJs\Paypal;
6 -use BitCode\BitForm\Admin\Form\InitJs\Razorpay;
7 -use BitCode\BitForm\Admin\Form\InitJs\Recaptcha;
8 -use BitCode\BitForm\Admin\Form\InitJs\RecaptchaV3;
9 -use BitCode\BitForm\Admin\Form\InitJs\ScriptLoader;
10 -use BitCode\BitForm\Admin\Form\InitJs\Stripe;
11 -use BitCode\BitForm\Admin\Form\InitJs\Turnstile;
5 +if (!defined('ABSPATH')) {
6 + exit;
7 +}
8 +
9 +use BitCode\BitForm\Core\Util\FileHandler;
12 10 use BitCode\BitForm\Core\Util\Log;
13 -use BitCode\BitForm\Core\Util\Utilities;
14 -use BitCode\BitForm\Core\WorkFlow\WorkFlowHandler;
15 -use BitCode\BitFormPro\Admin\FormSettings\FormAbandonment;
16 11 use WP_Error;
17 12
18 13 class FrontEndScriptGenerator
19 14 {
@@ -35,30 +30,36 @@
35 30
36 31 private static function generateBfGlobalObjJS($contentIds = [])
37 32 {
38 33 $contentidArray = wp_json_encode($contentIds);
39 - return <<<GLOBALOBJ
40 - if(!window.bf_globals){ window.bf_globals = {};}
41 - $contentidArray.forEach(function(contentId){
42 - const form = document.getElementById(contentId);
43 - if(!form){
44 - delete window.bf_globals[contentId];
45 - return;
46 - }
47 - if(!window.bf_globals[contentId]){
48 - window.bf_globals[contentId] = {inits: {}, contentId: contentId};
49 - }else{
50 - window.bf_globals[contentId].inits = {};
51 - window.bf_globals[contentId].contentId = contentId;
34 + return ' if(!window.bf_globals){ window.bf_globals = {};}
35 + (function(){
36 + var bfSetupGlobals = function(){
37 + ' . $contentidArray . '.forEach(function(contentId){
38 + const form = document.getElementById(contentId);
39 + if(!form){
40 + delete window.bf_globals[contentId];
41 + return;
42 + }
43 + if(!window.bf_globals[contentId]){
44 + window.bf_globals[contentId] = {inits: {}, contentId: contentId};
45 + }else{
46 + if(!window.bf_globals[contentId].inits) window.bf_globals[contentId].inits = {};
47 + window.bf_globals[contentId].contentId = contentId;
48 + }
49 + });
50 + };
51 + if(document.readyState === "loading"){
52 + document.addEventListener("DOMContentLoaded", bfSetupGlobals, { once: true });
53 + } else {
54 + bfSetupGlobals();
52 55 }
53 -
54 - });
55 -GLOBALOBJ;
56 + })();';
56 57 }
57 58
58 59 private static function isValidationNeeded($fldData)
59 60 {
60 - $validationsToCheck = ['valid->req', 'valid->regexr', 'mn', 'mx', 'opt', 'err->invalid->show'];
61 + $validationsToCheck = ['valid->req', 'valid->regexr', 'mn', 'mx', 'opt', 'err->invalid->show', 'err->notVerified->show'];
61 62 foreach ($validationsToCheck as $property) {
62 63 $needValidation = Helpers::property_exists_nested($fldData, $property);
63 64 if ($needValidation) {
64 65 return true;
@@ -92,8 +93,11 @@
92 93
93 94 // for hidden Field when cache plugin on
94 95 $this->jsHiddenFieldScript();
95 96
97 + // for recaptcha v3 (form-level setting)
98 + $this->jsRecaptchaV3Scripts();
99 +
96 100 // for form abandonment scripts
97 101 $this->jsFormAbandonmentScripts();
98 102
99 103 // multi step form scripts
@@ -106,8 +110,10 @@
106 110 $this->appendJs($this->getScript(), $postId, $preview);
107 111 $this->appendJs($this->generateFieldConfigsJs($contentIds), $postId, $preview);
108 112 // init all js events and functions at last
109 113 $this->appendJs(self::getFileFromAssetsJs('bitform-init.min.js'), $postId, $preview);
114 + // picks up forms injected after load (AJAX, popups, lazy content)
115 + $this->appendJs(self::getFileFromAssetsJs('bitform-observer.min.js'), $postId, $preview);
110 116 if (defined('ELEMENTOR_PRO_VERSION')) {
111 117 $this->appendJs(self::getFileFromAssetsJs('bitform-elementor.min.js'), $postId, $preview);
112 118 }
113 119
@@ -143,55 +149,24 @@
143 149 }
144 150
145 151 private function jsFormAbandonmentScripts()
146 152 {
147 - if (!Utilities::isPro() || !class_exists('\BitCode\BitFormPro\Admin\FormSettings\FormAbandonment')) {
153 + /**
154 + * Add-ons can inject required script files here.
155 + *
156 + * @param array $files Array of file arrays: ['priority' => int, 'filename' => string]
157 + * @param array $formContents
158 + * @param array $fields
159 + */
160 + $files = apply_filters('bitform_form_abandonment_script_files', [], $this->_formContents, $this->_fields);
161 + if (empty($files) || !is_array($files)) {
148 162 return;
149 163 }
150 - // check if any of the form has form abandonment enabled
151 - $allFiles = [];
152 - foreach ($this->_formContents as $formContent) {
153 - $formAbandonmentSettings = FormAbandonment::getFormAbandonmentSettings($formContent->formId);
154 - if (!empty($formAbandonmentSettings->saveFormDraft)) {
155 - $neededFiles = ScriptFilePriorityManager::formAbandonmentNeededFiles('autoSave');
156 - $allFiles = array_merge($allFiles, $neededFiles);
157 - break;
164 + foreach ($files as $jsFile) {
165 + if (!empty($jsFile['filename']) && !empty($jsFile['priority'])) {
166 + $this->addScriptInLoadedScriptsList($jsFile);
158 167 }
159 -
160 - $workflowHandler = new WorkFlowHandler($formContent->formId);
161 - $allWorkflows = $workflowHandler->getAllworkFlow();
162 - foreach ($allWorkflows as $workflow) {
163 - foreach ($workflow['conditions'] as $cond) {
164 - if (!empty($cond->actions) && !empty($cond->actions->fields)) {
165 - foreach ($cond->actions->fields as $fldAction) {
166 - if (empty($fldAction->field) || empty($fldAction->action)) {
167 - continue;
168 - }
169 - if ('_bf_form' === $fldAction->field && 'save_draft' === $fldAction->action) {
170 - $neededFiles = ScriptFilePriorityManager::formAbandonmentNeededFiles();
171 - $allFiles = array_merge($allFiles, $neededFiles);
172 - }
173 - }
174 - }
175 - }
176 - }
177 168 }
178 - if (isset($this->_fields['button'])) {
179 - foreach ($this->_fields['button'] as $button) {
180 - if ('save-draft' === $button['field']->btnTyp) {
181 - $neededFiles = ScriptFilePriorityManager::formAbandonmentNeededFiles();
182 - $allFiles = array_merge($allFiles, $neededFiles);
183 - break;
184 - }
185 - }
186 - }
187 - //
188 - if (empty($allFiles)) {
189 - return;
190 - }
191 - foreach ($allFiles as $jsFile) {
192 - $this->addScriptInLoadedScriptsList($jsFile);
193 - }
194 169 }
195 170
196 171 private function appendJs($script, $postId, $previewMode, $mode = 'a')
197 172 {
@@ -219,22 +194,12 @@
219 194
220 195 $script = '';
221 196 foreach ($this->_loadedScriptsList as $scriptFileArr) {
222 197 $fileNam = $scriptFileArr['filename'];
223 - if (!isset($scriptFileArr['scriptTyp']) || 'script' === $scriptFileArr['scriptTyp']) {
224 - if (self::getFileFromAssetsJs($fileNam)) {
225 - $script .= self::getFileFromAssetsJs($fileNam);
226 - continue;
227 - }
228 - continue;
198 + $fileContent = self::getFileFromAssetsJs($fileNam);
199 + if ($fileContent) {
200 + $script .= $fileContent;
229 201 }
230 - if ('custom' === $scriptFileArr['scriptTyp']) {
231 - $fileInstance = $scriptFileArr['source'] . $fileNam;
232 - if (!class_exists($fileInstance)) {
233 - continue;
234 - } // when class not found, skip load script
235 - $script .= $fileInstance::init($scriptFileArr['fk'], $scriptFileArr['field'], $scriptFileArr['contentId']);
236 - }
237 202 }
238 203 return $script;
239 204 }
240 205
@@ -242,8 +207,12 @@
242 207 {
243 208 foreach ($this->_fields as $flds) {
244 209 foreach ($flds as $fld) {
245 210 $fldData = $fld['field'];
211 + // Corrupt/partial form JSON can produce a null field or one without typ.
212 + if (!is_object($fldData)) {
213 + continue;
214 + }
246 215 // for validation js files
247 216 if (self::isValidationNeeded($fldData)) {
248 217 $validation = $this->_validationJsFilesNeeded['validation'];
249 218 $this->addScriptInLoadedScriptsList($validation);
@@ -263,18 +232,30 @@
263 232
264 233 $validationScriptFileMapping = ScriptFilePriorityManager::validationScriptFileMapping($fldData->typ);
265 234 if ($validationScriptFileMapping) {
266 235 foreach ($validationScriptFileMapping as $key => $value) {
267 - foreach ($value['paths'] as $path) {
236 + $paths = $value['paths'] ?? [];
237 + $hasMatchingPath = false;
238 + foreach ($paths as $path) {
268 239 if (Helpers::property_exists_nested($fldData, $path)) {
269 - $file = $this->_validationJsFilesNeeded[$key];
270 - $this->addScriptInLoadedScriptsList($file);
240 + $hasMatchingPath = true;
241 + break; // one match is enough
271 242 }
272 243 }
273 - if (isset($value['dependencies'])) {
274 - foreach ($value['dependencies'] as $dependency) {
275 - $dependencyFile = $this->_validationJsFilesNeeded[$dependency];
276 - $this->addScriptInLoadedScriptsList($dependencyFile);
244 +
245 + if (!$hasMatchingPath) {
246 + continue;
247 + }
248 +
249 + // Add the main script once
250 + if (!empty($this->_validationJsFilesNeeded[$key])) {
251 + $this->addScriptInLoadedScriptsList($this->_validationJsFilesNeeded[$key]);
252 + }
253 +
254 + // Add dependencies once each
255 + foreach (($value['dependencies'] ?? []) as $dep) {
256 + if (!empty($this->_validationJsFilesNeeded[$dep])) {
257 + $this->addScriptInLoadedScriptsList($this->_validationJsFilesNeeded[$dep]);
277 258 }
278 259 }
279 260 }
280 261 }
@@ -283,8 +264,9 @@
283 264 }
284 265
285 266 private function jsFieldsNeededFile()
286 267 {
268 + $filePondPluginList = apply_filters('bitform_filepond_plugins_list', []);
287 269 foreach ($this->_fields as $typ => $flds) {
288 270 if (!array_key_exists($typ, $this->_jsFilesNeeded)) {
289 271 continue;
290 272 }
@@ -294,26 +276,30 @@
294 276 if ('advanced-file-up' === $typ) {
295 277 $configs = $fld['field']->config;
296 278 foreach ($configs as $configKey => $config) {
297 279 if ($configs->$configKey) {
298 - $filepondPlugin = ScriptFilePriorityManager::filePondPlugins($configKey);
299 - if ($filepondPlugin) {
300 - $this->addScriptInLoadedScriptsList($filepondPlugin);
280 + if (array_key_exists($configKey, $filePondPluginList)) {
281 + $this->addScriptInLoadedScriptsList($filePondPluginList[$configKey]);
301 282 }
302 283 }
303 284 }
304 285 }
305 286 foreach ($fldScriptArr as $scriptFile) {
306 - if (!isset($scriptFile['scriptTyp'])) {
307 - $this->addScriptInLoadedScriptsList($scriptFile);
287 + if (isset($scriptFile['paths']) && is_array($scriptFile['paths'])) {
288 + $pathMatched = false;
289 + foreach ($scriptFile['paths'] as $path) {
290 + if (Helpers::property_exists_nested($fld['field'], $path)) {
291 + $pathMatched = true;
292 + break;
293 + }
294 + }
295 + if (!$pathMatched) {
296 + continue;
297 + }
298 + } elseif (isset($scriptFile['path']) && !Helpers::property_exists_nested($fld['field'], $scriptFile['path'])) {
308 299 continue;
309 300 }
310 - if ('custom' === $scriptFile['scriptTyp'] && Helpers::property_exists_nested($fld['field'], $scriptFile['path'], true)) {
311 - $scriptFile['field'] = $fld['field'];
312 - $scriptFile['fk'] = $fld['fk'];
313 - $scriptFile['contentId'] = $fld['contentId'];
314 - $this->addScriptInLoadedScriptsList($scriptFile);
315 - }
301 + $this->addScriptInLoadedScriptsList($scriptFile);
316 302 }
317 303 }
318 304 }
319 305 }
@@ -319,13 +305,15 @@
319 305 }
320 306
321 307 private static function getCustomJsCodes($contentIds = [])
322 308 {
323 - $script = 'let bfContentId = "", bfVars= "";';
309 + $script = 'let bfContentId = "", bfSlNo = "1", bfVars= "";';
324 310 foreach ($contentIds as $contentId) {
325 - $jsCode = self::getCustomCodes(explode('_', $contentId)[1])['JavaScript'];
311 + $contentIdArr = explode('_', $contentId);
312 + $jsCode = self::getCustomCodes($contentIdArr[1])['JavaScript'];
313 + $bfSlNo = array_key_exists(3, $contentIdArr) ? $contentIdArr[3] : '1';
326 314 if (!empty($jsCode)) {
327 - $script .= " if(bfSelect('#{$contentId}')){ bfContentId = '{$contentId}'; bfVars = window.bf_globals.{$contentId}.smartTags; {$jsCode}}";
315 + $script .= " if(bfSelect('#{$contentId}')){ bfContentId = '{$contentId}'; bfSlNo = '{$bfSlNo}'; bfVars = window.bf_globals.{$contentId}.smartTags; {$jsCode}}";
328 316 }
329 317 }
330 318
331 319 return $script;
@@ -355,9 +343,10 @@
355 343 {
356 344 // for js file
357 345 $path = 'form-scripts';
358 346 $fileName = "bitform-custom-$formId.js";
359 - self::customCodeFileSaveOrDelete($customCodes->JavaScript, $path, $fileName);
347 + $filteredJs = Helpers::removeJsSingleLineComments($customCodes->JavaScript);
348 + self::customCodeFileSaveOrDelete($filteredJs, $path, $fileName);
360 349
361 350 // for css file
362 351 $path = 'form-styles';
363 352 $fileName = "bitform-custom-$formId.css";
@@ -372,11 +361,9 @@
372 361 Helpers::saveFile($path, $fileName, $script, 'w');
373 362 } else {
374 363 $uploadPath = "$path/$fileName";
375 364 $uploadFilePath = Helpers::generatePathDirOrFile($uploadPath);
376 - if (file_exists($uploadFilePath)) {
377 - unlink($uploadFilePath);
378 - }
365 + FileHandler::deleteIsFileExists($uploadFilePath);
379 366 }
380 367 return true;
381 368 }
382 369
@@ -392,26 +379,31 @@
392 379 return $customCodes;
393 380 }
394 381
395 382 private $fldContainersByType = [
396 - 'select' => '.__$fk__-dpd-fld-wrp',
397 - 'country' => '.__$fk__-country-fld-wrp',
398 - 'currency' => '.__$fk__-currency-fld-wrp',
399 - 'phone-number' => '.__$fk__-phone-fld-wrp',
400 - 'file-up' => '.__$fk__-file-up-wrpr',
401 - 'advanced-file-up' => '#filepond-__$fk__-container',
402 - 'paypal' => '.__$fk__-paypal-wrp',
403 - 'razorpay' => '.__$fk__-razorpay-wrp',
404 - 'recaptcha' => '.__$fk__-recaptcha-wrp',
405 - 'stripe' => '.__$fk__-stripe-fld',
406 - 'repeater' => '.__$fk__-rpt-fld-wrp',
407 - 'signature' => '.__$fk__-inp-fld-wrp',
408 - 'rating' => '.__$fk__-inp-fld-wrp',
383 + 'address' => '.__$fk__-parent-fld-wrp',
384 + 'select' => '.__$fk__-dpd-fld-wrp',
385 + 'country' => '.__$fk__-country-fld-wrp',
386 + 'currency' => '.__$fk__-currency-fld-wrp',
387 + 'phone-number' => '.__$fk__-phone-fld-wrp',
388 + 'file-up' => '.__$fk__-file-up-wrpr',
389 + 'advanced-file-up' => '#filepond-__$fk__-container',
390 + 'paypal' => '.__$fk__-paypal-wrp',
391 + 'razorpay' => '.__$fk__-razorpay-wrp',
392 + 'recaptcha' => '.__$fk__-recaptcha-wrp',
393 + 'stripe' => '.__$fk__-stripe-fld',
394 + 'mollie' => '.__$fk__-mollie-wrp',
395 + 'repeater' => '.__$fk__-rpt-fld-wrp',
396 + 'signature' => '.__$fk__-inp-fld-wrp',
397 + 'rating' => '.__$fk__-inp-fld-wrp',
398 + 'email-otp' => '.__$fk__-inp-fld-wrp',
399 + 'hcaptcha' => '.__$fk__-h-captcha-wrp',
400 + 'advanced-datetime' => '.__$fk__-advanced-datetime',
409 401 ];
410 402
411 403 private function generateFieldConfigsJs()
412 404 {
413 - $customFlds = ['select', 'country', 'currency', 'phone-number', 'file-up', 'advanced-file-up', 'paypal', 'razorpay', 'stripe', 'recaptcha', 'repeater', 'signature', 'rating', 'turnstile'];
405 + $customFlds = ['address', 'select', 'country', 'currency', 'phone-number', 'file-up', 'advanced-file-up', 'paypal', 'razorpay', 'stripe', 'mollie', 'recaptcha', 'repeater', 'signature', 'rating', 'turnstile', 'hcaptcha', 'advanced-datetime', 'email-otp'];
414 406 $allFieldTypes = array_keys($this->_fields);
415 407 $customFldsInForms = array_intersect($allFieldTypes, $customFlds);
416 408 $formContents = $this->_formContents;
417 409 $recaptchaV3Enabled = false;
@@ -433,10 +425,10 @@
433 425 }
434 426
435 427 $customFldConfigPaths = [];
436 428
429 + $allConfs = ScriptFilePriorityManager::getAllFldConfs();
437 430 foreach ($customFldsInForms as $customFldTyp) {
438 - $allConfs = ScriptFilePriorityManager::getAllFldConfs();
439 431 if (isset($allConfs[$customFldTyp])) {
440 432 $customFldConfigPaths[$customFldTyp] = $allConfs[$customFldTyp];
441 433 } else {
442 434 $customFldConfigPaths[$customFldTyp] = (object) [];
@@ -445,89 +437,45 @@
445 437
446 438 $customFldConfigPaths = wp_json_encode($customFldConfigPaths);
447 439 $containers = wp_json_encode($containers);
448 440
449 - $scriptLoaderFields = ['paypal', 'razorpay', 'stripe', 'recaptcha', 'turnstile'];
450 - $scriptLoadedNeeded = array_intersect($scriptLoaderFields, $customFldsInForms) || $recaptchaV3Enabled;
451 - if ($scriptLoadedNeeded) {
452 - $scriptLoaderJs = ScriptLoader::init();
453 - } else {
454 - $scriptLoaderJs = '';
455 - }
456 -
457 - if (in_array('paypal', $customFldsInForms)) {
458 - $paypalInitJs = Paypal::init();
459 - } else {
460 - $paypalInitJs = '';
461 - }
462 -
463 - if (in_array('razorpay', $customFldsInForms)) {
464 - $razorpayInitJs = Razorpay::init();
465 - } else {
466 - $razorpayInitJs = '';
467 - }
468 -
469 - if (in_array('stripe', $customFldsInForms)) {
470 - $stripeInitJs = Stripe::init();
471 - } else {
472 - $stripeInitJs = '';
473 - }
474 -
475 - if (in_array('recaptcha', $customFldsInForms)) {
476 - $recaptchaInitJs = Recaptcha::init();
477 - } else {
478 - $recaptchaInitJs = '';
479 - }
480 -
481 - if (in_array('turnstile', $customFldsInForms)) {
482 - $turnstileInitJs = Turnstile::init();
483 - } else {
484 - $turnstileInitJs = '';
485 - }
486 -
487 - if ($recaptchaV3Enabled) {
488 - $recaptchaV3InitJs = RecaptchaV3::init();
489 - } else {
490 - $recaptchaV3InitJs = '';
491 - }
492 -
493 - $script = <<<FIELDCONFIGJS
494 - const customFldConfigPaths = $customFldConfigPaths;
495 - const fldContainers = $containers;
441 + $script = ' const customFldConfigPaths = ' . $customFldConfigPaths . ';
442 + const fldContainers = ' . $containers . ';
496 443
497 - $scriptLoaderJs;
498 -
499 444 function initAllCustomFlds (formContentId = null) {
500 445 const allContendIds = formContentId ? [formContentId] : Object.keys(bf_globals);
501 446 allContendIds.forEach((contentId) => {
502 447 const contentData = bf_globals[contentId];
503 - const flds = bf_globals[contentId].fields;
448 + if(!contentData?.inits) contentData.inits = {};
449 + const flds = bf_globals[contentId]?.fields || {};
504 450 const fldKeys = Object.keys(flds).reverse();
505 451 fldKeys.forEach((fldKey) => {
506 452 const fldData = flds[fldKey];
507 453 const fldType = fldData.typ;
508 - if(fldType === 'paypal') {
509 - $paypalInitJs;
510 - } else if(fldType === 'razorpay') {
511 - $razorpayInitJs;
512 - } else if(fldType === 'recaptcha') {
513 - $recaptchaInitJs;
514 - } else if(fldType === 'turnstile') {
515 - $turnstileInitJs;
516 - } else if(fldType === 'stripe') {
517 - $stripeInitJs;
454 + if(fldType === \'paypal\') {
455 + initPaypalFld(contentId, fldKey, fldData, fldType);
456 + } else if(fldType === \'razorpay\') {
457 + initRazorpayFld(contentId, fldKey, fldType);
458 + } else if(fldType === \'recaptcha\') {
459 + initRecaptchaFld(contentId, fldKey, fldType);
460 + } else if(fldType === \'turnstile\') {
461 + initTurnstileFld(contentId, fldKey);
462 + } else if(fldType === \'hcaptcha\') {
463 + initHCaptchaFld(contentId, fldKey, fldType);
464 + } else if(fldType === \'stripe\' || fldType === \'mollie\') {
465 + initStripeFld(contentId, fldKey, fldType);
518 466 } else if (customFldConfigPaths[fldType]) {
519 467 contentData.inits[fldKey] = getFldInstance(contentId, fldKey, fldType);
520 468 }
521 469 });
522 - if(contentData.gRecaptchaVersion === 'v3' && contentData.gRecaptchaSiteKey){
523 - $recaptchaV3InitJs;
470 + if(contentData.gRecaptchaVersion === \'v3\' && contentData.gRecaptchaSiteKey){
471 + initRecaptchaV3Fld(contentId, contentData);
524 472 }
525 473 });
526 474 };
527 - function getFldInstance(contentId, fldKey, fldTyp, nestedSelector = '') {
528 - const fldClass = this['bit_'+fldTyp.replace(/-/g, '_')+'_field'];
529 - const selector = '#form-'+contentId+' '+nestedSelector+fldContainers[fldTyp].replace("__\$fk__", fldKey);
475 + function getFldInstance(contentId, fldKey, fldTyp, nestedSelector = \'\') {
476 + const fldClass = this[\'bit_\'+fldTyp.replace(/-/g, \'_\')+\'_field\'];
477 + const selector = \'#form-\'+contentId+\' \'+nestedSelector+fldContainers[fldTyp].replace("__$fk__", fldKey);
530 478 if(!fldClass || !bfSelect(selector)) return;
531 479 return new fldClass(selector, getFldConf(contentId, fldKey, fldTyp));
532 480 };
533 481 function getFldConf(contentId, fieldKey, fldTyp) {
@@ -548,13 +496,13 @@
548 496 } else {
549 497 value = getDataFromNestedPath(fldData, fldPath.path);
550 498 }
551 499 }
552 - if (!value && fldPath.val) {
500 + if (!value && "val" in fldPath) {
553 501 value = fldPath.val;
554 - if(typeof value === 'string') {
502 + if(typeof value === \'string\') {
555 503 Object.entries(varData).forEach(([key, val]) => {
556 - value = value.replace("__\$"+key+"__", val);
504 + value = value.replace("__$"+key+"__", val);
557 505 });
558 506 }
559 507 }
560 508 fldConf = setDataToNestedPath(fldConf, confPath, value);
@@ -580,10 +528,9 @@
580 528 current = current[k];
581 529 });
582 530 current[lastKey] = value;
583 531 return current;
584 - }
585 -FIELDCONFIGJS;
532 + }';
586 533
587 534 return $script;
588 535 }
589 536
@@ -604,8 +551,10 @@
604 551 $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['conditionalLogic'];
605 552 $this->addScriptInLoadedScriptsList($fileArr);
606 553 $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['resetPlaceholders'];
607 554 $this->addScriptInLoadedScriptsList($fileArr);
555 + $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['bfResetDefaultValue'];
556 + $this->addScriptInLoadedScriptsList($fileArr);
608 557 $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['validateFocusLost'];
609 558 $this->addScriptInLoadedScriptsList($fileArr);
610 559 $fileArr = ScriptFilePriorityManager::frontendScriptFile()['observeElm'];
611 560 $this->addScriptInLoadedScriptsList($fileArr);
@@ -619,9 +568,15 @@
619 568
620 569 private function jsHiddenFieldScript()
621 570 {
622 571 $appConfig = get_option('bitform_app_config');
623 - if (Helpers::property_exists_nested($appConfig, 'cache_plugin', true)) {
572 + $cacheTokenEnabled = true;
573 + if (is_object($appConfig) && property_exists($appConfig, 'cache_plugin')) {
574 + $cacheTokenEnabled = (bool) $appConfig->cache_plugin;
575 + } elseif (is_array($appConfig) && array_key_exists('cache_plugin', $appConfig)) {
576 + $cacheTokenEnabled = (bool) $appConfig['cache_plugin'];
577 + }
578 + if ($cacheTokenEnabled) {
624 579 $fileArr = ScriptFilePriorityManager::frontendScriptFile()['hidden-token-field'];
625 580 $this->addScriptInLoadedScriptsList($fileArr);
626 581 return;
627 582 }
@@ -626,14 +581,15 @@
626 581 return;
627 582 }
628 583 }
629 584
630 - public function dd($data, $exit = false)
585 + private function jsRecaptchaV3Scripts()
631 586 {
632 - echo '+++++++++++++';
633 - echo '<pre>';
634 - var_dump($data);
635 - echo '</pre>';
636 - echo '+++++++++++++';
637 - $exit ? exit : '';
587 + foreach ($this->_formContents as $content) {
588 + if (isset($content->additional->enabled->recaptchav3) && $content->additional->enabled->recaptchav3) {
589 + $this->addScriptInLoadedScriptsList(['priority' => 302, 'filename' => 'scriptLoader.min.js']);
590 + $this->addScriptInLoadedScriptsList(['priority' => 303, 'filename' => 'initRecaptchaV3Fld.min.js']);
591 + return;
592 + }
593 + }
638 594 }
639 595 }