PluginProbe
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder / 2.10.2
Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder v2.10.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
bit-form / includes / Admin / Form / FrontEndScriptGenerator.php

FrontEndScriptGenerator.php in Bit Form – Contact Form, Payment Forms, Multi Step Forms, Calculator & Custom Form Builder 2.10.2, at includes/Admin/Form/FrontEndScriptGenerator.php

640 lines 21.8 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\Admin\Form;
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;
12 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 use WP_Error;
17
18 class FrontEndScriptGenerator
19 {
20 private $_scriptAddedFlags;
21 private $_fields;
22 private $_formContents;
23 private $_jsFilesNeeded;
24 private $_loadedScriptsList;
25 private $_validationJsFilesNeeded;
26
27 public function __construct()
28 {
29 $this->_scriptAddedFlags = [];
30 $this->_fields = [];
31 $this->_jsFilesNeeded = [];
32 $this->_loadedScriptsList = [];
33 $this->_validationJsFilesNeeded = ScriptFilePriorityManager::validationAndOtherScriptFile();
34 }
35
36 private static function generateBfGlobalObjJS($contentIds = [])
37 {
38 $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;
52 }
53
54 });
55 GLOBALOBJ;
56 }
57
58 private static function isValidationNeeded($fldData)
59 {
60 $validationsToCheck = ['valid->req', 'valid->regexr', 'mn', 'mx', 'opt', 'err->invalid->show'];
61 foreach ($validationsToCheck as $property) {
62 $needValidation = Helpers::property_exists_nested($fldData, $property);
63 if ($needValidation) {
64 return true;
65 }
66 }
67 return false;
68 }
69
70 public function generateJsFile($formContents, $fields, $contentIds, $postId, $formIDs = null, $preview = 'classic')
71 {
72 add_option('bitforms_frontend_js_generating', true);
73 $this->_formContents = $formContents;
74 $this->_fields = $fields;
75
76 $this->appendJs(self::generateBfGlobalObjJS($contentIds), $postId, $preview, 'w');
77 $this->_jsFilesNeeded = ScriptFilePriorityManager::jsFile();
78
79 // helper js files for whole form
80 foreach ($this->_jsFilesNeeded['helperScript'] as $jsFile) {
81 $this->addScriptInLoadedScriptsList($jsFile);
82 }
83
84 // for add validation js files
85 $this->jsValidationNeededFile();
86
87 // js files for all fields
88 $this->jsFieldsNeededFile();
89
90 // for frontend helper js files
91 $this->jsFrontendScript();
92
93 // for hidden Field when cache plugin on
94 $this->jsHiddenFieldScript();
95
96 // for form abandonment scripts
97 $this->jsFormAbandonmentScripts();
98
99 // multi step form scripts
100 $this->multiStepFormScripts();
101
102 // conversational form scripts
103 $this->conversationalFormScripts();
104
105 //⚠👆 every script file generate method call before this method
106 $this->appendJs($this->getScript(), $postId, $preview);
107 $this->appendJs($this->generateFieldConfigsJs($contentIds), $postId, $preview);
108 // init all js events and functions at last
109 $this->appendJs(self::getFileFromAssetsJs('bitform-init.min.js'), $postId, $preview);
110 if (defined('ELEMENTOR_PRO_VERSION')) {
111 $this->appendJs(self::getFileFromAssetsJs('bitform-elementor.min.js'), $postId, $preview);
112 }
113
114 // for js file minification
115 $this->appendJs(self::getCustomJsCodes($contentIds), $postId, $preview);
116 delete_option('bitforms_frontend_js_generating');
117 return true;
118 }
119
120 private function multiStepFormScripts()
121 {
122 foreach ($this->_formContents as $formContent) {
123 $layout = $formContent->layout;
124 if (is_array($layout) && count($layout) > 1) {
125 $files = ScriptFilePriorityManager::multiStepFiles();
126 foreach ($files as $file) {
127 $this->addScriptInLoadedScriptsList($file);
128 }
129 }
130 }
131 }
132
133 private function conversationalFormScripts()
134 {
135 foreach ($this->_formContents as $formContent) {
136 if (!empty($formContent->formInfo->conversationalSettings) && $formContent->formInfo->conversationalSettings->enable) {
137 $files = ScriptFilePriorityManager::conversationalFormFiles();
138 foreach ($files as $file) {
139 $this->addScriptInLoadedScriptsList($file);
140 }
141 }
142 }
143 }
144
145 private function jsFormAbandonmentScripts()
146 {
147 if (!Utilities::isPro() || !class_exists('\BitCode\BitFormPro\Admin\FormSettings\FormAbandonment')) {
148 return;
149 }
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;
158 }
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 }
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 }
195
196 private function appendJs($script, $postId, $previewMode, $mode = 'a')
197 {
198 $fileName = '';
199 $path = '';
200
201 if ('conversational' === $previewMode) {
202 $fileName = "bitform-conversational-{$postId}.js";
203 $path = 'form-scripts';
204 } elseif ('preview' === $previewMode) {
205 $fileName = "preview-{$postId}.js";
206 $path = 'form-scripts';
207 } else {
208 $fileName = "bitform-js-$postId.js";
209 $path = "form-scripts/{$postId}";
210 }
211 Helpers::saveFile($path, $fileName, Helpers::minifyJs($script), $mode);
212 }
213
214 private function getScript()
215 {
216 usort($this->_loadedScriptsList, function ($a, $b) {
217 return $a['priority'] - $b['priority'];
218 });
219
220 $script = '';
221 foreach ($this->_loadedScriptsList as $scriptFileArr) {
222 $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;
229 }
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 }
238 return $script;
239 }
240
241 private function jsValidationNeededFile()
242 {
243 foreach ($this->_fields as $flds) {
244 foreach ($flds as $fld) {
245 $fldData = $fld['field'];
246 // for validation js files
247 if (self::isValidationNeeded($fldData)) {
248 $validation = $this->_validationJsFilesNeeded['validation'];
249 $this->addScriptInLoadedScriptsList($validation);
250 }
251 // for required
252 if (Helpers::property_exists_nested($fldData, 'valid->req')) {
253 $fileArr = $this->_validationJsFilesNeeded['requiredFldValidation'];
254 $this->addScriptInLoadedScriptsList($fileArr);
255 }
256 // for regex
257 if (Helpers::property_exists_nested($fldData, 'valid->regexr')) {
258 $patternFile = $this->_validationJsFilesNeeded['generateBackslashPattern'];
259 $rgx = $this->_validationJsFilesNeeded['regexPatternValidation'];
260 $this->addScriptInLoadedScriptsList($patternFile);
261 $this->addScriptInLoadedScriptsList($rgx);
262 }
263
264 $validationScriptFileMapping = ScriptFilePriorityManager::validationScriptFileMapping($fldData->typ);
265 if ($validationScriptFileMapping) {
266 foreach ($validationScriptFileMapping as $key => $value) {
267 foreach ($value['paths'] as $path) {
268 if (Helpers::property_exists_nested($fldData, $path)) {
269 $file = $this->_validationJsFilesNeeded[$key];
270 $this->addScriptInLoadedScriptsList($file);
271 }
272 }
273 if (isset($value['dependencies'])) {
274 foreach ($value['dependencies'] as $dependency) {
275 $dependencyFile = $this->_validationJsFilesNeeded[$dependency];
276 $this->addScriptInLoadedScriptsList($dependencyFile);
277 }
278 }
279 }
280 }
281 }
282 }
283 }
284
285 private function jsFieldsNeededFile()
286 {
287 foreach ($this->_fields as $typ => $flds) {
288 if (!array_key_exists($typ, $this->_jsFilesNeeded)) {
289 continue;
290 }
291 $fldScriptArr = $this->_jsFilesNeeded[$typ];
292
293 foreach ($flds as $fld) {
294 if ('advanced-file-up' === $typ) {
295 $configs = $fld['field']->config;
296 foreach ($configs as $configKey => $config) {
297 if ($configs->$configKey) {
298 $filepondPlugin = ScriptFilePriorityManager::filePondPlugins($configKey);
299 if ($filepondPlugin) {
300 $this->addScriptInLoadedScriptsList($filepondPlugin);
301 }
302 }
303 }
304 }
305 foreach ($fldScriptArr as $scriptFile) {
306 if (!isset($scriptFile['scriptTyp'])) {
307 $this->addScriptInLoadedScriptsList($scriptFile);
308 continue;
309 }
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 }
316 }
317 }
318 }
319 }
320
321 private static function getCustomJsCodes($contentIds = [])
322 {
323 $script = 'let bfContentId = "", bfVars= "";';
324 foreach ($contentIds as $contentId) {
325 $jsCode = self::getCustomCodes(explode('_', $contentId)[1])['JavaScript'];
326 if (!empty($jsCode)) {
327 $script .= " if(bfSelect('#{$contentId}')){ bfContentId = '{$contentId}'; bfVars = window.bf_globals.{$contentId}.smartTags; {$jsCode}}";
328 }
329 }
330
331 return $script;
332 }
333
334 private static function getFileFromAssetsJs($fileName)
335 {
336 $sourceJsFile = BITFORMS_PLUGIN_DIR_PATH . 'assets' . DIRECTORY_SEPARATOR . $fileName;
337 if (file_exists($sourceJsFile)) {
338 return file_get_contents($sourceJsFile);
339 }
340 Log::debug_log('file not found: ' . $fileName);
341 return false;
342 }
343
344 public static function saveCssFile($formId, $atomicCssText)
345 {
346 $path = 'form-styles';
347 $fileName = "bitform-$formId.css";
348 if (!isset($formId) || '' === $formId) {
349 return new WP_Error('missing_form_id', __('Error Occurred, Please Reload', 'bit-form'));
350 }
351 return Helpers::saveFile($path, $fileName, $atomicCssText, 'w');
352 }
353
354 public static function customCodeFile($formId, $customCodes)
355 {
356 // for js file
357 $path = 'form-scripts';
358 $fileName = "bitform-custom-$formId.js";
359 self::customCodeFileSaveOrDelete($customCodes->JavaScript, $path, $fileName);
360
361 // for css file
362 $path = 'form-styles';
363 $fileName = "bitform-custom-$formId.css";
364 self::customCodeFileSaveOrDelete($customCodes->CSS, $path, $fileName);
365
366 return true;
367 }
368
369 public static function customCodeFileSaveOrDelete($script, $path, $fileName)
370 {
371 if ($script) {
372 Helpers::saveFile($path, $fileName, $script, 'w');
373 } else {
374 $uploadPath = "$path/$fileName";
375 $uploadFilePath = Helpers::generatePathDirOrFile($uploadPath);
376 if (file_exists($uploadFilePath)) {
377 unlink($uploadFilePath);
378 }
379 }
380 return true;
381 }
382
383 public static function getCustomCodes($formId)
384 {
385 $customCodes = ['JavaScript' => '', 'CSS' => ''];
386 $customJsPath = Helpers::generatePathDirOrFile("form-scripts/bitform-custom-$formId.js");
387 $customCodes['JavaScript'] = Helpers::fileRead($customJsPath);
388
389 $customCSSPath = Helpers::generatePathDirOrFile("form-styles/bitform-custom-$formId.css");
390 $customCodes['CSS'] = Helpers::fileRead($customCSSPath);
391
392 return $customCodes;
393 }
394
395 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',
409 ];
410
411 private function generateFieldConfigsJs()
412 {
413 $customFlds = ['select', 'country', 'currency', 'phone-number', 'file-up', 'advanced-file-up', 'paypal', 'razorpay', 'stripe', 'recaptcha', 'repeater', 'signature', 'rating', 'turnstile'];
414 $allFieldTypes = array_keys($this->_fields);
415 $customFldsInForms = array_intersect($allFieldTypes, $customFlds);
416 $formContents = $this->_formContents;
417 $recaptchaV3Enabled = false;
418 foreach ($formContents as $content) {
419 if (isset($content->additional->enabled->recaptchav3) && $content->additional->enabled->recaptchav3) {
420 $recaptchaV3Enabled = true;
421 break;
422 }
423 }
424 if (empty($customFldsInForms) && !$recaptchaV3Enabled) {
425 return '';
426 }
427
428 $containers = [];
429 foreach ($customFldsInForms as $customFldTyp) {
430 if (isset($this->fldContainersByType[$customFldTyp])) {
431 $containers[$customFldTyp] = $this->fldContainersByType[$customFldTyp];
432 }
433 }
434
435 $customFldConfigPaths = [];
436
437 foreach ($customFldsInForms as $customFldTyp) {
438 $allConfs = ScriptFilePriorityManager::getAllFldConfs();
439 if (isset($allConfs[$customFldTyp])) {
440 $customFldConfigPaths[$customFldTyp] = $allConfs[$customFldTyp];
441 } else {
442 $customFldConfigPaths[$customFldTyp] = (object) [];
443 }
444 }
445
446 $customFldConfigPaths = wp_json_encode($customFldConfigPaths);
447 $containers = wp_json_encode($containers);
448
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;
496
497 $scriptLoaderJs;
498
499 function initAllCustomFlds (formContentId = null) {
500 const allContendIds = formContentId ? [formContentId] : Object.keys(bf_globals);
501 allContendIds.forEach((contentId) => {
502 const contentData = bf_globals[contentId];
503 const flds = bf_globals[contentId].fields;
504 const fldKeys = Object.keys(flds).reverse();
505 fldKeys.forEach((fldKey) => {
506 const fldData = flds[fldKey];
507 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;
518 } else if (customFldConfigPaths[fldType]) {
519 contentData.inits[fldKey] = getFldInstance(contentId, fldKey, fldType);
520 }
521 });
522 if(contentData.gRecaptchaVersion === 'v3' && contentData.gRecaptchaSiteKey){
523 $recaptchaV3InitJs;
524 }
525 });
526 };
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);
530 if(!fldClass || !bfSelect(selector)) return;
531 return new fldClass(selector, getFldConf(contentId, fldKey, fldTyp));
532 };
533 function getFldConf(contentId, fieldKey, fldTyp) {
534 const fldData = bf_globals[contentId].fields[fieldKey];
535 const fldConfPaths = Object.entries(customFldConfigPaths[fldTyp]);
536 let fldConf = {};
537 const { formId } = bf_globals[contentId];
538 if (!("config" in customFldConfigPaths[fldTyp]) && "config" in fldData) fldConf = fldData.config;
539 const varData = { contentId, fieldKey, formId };
540 fldConfPaths.forEach(([ confPath, fldPath ]) => {
541 let value = "";
542 if (fldPath.var) value = varData[fldPath.var];
543 if (!value && fldPath.path) {
544 if(Array.isArray(fldPath.path)) {
545 fldPath.path.forEach((path) => {
546 if(!value) value = getDataFromNestedPath(fldData, path);
547 });
548 } else {
549 value = getDataFromNestedPath(fldData, fldPath.path);
550 }
551 }
552 if (!value && fldPath.val) {
553 value = fldPath.val;
554 if(typeof value === 'string') {
555 Object.entries(varData).forEach(([key, val]) => {
556 value = value.replace("__\$"+key+"__", val);
557 });
558 }
559 }
560 fldConf = setDataToNestedPath(fldConf, confPath, value);
561 });
562 return fldConf;
563 };
564 function getDataFromNestedPath(data, key) {
565 const keys = key.split("->");
566 const lastKey = keys.pop();
567 let current = {...data};
568 for (const k of keys) {
569 if (!(k in current)) return null;
570 current = current[k];
571 }
572 return current[lastKey] || null;
573 }
574 function setDataToNestedPath(data, key, value) {
575 const keys = key.split("->");
576 const lastKey = keys.pop();
577 let current = {...data};
578 keys.forEach((k) => {
579 if (!current[k]) current[k] = {};
580 current = current[k];
581 });
582 current[lastKey] = value;
583 return current;
584 }
585 FIELDCONFIGJS;
586
587 return $script;
588 }
589
590 private function addScriptInLoadedScriptsList($fileArr)
591 {
592 $fileName = $fileArr['filename'];
593 if (!in_array($fileName, $this->_scriptAddedFlags)) {
594 $this->_loadedScriptsList[] = $fileArr;
595 $this->_scriptAddedFlags[] = $fileName;
596 }
597 return true;
598 }
599
600 private function jsFrontendScript()
601 {
602 foreach ($this->_formContents as $formContent) {
603 if (Helpers::property_exists_nested($formContent, 'workFlowExist->oninput', true)) {
604 $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['conditionalLogic'];
605 $this->addScriptInLoadedScriptsList($fileArr);
606 $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['resetPlaceholders'];
607 $this->addScriptInLoadedScriptsList($fileArr);
608 $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['validateFocusLost'];
609 $this->addScriptInLoadedScriptsList($fileArr);
610 $fileArr = ScriptFilePriorityManager::frontendScriptFile()['observeElm'];
611 $this->addScriptInLoadedScriptsList($fileArr);
612 }
613 if (Helpers::property_exists_nested($formContent, 'additional->enabled->validateFocusLost', true)) {
614 $fileArr = ScriptFilePriorityManager::validationAndOtherScriptFile()['validateFocusLost'];
615 $this->addScriptInLoadedScriptsList($fileArr);
616 }
617 }
618 }
619
620 private function jsHiddenFieldScript()
621 {
622 $appConfig = get_option('bitform_app_config');
623 if (Helpers::property_exists_nested($appConfig, 'cache_plugin', true)) {
624 $fileArr = ScriptFilePriorityManager::frontendScriptFile()['hidden-token-field'];
625 $this->addScriptInLoadedScriptsList($fileArr);
626 return;
627 }
628 }
629
630 public function dd($data, $exit = false)
631 {
632 echo '+++++++++++++';
633 echo '<pre>';
634 var_dump($data);
635 echo '</pre>';
636 echo '+++++++++++++';
637 $exit ? exit : '';
638 }
639 }
640