PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 5.2.9
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v5.2.9
6.2.14 6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 All 196 releases
fluentform / app / Modules / Component / Component.php

Component.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 5.2.9, at app/Modules/Component/Component.php

1,432 lines 54.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Modules\Component;
4
5 use FluentForm\App\Helpers\Helper;
6 use FluentForm\App\Modules\Acl\Acl;
7 use FluentForm\App\Modules\Form\FormDataParser;
8 use FluentForm\App\Services\FormBuilder\EditorShortcodeParser;
9 use FluentForm\App\Services\FormBuilder\Notifications\EmailNotificationActions;
10 use FluentForm\Framework\Foundation\Application;
11 use FluentForm\Framework\Helpers\ArrayHelper;
12 use FluentForm\Framework\Helpers\ArrayHelper as Arr;
13
14
15 class Component
16 {
17 /**
18 * FluentForm\Framework\Foundation\Application
19 *
20 * @var $app
21 */
22 protected $app = null;
23
24 /**
25 * Determine whether to register Elementor PopUp handler.
26 *
27 * @var bool
28 */
29 protected $elementorPopUpHandler = false;
30
31 /**
32 * Biuld the instance of this class
33 *
34 * @param \FluentForm\Framework\Foundation\Application $app
35 */
36 public function __construct(Application $app)
37 {
38 $this->app = $app;
39 }
40
41 public function registerScripts()
42 {
43 $app = $this->app;
44
45 // We will just register the scripts here. We will not load any scripts from here
46
47 $fluentFormPublicCss = fluentFormMix('css/fluent-forms-public.css');
48 $fluentFormPublicDefaultCss = fluentFormMix('css/fluentform-public-default.css');
49
50 if (is_rtl()) {
51 $fluentFormPublicCss = fluentFormMix('css/fluent-forms-public-rtl.css');
52 $fluentFormPublicDefaultCss = fluentFormMix('css/fluentform-public-default-rtl.css');
53 }
54
55 wp_register_style(
56 'fluent-form-styles',
57 $fluentFormPublicCss,
58 [],
59 FLUENTFORM_VERSION
60 );
61
62 wp_register_style(
63 'fluentform-public-default',
64 $fluentFormPublicDefaultCss,
65 [],
66 FLUENTFORM_VERSION
67 );
68
69 wp_register_script(
70 'fluent-form-submission',
71 fluentFormMix('js/form-submission.js'),
72 ['jquery'],
73 FLUENTFORM_VERSION,
74 true
75 );
76
77 wp_register_script(
78 'fluentform-advanced',
79 fluentFormMix('js/fluentform-advanced.js'),
80 ['jquery'],
81 FLUENTFORM_VERSION,
82 true
83 );
84
85 // Date Pickckr Style
86 //fix for essential addon event picker conflict
87 if (!wp_script_is('flatpickr', 'registered')) {
88 wp_register_style(
89 'flatpickr',
90 fluentFormMix('libs/flatpickr/flatpickr.min.css'),
91 [],
92 '4.6.9'
93 );
94 }
95 // Date Pickckr Script
96 wp_register_script(
97 'flatpickr',
98 fluentFormMix('libs/flatpickr/flatpickr.min.js'),
99 ['jquery'],
100 '4.6.9',
101 true
102 );
103
104 wp_register_script(
105 'choices',
106 fluentFormMix('libs/choices/choices.min.js'),
107 [],
108 '9.0.1',
109 true
110 );
111
112 wp_register_style(
113 'ff_choices',
114 fluentFormMix('css/choices.css'),
115 [],
116 FLUENTFORM_VERSION
117 );
118
119 wp_register_script(
120 'form-save-progress',
121 fluentFormMix('js/form-save-progress.js'),
122 ['jquery'],
123 FLUENTFORM_VERSION,
124 true
125 );
126
127 do_action_deprecated(
128 'fluentform_scripts_registered',
129 [
130
131 ],
132 FLUENTFORM_FRAMEWORK_UPGRADE,
133 'fluentform/scripts_registered',
134 'Use fluentform/scripts_registered instead of fluentform_scripts_registered.'
135 );
136
137 $this->app->doAction('fluentform/scripts_registered');
138
139 $this->maybeLoadFluentFormStyles();
140 }
141
142 protected function maybeLoadFluentFormStyles()
143 {
144 global $post;
145
146 $postId = isset($post->ID) ? $post->ID : false;
147 if (!$postId) {
148 return;
149 }
150 $fluentFormIds = get_post_meta($postId, '_has_fluentform', true);
151 $hasFluentformMeta = is_a($post, 'WP_Post') && $fluentFormIds;
152
153 $loadStyle = apply_filters_deprecated(
154 'fluentform_load_styles',
155 [
156 false,
157 $post
158 ],
159 FLUENTFORM_FRAMEWORK_UPGRADE,
160 'fluentform/load_styles',
161 'Use fluentform/load_styles instead of fluentform_load_styles.'
162 );
163
164 if ($hasFluentformMeta || apply_filters('fluentform/load_styles', $loadStyle, $post)) {
165 wp_enqueue_style('fluent-form-styles');
166 wp_enqueue_style('fluentform-public-default');
167
168 do_action_deprecated(
169 'fluentform_pre_load_scripts',
170 [
171 $post
172 ],
173 FLUENTFORM_FRAMEWORK_UPGRADE,
174 'fluentform/pre_load_scripts',
175 'Use fluentform/pre_load_scripts instead of fluentform_pre_load_scripts.'
176 );
177
178 $this->app->doAction('fluentform/pre_load_scripts', $post);
179
180 wp_enqueue_script('fluent-form-submission');
181 }
182 }
183
184 /**
185 * Get all the available components
186 * @deprecated Use \FluentForm\App\Http\Controllers\FormController::resources
187 * @return void
188 *
189 * @throws \Exception
190 * @throws \FluentForm\Framework\Exception\UnResolveableEntityException
191 */
192 public function index()
193 {
194 $formId = intval($this->app->request->get('formId'));
195
196 $components = $this->app->make('components');
197
198 do_action_deprecated(
199 'fluent_editor_init',
200 [
201 $components
202 ],
203 FLUENTFORM_FRAMEWORK_UPGRADE,
204 'fluentform/editor_init',
205 'Use fluentform/editor_init instead of fluent_editor_init.'
206 );
207
208 $this->app->doAction('fluentform/editor_init', $components);
209
210 $editorComponents = $components->sort()->toArray();
211
212 $editorComponents = apply_filters_deprecated(
213 'fluent_editor_components',
214 [
215 $editorComponents,
216 $formId
217 ],
218 FLUENTFORM_FRAMEWORK_UPGRADE,
219 'fluentform/editor_components',
220 'Use fluentform/editor_components instead of fluent_editor_components.'
221 );
222
223 $editorComponents = apply_filters('fluentform/editor_components', $editorComponents, $formId);
224
225 wp_send_json_success([
226 'countries' => getFluentFormCountryList(),
227 'components' => $editorComponents,
228 'disabled_components' => $this->getDisabledComponents(),
229 ]);
230 }
231
232 /**
233 * Get disabled components
234 *
235 * @return array
236 */
237 private function getDisabledComponents()
238 {
239 $isReCaptchaDisabled = !get_option('_fluentform_reCaptcha_keys_status', false);
240 $isHCaptchaDisabled = !get_option('_fluentform_hCaptcha_keys_status', false);
241 $isTurnstileDisabled = !get_option('_fluentform_turnstile_keys_status', false);
242
243 $disabled = [
244 'recaptcha' => [
245 'disabled' => $isReCaptchaDisabled,
246 'title' => __('reCaptcha', 'fluentform'),
247 'description' => __('Please enter a valid API key on FluentForms->Settings->reCaptcha', 'fluentform'),
248 'hidePro' => true,
249 ],
250 'hcaptcha' => [
251 'disabled' => $isHCaptchaDisabled,
252 'title' => __('hCaptcha', 'fluentform'),
253 'description' => __('Please enter a valid API key on FluentForms->Settings->hCaptcha', 'fluentform'),
254 'hidePro' => true,
255 ],
256 'turnstile' => [
257 'disabled' => $isTurnstileDisabled,
258 'title' => __('Turnstile', 'fluentform'),
259 'description' => __('Please enter a valid API key on FluentForms->Settings->Turnstile', 'fluentform'),
260 'hidePro' => true,
261 ],
262 'input_image' => [
263 'disabled' => true,
264 'title' => __('Image Upload', 'fluentform'),
265 'description' => __('Image Upload is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
266 'image' => '',
267 'video' => 'https://www.youtube.com/embed/Yb3FSoZl9Zg',
268 ],
269 'input_file' => [
270 'disabled' => true,
271 'title' => __('File Upload', 'fluentform'),
272 'description' => __('File Upload is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
273 'image' => '',
274 'video' => 'https://www.youtube.com/embed/bXbTbNPM_4k',
275 ],
276 'shortcode' => [
277 'disabled' => true,
278 'title' => __('Shortcode', 'fluentform'),
279 'description' => __('Shortcode is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
280 'image' => '',
281 'video' => 'https://www.youtube.com/embed/op3mEQxX1MM',
282 ],
283 'action_hook' => [
284 'disabled' => true,
285 'title' => __('Action Hook', 'fluentform'),
286 'description' => __('Action Hook is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
287 'image' => fluentformMix('img/pro-fields/action-hook.png'),
288 'video' => '',
289 ],
290 'form_step' => [
291 'disabled' => true,
292 'title' => __('Form Step', 'fluentform'),
293 'description' => __('Form Step is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
294 'image' => '',
295 'video' => 'https://www.youtube.com/embed/VQTWnM6BbRU',
296 ],
297 ];
298
299 if (!defined('FLUENTFORMPRO')) {
300 $disabled['ratings'] = [
301 'disabled' => true,
302 'title' => __('Ratings', 'fluentform'),
303 'description' => __('Ratings is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
304 'image' => '',
305 'video' => 'https://www.youtube.com/embed/YGdkNspMaEs',
306 ];
307 $disabled['tabular_grid'] = [
308 'disabled' => true,
309 'title' => __('Checkable Grid', 'fluentform'),
310 'description' => __('Checkable Grid is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
311 'image' => '',
312 'video' => 'https://www.youtube.com/embed/ayI3TzXXANA',
313 ];
314 $disabled['chained_select'] = [
315 'disabled' => true,
316 'title' => __('Chained Select Field', 'fluentform'),
317 'description' => __('Chained Select Field is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
318 'image' => fluentformMix('img/pro-fields/chained-select-field.png'),
319 'video' => '',
320 ];
321 $disabled['phone'] = [
322 'disabled' => true,
323 'title' => 'Phone Field',
324 'description' => __('Phone Field is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
325 'image' => fluentformMix('img/pro-fields/phone-field.png'),
326 'video' => '',
327 ];
328 $disabled['rich_text_input'] = [
329 'disabled' => true,
330 'title' => __('Rich Text Input', 'fluentform'),
331 'description' => __('Rich Text Input is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
332 'image' => fluentformMix('img/pro-fields/rich-text-input.png'),
333 'video' => '',
334 ];
335 $disabled['save_progress_button'] = [
336 'disabled' => true,
337 'title' => __('Save & Resume', 'fluentform'),
338 'description' => __('Save & Resume is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
339 'image' => fluentformMix('img/pro-fields/save-progress-button.png'),
340 'video' => '',
341 ];
342 $disabled['cpt_selection'] = [
343 'disabled' => true,
344 'title' => __('Post/CPT Selection', 'fluentform'),
345 'description' => __('Post/CPT Selection is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
346 'image' => fluentformMix('img/pro-fields/post-cpt-selection.png'),
347 'video' => '',
348 ];
349 $disabled['quiz_score'] = [
350 'disabled' => true,
351 'title' => __('Quiz Score', 'fluentform'),
352 'description' => __('Quiz Score is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
353 'image' => '',
354 'video' => 'https://www.youtube.com/embed/bPjDXR0y_Oo',
355 ];
356 $disabled['net_promoter_score'] = [
357 'disabled' => true,
358 'title' => __('Net Promoter Score', 'fluentform'),
359 'description' => __('Net Promoter Score is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
360 'image' => fluentformMix('img/pro-fields/net-promoter-score.png'),
361 'video' => '',
362 ];
363 $disabled['repeater_field'] = [
364 'disabled' => true,
365 'title' => __('Repeat Field', 'fluentform'),
366 'description' => __('Repeat Field is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
367 'image' => '',
368 'video' => 'https://www.youtube.com/embed/BXo9Sk-OLnQ',
369 ];
370 $disabled['rangeslider'] = [
371 'disabled' => true,
372 'title' => __('Range Slider', 'fluentform'),
373 'description' => __('Range Slider is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
374 'image' => '',
375 'video' => 'https://www.youtube.com/embed/RaY2VcPWk6I',
376 ];
377 $disabled['color-picker'] = [
378 'disabled' => true,
379 'title' => __('Color Picker', 'fluentform'),
380 'description' => __('Color Picker is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
381 'image' => fluentformMix('img/pro-fields/color-picker.png'),
382 'video' => '',
383 ];
384 $disabled['multi_payment_component'] = [
385 'disabled' => true,
386 'is_payment' => true,
387 'title' => __('Payment Field', 'fluentform'),
388 'description' => __('Payment Field is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
389 'image' => fluentformMix('img/pro-fields/payment-field.png'),
390 'video' => '',
391 ];
392 $disabled['custom_payment_component'] = [
393 'disabled' => true,
394 'is_payment' => true,
395 'title' => 'Custom Payment Amount',
396 'description' => __('Custom Payment Amount is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
397 'image' => fluentformMix('img/pro-fields/custom-payment-amount.png'),
398 'video' => '',
399 ];
400 $disabled['subscription_payment_component'] = [
401 'disabled' => true,
402 'is_payment' => true,
403 'title' => __('Subscription Field', 'fluentform'),
404 'description' => __('Subscription Field is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
405 'image' => fluentformMix('img/pro-fields/subscription-field.png'),
406 'video' => '',
407 ];
408 $disabled['item_quantity_component'] = [
409 'disabled' => true,
410 'is_payment' => true,
411 'title' => __('Item Quantity', 'fluentform'),
412 'description' => __('Item Quantity is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
413 'image' => fluentformMix('img/pro-fields/item-quantity.png'),
414 'video' => '',
415 ];
416 $disabled['payment_method'] = [
417 'disabled' => true,
418 'is_payment' => true,
419 'title' => __('Payment Method', 'fluentform'),
420 'description' => __('Payment Method is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
421 'image' => fluentformMix('img/pro-fields/payment-method.png'),
422 'video' => '',
423 ];
424 $disabled['payment_summary_component'] = [
425 'disabled' => true,
426 'is_payment' => true,
427 'title' => __('Payment Summary', 'fluentform'),
428 'description' => __('Payment Summary is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
429 'image' => fluentformMix('img/pro-fields/payment-summary.png'),
430 'video' => '',
431 ];
432 $disabled['payment_coupon'] = [
433 'disabled' => true,
434 'title' => __('Coupon', 'fluentform'),
435 'description' => __('Coupon is not available with the free version. Please upgrade to pro to get all the advanced features.', 'fluentform'),
436 'image' => fluentformMix('img/pro-fields/coupon.png'),
437 'video' => '',
438 ];
439 }
440
441 $disabled = apply_filters_deprecated(
442 'fluentform_disabled_components',
443 [
444 $disabled
445 ],
446 FLUENTFORM_FRAMEWORK_UPGRADE,
447 'fluentform/disabled_components',
448 'Use fluentform/disabled_components instead of fluentform_disabled_components.'
449 );
450 return $this->app->applyFilters('fluentform/disabled_components', $disabled);
451 }
452
453 /**
454 * Get available shortcodes for editor
455 *
456 * @return void
457 *
458 * @throws \Exception
459 */
460 public function getEditorShortcodes()
461 {
462 $editor_shortcodes = fluentFormEditorShortCodes();
463 wp_send_json_success(['shortcodes' => $editor_shortcodes], 200);
464 }
465
466 /**
467 * @deprecated Use \FluentForm\App\Services\Form\FormService::shortcodes
468 * Get all available shortcodes for editor
469 *
470 * @return void
471 *
472 * @throws \Exception
473 */
474 public function getAllEditorShortcodes()
475 {
476 wp_send_json(fluentFormGetAllEditorShortCodes(
477 $this->app->request->get('formId')
478 ), 200);
479 }
480
481 /**
482 * Register the form renderer shortcode
483 *
484 * @return void
485 */
486 public function addFluentFormShortCode()
487 {
488 add_action('wp_enqueue_scripts', [$this, 'registerScripts'], 9);
489
490 $this->app->addShortCode('fluentform', function ($atts, $content) {
491 $data = [
492 'id' => null,
493 'title' => null,
494 'css_classes' => '',
495 'permission' => '',
496 'type' => 'classic',
497 'theme' => '',
498 'permission_message' => __('Sorry, You do not have permission to view this form', 'fluentform')
499 ];
500 /* This filter is deprecated, will be removed soon */
501 $data = apply_filters('fluentform_shortcode_defaults', $data, $atts );
502
503 $shortcodeDefaults = apply_filters('fluentform/shortcode_defaults', $data, $atts);
504
505 $atts = shortcode_atts($shortcodeDefaults, $atts);
506
507 return $this->renderForm($atts);
508 });
509
510 $this->registerHelperShortCodes();
511 }
512
513 public function renderForm($atts)
514 {
515 $form_id = $atts['id'];
516 $query = wpFluent()->table('fluentform_forms');
517
518 if (! $this->app->request->get('preview_id')) {
519 $query->where('status', 'published');
520 }
521
522 if ($form_id) {
523 $form = $query->find($form_id);
524 } elseif ($formTitle = $atts['title']) {
525 $form = $query->where('title', $formTitle)->first();
526 } else {
527 return '';
528 }
529
530 if (!$form) {
531 return '';
532 }
533
534 if (!empty($atts['permission'])) {
535 if (!current_user_can($atts['permission'])) {
536 return "<div id='ff_form_{$form->id}' class='ff_form_not_render'>{$atts['permission_message']}</div>";
537 }
538 }
539
540 if (is_feed()) {
541 global $post;
542 $feedText = sprintf(__('The form can be filled in the actual <a href="%s">website url</a>.', 'fluentform'), get_permalink($post));
543
544 $feedText = apply_filters_deprecated(
545 'fluentform_shortcode_feed_text',
546 [
547 $feedText,
548 $form
549 ],
550 FLUENTFORM_FRAMEWORK_UPGRADE,
551 'fluentform/shortcode_feed_text',
552 'Use fluentform/shortcode_feed_text instead of fluentform_shortcode_feed_text.'
553 );
554
555 $feedText = apply_filters('fluentform/shortcode_feed_text', $feedText, $form);
556 return $feedText;
557 }
558
559 $formSettings = wpFluent()
560 ->table('fluentform_form_meta')
561 ->where('form_id', $form_id)
562 ->where('meta_key', 'formSettings')
563 ->first();
564
565 if (!$formSettings) {
566 return '';
567 }
568
569 $form->fields = json_decode($form->form_fields, true);
570
571 if (!$form->fields['fields']) {
572 return '';
573 }
574
575 $form->settings = json_decode($formSettings->value, true);
576
577 $form = apply_filters_deprecated(
578 'fluentform_rendering_form',
579 [
580 $form
581 ],
582 FLUENTFORM_FRAMEWORK_UPGRADE,
583 'fluentform/rendering_form',
584 'Use fluentform/rendering_form instead of fluentform_rendering_form.'
585 );
586
587 $form = $this->app->applyFilters('fluentform/rendering_form', $form);
588 $isRenderable = [
589 'status' => true,
590 'message' => '',
591 ];
592 /* This filter is deprecated and will be removed soon */
593 $isRenderable = apply_filters('fluentform_is_form_renderable', $isRenderable, $form);
594
595 $isRenderable = $this->app->applyFilters('fluentform/is_form_renderable', $isRenderable, $form);
596
597 if (is_array($isRenderable) && !$isRenderable['status']) {
598 return "<div id='ff_form_{$form->id}' class='ff_form_not_render'>{$isRenderable['message']}</div>";
599 }
600
601 $instanceCssClass = Helper::getFormInstaceClass($form->id);
602
603 $form->instance_css_class = $instanceCssClass;
604 $form->instance_index = Helper::$formInstance;
605
606 if ('conversational' == $atts['type']) {
607 $this->addInlineVars();
608 return (new \FluentForm\App\Services\FluentConversational\Classes\Form())->renderShortcode($form);
609 }
610
611 $formBuilder = $this->app->make('formBuilder');
612
613 $cssClasses = trim($instanceCssClass . ' ff-form-loading');
614
615 $output = $formBuilder->build($form, $cssClasses, $instanceCssClass, $atts);
616
617 $output = $this->replaceEditorSmartCodes($output, $form);
618
619 if (!wp_script_is('fluent-form-submission', 'registered')) {
620 $this->registerScripts();
621 }
622
623 wp_enqueue_style('fluent-form-styles');
624
625 $loadStyle = apply_filters_deprecated(
626 'fluentform_load_default_public',
627 [
628 true,
629 $form
630 ],
631 FLUENTFORM_FRAMEWORK_UPGRADE,
632 'fluentform/load_default_public',
633 'Use fluentform/load_default_public instead of fluentform_load_default_public.'
634 );
635
636 if (apply_filters('fluentform/load_default_public', $loadStyle, $form)) {
637 wp_enqueue_style('fluentform-public-default');
638 }
639 /*
640 * We will load fluentform-advanced if the form has certain fields or feature
641 */
642 $this->maybeHasAdvandedFields($form, $formBuilder);
643 wp_enqueue_script('fluent-form-submission');
644
645 $stepText = __('Step %activeStep% of %totalStep% - %stepTitle%', 'fluentform');
646
647 $stepText = apply_filters_deprecated(
648 'fluentform_step_string',
649 [
650 $stepText
651 ],
652 FLUENTFORM_FRAMEWORK_UPGRADE,
653 'fluentform/step_string',
654 'Use fluentform/step_string instead of fluentform_step_string.'
655 );
656
657 $stepText = apply_filters('fluentform/step_string', $stepText);
658
659 $data = [
660 'ajaxUrl' => admin_url('admin-ajax.php'),
661 'forms' => [],
662 'step_text' => $stepText,
663 'is_rtl' => is_rtl(),
664 'date_i18n' => self::getDatei18n(),
665 'pro_version' => (defined('FLUENTFORMPRO_VERSION')) ? FLUENTFORMPRO_VERSION : false,
666 'fluentform_version' => FLUENTFORM_VERSION,
667 'force_init' => false,
668 'stepAnimationDuration' => 350,
669 'upload_completed_txt' => __('100% Completed', 'fluentform'),
670 'upload_start_txt' => __('0% Completed', 'fluentform'),
671 'uploading_txt' => __('Uploading', 'fluentform'),
672 'choice_js_vars' => [
673 'noResultsText' => __('No results found', 'fluentform'),
674 'loadingText' => __('Loading...', 'fluentform'),
675 'noChoicesText' => __('No choices to choose from', 'fluentform'),
676 'itemSelectText' => __('Press to select', 'fluentform'),
677 'maxItemText' => __('Only %%maxItemCount%% options can be added', 'fluentform'),
678 ],
679 'input_mask_vars' => [
680 'clearIfNotMatch' => false,
681 ],
682 'nonce' => wp_create_nonce()
683 ];
684
685 $data = apply_filters_deprecated(
686 'fluentform_global_form_vars',
687 [
688 $data
689 ],
690 FLUENTFORM_FRAMEWORK_UPGRADE,
691 'fluentform/global_form_vars',
692 'Use fluentform/global_form_vars instead of fluentform_global_form_vars.'
693 );
694
695 $vars = apply_filters('fluentform/global_form_vars', $data);
696
697 wp_localize_script('fluent-form-submission', 'fluentFormVars', $vars);
698
699 $formSettings = $form->settings;
700
701 $formSettings = ArrayHelper::only($formSettings, ['layout', 'id']);
702
703 $formSettings['restrictions']['denyEmptySubmission'] = [
704 'enabled' => false,
705 ];
706
707 if (!empty($formBuilder->validationRules)) {
708 $formBuilder->validationRules = fluentform_backend_sanitizer($formBuilder->validationRules, [
709 'message' => 'fluentform_sanitize_html'
710 ]);
711 }
712
713 $form_vars = [
714 'id' => $form->id,
715 'settings' => $formSettings,
716 'form_instance' => $instanceCssClass,
717 'form_id_selector' => 'fluentform_' . $form->id,
718 'rules' => $formBuilder->validationRules,
719 'debounce_time' => apply_filters('fluentform/show_hide_elements_debounce_time', 300),
720 ];
721
722 if ($conditionals = $formBuilder->conditions) {
723 $form_vars['conditionals'] = $conditionals;
724 }
725
726 $form_vars = apply_filters('fluentform/form_vars_for_JS', $form_vars, $form);
727
728 if ($form->has_payment) {
729 do_action_deprecated(
730 'fluentform_rendering_payment_form',
731 [
732 $form
733 ],
734 FLUENTFORM_FRAMEWORK_UPGRADE,
735 'fluentform/rendering_payment_form',
736 'Use fluentform/rendering_payment_form instead of fluentform_rendering_payment_form.'
737 );
738 do_action('fluentform/rendering_payment_form', $form);
739 }
740
741 $otherScripts = '';
742 $otherScriptsRenderImmediately = apply_filters('fluentform/load_form_instance_js_var_immediately', false);
743 if (!$otherScriptsRenderImmediately) {
744 ob_start();
745 }
746 ?>
747 <script type="text/javascript">
748 window.fluent_form_<?php echo esc_attr($instanceCssClass); ?> = <?php echo wp_json_encode($form_vars); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $form_vars is escaped before being passed in.?>;
749 <?php if (wp_doing_ajax()): ?>
750 function initFFInstance_<?php echo esc_attr($form_vars['id']); ?>() {
751 if (!window.fluentFormApp) {
752 console.log('No fluentFormApp found');
753 return;
754 }
755 var ajax_formInstance = window.fluentFormApp(jQuery('form.<?php echo esc_attr($form_vars['form_instance']); ?>'));
756 if (ajax_formInstance) {
757 ajax_formInstance.initFormHandlers();
758 }
759 }
760
761 initFFInstance_<?php echo esc_attr($form_vars['id']); ?>();
762 <?php endif; ?>
763 </script>
764 <?php
765 $this->addInlineVars();
766 if (!$otherScriptsRenderImmediately) {
767 $otherScripts .= ob_get_clean();
768 }
769
770
771 $disableAnalytics = apply_filters_deprecated(
772 'fluentform-disabled_analytics',
773 [
774 true
775 ],
776 FLUENTFORM_FRAMEWORK_UPGRADE,
777 'fluentform/disabled_analytics',
778 'Use fluentform/disabled_analytics instead of fluentform-disabled_analytics.'
779 );
780
781 if (!$this->app->applyFilters('fluentform/disabled_analytics', $disableAnalytics)) {
782 if (!Acl::hasAnyFormPermission($form->id)) {
783 (new \FluentForm\App\Services\Analytics\AnalyticsService())->store($form->id);
784 }
785 }
786
787 return $output . $otherScripts;
788 }
789
790 /**
791 * Process the output HTML to generate the default values.
792 *
793 * @param string $output
794 * @param \stdClass $form
795 *
796 * @return string
797 */
798 public function replaceEditorSmartCodes($output, $form)
799 {
800 // Get the patterns for default values from the output HTML string.
801 // The example of a pattern would be for user ID: {user.ID}
802 preg_match_all('/{(.*?)}/', $output, $matches);
803 $patterns = array_unique($matches[0]);
804
805 $attrDefaultValues = [];
806
807 foreach ($patterns as $pattern) {
808 // The default value for each pattern will be resolved here.
809 $attrDefaultValues[$pattern] = apply_filters_deprecated(
810 'fluentform_parse_default_value',
811 [
812 $pattern,
813 $form
814 ],
815 FLUENTFORM_FRAMEWORK_UPGRADE,
816 'fluentform/parse_default_value',
817 'Use fluentform/parse_default_value instead of fluentform_parse_default_value.'
818 );
819
820 $attrDefaultValues[$pattern] = apply_filters('fluentform/parse_default_value', $attrDefaultValues[$pattern], $form);
821 }
822
823 // Raising an event so that others can hook into it and modify the default values later.
824 $attrDefaultValues = apply_filters_deprecated(
825 'fluentform_parse_default_values',
826 [
827 $attrDefaultValues
828 ],
829 FLUENTFORM_FRAMEWORK_UPGRADE,
830 'fluentform/parse_default_values',
831 'Use fluentform/parse_default_values instead of fluentform_parse_default_values.'
832 );
833
834 $attrDefaultValues = (array) apply_filters('fluentform/parse_default_values', $attrDefaultValues);
835
836 if (isset($attrDefaultValues['{payment_total}'])) {
837 $attrDefaultValues['{payment_total}'] = '<span class="ff_order_total"></span>';
838 }
839
840 // Finally, replace the patterns with the replacements and return the output HTML.
841 return str_replace(array_keys($attrDefaultValues), array_values($attrDefaultValues), $output);
842 }
843
844 /**
845 * Register renderer actions for compiling each element
846 *
847 * @return void
848 */
849 public function addRendererActions()
850 {
851 $actionMappings = [
852 'Select@compile' => ['fluentform/render_item_select'],
853 'Rating@compile' => ['fluentform/render_item_ratings'],
854 'Address@compile' => ['fluentform/render_item_address'],
855 'Name@compile' => ['fluentform/render_item_input_name'],
856 'TextArea@compile' => ['fluentform/render_item_textarea'],
857 'DateTime@compile' => ['fluentform/render_item_input_date'],
858 'Recaptcha@compile' => ['fluentform/render_item_recaptcha'],
859 'Hcaptcha@compile' => ['fluentform/render_item_hcaptcha'],
860 'Turnstile@compile' => ['fluentform/render_item_turnstile'],
861 'Container@compile' => ['fluentform/render_item_container'],
862 'CustomHtml@compile' => ['fluentform/render_item_custom_html'],
863 'SectionBreak@compile' => ['fluentform/render_item_section_break'],
864 'SubmitButton@compile' => ['fluentform/render_item_submit_button'],
865 'SelectCountry@compile' => ['fluentform/render_item_select_country'],
866
867 'TermsAndConditions@compile' => [
868 'fluentform/render_item_terms_and_condition',
869 'fluentform/render_item_gdpr_agreement',
870 ],
871
872 'TabularGrid@compile' => [
873 'fluentform/render_item_tabular_grid',
874 ],
875
876 'Checkable@compile' => [
877 'fluentform/render_item_input_radio',
878 'fluentform/render_item_input_checkbox',
879 ],
880
881 'Text@compile' => [
882 'fluentform/render_item_input_url',
883 'fluentform/render_item_input_text',
884 'fluentform/render_item_input_email',
885 'fluentform/render_item_input_number',
886 'fluentform/render_item_input_hidden',
887 'fluentform/render_item_input_password',
888 ],
889 ];
890
891 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
892 foreach ($actionMappings as $handler => $actions) {
893 foreach ($actions as $action) {
894 $this->app->addAction($action, function () use ($path, $handler) {
895 list($class, $method) = $this->app->parseHookHandler($path . $handler);
896 call_user_func_array([$class, $method], func_get_args());
897 }, 10, 2);
898 }
899 }
900 }
901
902 /**
903 * Register dynamic value shortcode parser (filter default value)
904 *
905 * @return void
906 */
907 public function addFluentFormDefaultValueParser()
908 {
909 $this->app->addFilter('fluentform/parse_default_value', function ($value, $form) {
910 return EditorShortcodeParser::filter($value, $form);
911 }, 10, 2);
912 }
913
914 /**
915 * Register filter to check whether the form is renderable or active
916 *
917 * @return mixed
918 */
919 public function addIsRenderableFilter()
920 {
921 $this->app->addFilter('fluentform/is_form_renderable', function ($isRenderable, $form) {
922 $checkables = ['limitNumberOfEntries', 'scheduleForm', 'requireLogin'];
923
924 foreach ($form->settings['restrictions'] as $key => $restrictions) {
925 if (in_array($key, $checkables)) {
926 $isRenderable['status'] = $this->{$key}($restrictions, $form, $isRenderable);
927 if (!$isRenderable['status']) {
928 $isRenderable['status'] = false;
929 return $isRenderable;
930 }
931 }
932 }
933 if($form->status == 'unpublished'){
934 $isRenderable['status'] = false;
935 $isRenderable['message'] = apply_filters('fluentform/unpublished_form_submission_message',__('Invalid Form!'));
936 }
937
938 return $isRenderable;
939 }, 10, 2);
940 }
941
942 /**
943 * Check if limit is set on form submits and it's valid yet
944 *
945 * @param array $restrictions
946 *
947 * @return bool
948 */
949 private function limitNumberOfEntries($restrictions, $form, &$isRenderable)
950 {
951
952 if (!$restrictions['enabled'] || !isset($restrictions['period']) || !isset($restrictions['numberOfEntries'])) {
953 return true;
954 }
955
956
957 $col = 'created_at';
958 $period = $restrictions['period'];
959 $maxAllowedEntries = $restrictions['numberOfEntries'];
960
961 if (!$maxAllowedEntries) {
962 return true;
963 }
964
965 $query = wpFluent()->table('fluentform_submissions')
966 ->where('form_id', $form->id)
967 ->where('status', '!=', 'trashed');
968
969 if ('day' == $period) {
970 $year = "YEAR(`{$col}`) = YEAR(NOW())";
971 $month = "MONTH(`{$col}`) = MONTH(NOW())";
972 $day = "DAY(`{$col}`) = DAY(NOW())";
973 $query->whereRaw(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
974 } elseif ('week' == $period) {
975 $query->whereRaw(
976 wpFluent()->raw("YEARWEEK(`{$col}`, 1) = YEARWEEK(CURDATE(), 1)")
977 );
978 } elseif ('month' == $period) {
979 $year = "YEAR(`{$col}`) = YEAR(NOW())";
980 $month = "MONTH(`{$col}`) = MONTH(NOW())";
981 $query->whereRaw(wpFluent()->raw("{$year} AND {$month}"));
982 } elseif ('year' == $period) {
983 $query->whereRaw(wpFluent()->raw("YEAR(`{$col}`) = YEAR(NOW())"));
984 } elseif ('per_user_ip' == $period) {
985 $ip = $this->app->request->getIp();
986 $query->where('ip', $ip);
987 } elseif ('per_user_id' == $period) {
988 $userId = get_current_user_id();
989 if (!$userId) {
990 return true;
991 }
992 $query->where('user_id', $userId);
993 }
994
995 $count = $query->count();
996
997 if ($count >= $maxAllowedEntries) {
998 $isRenderable['message'] = $restrictions['limitReachedMsg'];
999 return false;
1000 }
1001
1002 return true;
1003 }
1004
1005 /**
1006 * Check if form has scheduled date & weekdays and open for submission
1007 *
1008 * @param array $restrictions
1009 *
1010 * @return bool
1011 */
1012 private function scheduleForm($restrictions, $form, &$isRenderable)
1013 {
1014 if (!$restrictions['enabled']) {
1015 return true;
1016 }
1017
1018 $time = time();
1019 $start = strtotime($restrictions['start']);
1020 $end = strtotime($restrictions['end']);
1021
1022 if ($time < $start) {
1023 $isRenderable['message'] = $restrictions['pendingMsg'];
1024 return false;
1025 }
1026
1027 if ($time >= $end) {
1028 $isRenderable['message'] = $restrictions['expiredMsg'];
1029
1030 return false;
1031 }
1032
1033 $weekDayToday = date('l'); //day of the week
1034 $selectedWeekDays = ArrayHelper::get($restrictions, 'selectedDays');
1035 //skip if it was not set initially and $selectedWeekDays is null
1036 if ($selectedWeekDays && is_array($selectedWeekDays) && !in_array($weekDayToday, $selectedWeekDays)) {
1037 $isRenderable['message'] = $restrictions['expiredMsg'];
1038 return false;
1039 }
1040
1041 return true;
1042 }
1043
1044 /**
1045 * * Check if form requires loged in user and user is logged in
1046 *
1047 * @param array $restrictions
1048 *
1049 * @return bool
1050 */
1051 private function requireLogin($restrictions, $form, &$isRenderable)
1052 {
1053 if (!$restrictions['enabled']) {
1054 return true;
1055 }
1056
1057 if (!($isLoggedIn = is_user_logged_in())) {
1058 $isRenderable['message'] = $restrictions['requireLoginMsg'];
1059 }
1060
1061 return $isLoggedIn;
1062 }
1063
1064 /**
1065 * Register fluentform_submission_inserted actions
1066 *
1067 * @return void
1068 */
1069 public function addFluentformSubmissionInsertedFilter()
1070 {
1071 (new EmailNotificationActions($this->app))->register();
1072 }
1073
1074 /**
1075 * Add inline scripts [Add localized script using same var]
1076 *
1077 * @return void
1078 */
1079 private function addInlineVars()
1080 {
1081 if (!defined('ELEMENTOR_PRO_VERSION') || $this->elementorPopUpHandler) {
1082 return '';
1083 }
1084
1085 // Previously this handler was registered for every form
1086 // in a single page. So multiple event handlers were
1087 // registered. This flag ensures the handler is
1088 // registered just once, since one is enough!
1089 $this->elementorPopUpHandler = true;
1090
1091 $actionName = 'wp_footer';
1092 if (is_admin()) {
1093 $actionName = 'admin_footer';
1094 }
1095
1096 add_action($actionName, function () {
1097 ?>
1098 <script type="text/javascript">
1099 <?php if (defined('ELEMENTOR_PRO_VERSION')): ?>
1100
1101 window.addEventListener('elementor/popup/show', function (e) {
1102 var ffForms = jQuery('#elementor-popup-modal-' + e.detail.id).find('form.frm-fluent-form');
1103
1104 /**
1105 * Support conversation form in elementor popup
1106 * No regular form found, check for conversational form
1107 */
1108 if (!ffForms.length) {
1109 const elements = document.getElementsByClassName('ffc_conv_form');
1110 if (elements.length) {
1111 let jsEvent = new CustomEvent('ff-elm-conv-form-event', {
1112 detail: elements
1113 });
1114 document.dispatchEvent(jsEvent);
1115 }
1116 }
1117 if (ffForms.length) {
1118 jQuery.each(ffForms, function(index, ffForm) {
1119 jQuery(ffForm).trigger('reInitExtras');
1120 jQuery(document).trigger('ff_reinit', [ffForm]);
1121 });
1122 }
1123 });
1124 <?php endif; ?>
1125 </script>
1126 <?php
1127 }, 999);
1128 return '';
1129 }
1130
1131 public static function getDatei18n()
1132 {
1133 $i18n = [
1134 'previousMonth' => __('Previous Month', 'fluentform'),
1135 'nextMonth' => __('Next Month', 'fluentform'),
1136 'months' => [
1137 'shorthand' => [
1138 __('Jan', 'fluentform'),
1139 __('Feb', 'fluentform'),
1140 __('Mar', 'fluentform'),
1141 __('Apr', 'fluentform'),
1142 __('May', 'fluentform'),
1143 __('Jun', 'fluentform'),
1144 __('Jul', 'fluentform'),
1145 __('Aug', 'fluentform'),
1146 __('Sep', 'fluentform'),
1147 __('Oct', 'fluentform'),
1148 __('Nov', 'fluentform'),
1149 __('Dec', 'fluentform'),
1150 ],
1151 'longhand' => [
1152 __('January', 'fluentform'),
1153 __('February', 'fluentform'),
1154 __('March', 'fluentform'),
1155 __('April', 'fluentform'),
1156 __('May', 'fluentform'),
1157 __('June', 'fluentform'),
1158 __('July', 'fluentform'),
1159 __('August', 'fluentform'),
1160 __('September', 'fluentform'),
1161 __('October', 'fluentform'),
1162 __('November', 'fluentform'),
1163 __('December', 'fluentform'),
1164 ],
1165 ],
1166 'weekdays' => [
1167 'longhand' => [
1168 __('Sunday', 'fluentform'),
1169 __('Monday', 'fluentform'),
1170 __('Tuesday', 'fluentform'),
1171 __('Wednesday', 'fluentform'),
1172 __('Thursday', 'fluentform'),
1173 __('Friday', 'fluentform'),
1174 __('Saturday', 'fluentform'),
1175 ],
1176 'shorthand' => [
1177 __('Sun', 'fluentform'),
1178 __('Mon', 'fluentform'),
1179 __('Tue', 'fluentform'),
1180 __('Wed', 'fluentform'),
1181 __('Thu', 'fluentform'),
1182 __('Fri', 'fluentform'),
1183 __('Sat', 'fluentform'),
1184 ],
1185 ],
1186 'daysInMonth' => [
1187 31,
1188 28,
1189 31,
1190 30,
1191 31,
1192 30,
1193 31,
1194 31,
1195 30,
1196 31,
1197 30,
1198 31,
1199 ],
1200 'rangeSeparator' => __(' to ', 'fluentform'),
1201 'weekAbbreviation' => __('Wk', 'fluentform'),
1202 'scrollTitle' => __('Scroll to increment', 'fluentform'),
1203 'toggleTitle' => __('Click to toggle', 'fluentform'),
1204 'amPM' => [
1205 __('AM', 'fluentform'),
1206 __('PM', 'fluentform'),
1207 ],
1208 'yearAriaLabel' => __('Year', 'fluentform'),
1209 'firstDayOfWeek' => (int) get_option('start_of_week'),
1210 ];
1211
1212 return apply_filters('fluentform/date_i18n', $i18n);
1213 }
1214
1215 protected function maybeHasAdvandedFields($form, $formBuilder)
1216 {
1217 $advancedFields = [
1218 'step_start',
1219 'repeater_field',
1220 'ratings',
1221 'form_step',
1222 'input_file',
1223 'input_image',
1224 'net_promoter_score',
1225 'featured_image',
1226 ];
1227 if ($formBuilder->conditions || array_intersect($formBuilder->fieldLists, $advancedFields)) {
1228 wp_enqueue_script('fluentform-advanced');
1229 }
1230 }
1231
1232 public function registerInputSanitizers()
1233 {
1234 add_filter('fluentform/input_data_input_number', [$this, 'getNumericInputValue'], 10, 2);
1235 add_filter('fluentform/input_data_custom_payment_component', [$this, 'getNumericInputValue'], 10, 2);
1236 }
1237
1238 public function getNumericInputValue($value, $field)
1239 {
1240 $formatter = ArrayHelper::get($field, 'raw.settings.numeric_formatter');
1241 if (!$formatter) {
1242 return $value;
1243 }
1244 return Helper::getNumericValue($value, $formatter);
1245 }
1246
1247
1248 public function registerHelperShortCodes()
1249 {
1250 $this->app->addShortCode('fluentform_info', function ($atts) {
1251 $data = [
1252 'id' => null, // This is the form id
1253 'info' => 'submission_count', // submission_count | created_at | updated_at | payment_total
1254 'status' => 'all', // get submission cound of a particular entry status favourites | unread | read
1255 'with_trashed' => 'no', // yes | no
1256 'substract_from' => 0, // [fluentform_info id="2" info="submission_count" substract_from="20"]
1257 'hide_on_zero' => 'no',
1258 'payment_status' => 'all', // it can be all / specific payment status
1259 'currency_formatted' => 'yes',
1260 'date_format' => '',
1261 ];
1262 /* This filter is deprecated, will be removed soon */
1263 $data = apply_filters('fluentform_info_shortcode_defaults', $data, $atts );
1264
1265 $shortcodeDefaults = apply_filters('fluentform/info_shortcode_defaults', $data, $atts);
1266
1267 $atts = shortcode_atts($shortcodeDefaults, $atts);
1268 $formId = $atts['id'];
1269 $form = wpFluent()->table('fluentform_forms')->find($formId);
1270
1271 if (!$form) {
1272 return '';
1273 }
1274
1275 if ('submission_count' == $atts['info']) {
1276 $countQuery = wpFluent()->table('fluentform_submissions')
1277 ->where('form_id', $formId);
1278
1279 if ('trashed' != $atts['status'] && 'no' == $atts['with_trashed']) {
1280 $countQuery = $countQuery->where('status', '!=', 'trashed');
1281 }
1282
1283 if ('all' == $atts['status']) {
1284 // ...
1285 } elseif ('favourites' == $atts['status']) {
1286 $countQuery = $countQuery->where('is_favourite', '=', 1);
1287 } else {
1288 $countQuery = $countQuery->where('status', '=', sanitize_key($atts['status']));
1289 }
1290 if ($atts['payment_status'] && defined('FLUENTFORMPRO') && 'all' != $atts['payment_status']) {
1291 $countQuery = $countQuery->where('payment_status', '=', sanitize_key($atts['payment_status']));
1292 }
1293
1294 $total = $countQuery->count();
1295
1296 if ($atts['substract_from']) {
1297 $total = intval($atts['substract_from']) - $total;
1298 }
1299
1300 if ('yes' == $atts['hide_on_zero'] && !$total || $total < 0) {
1301 return '';
1302 }
1303
1304 return $total;
1305 } elseif ('created_at' == $atts['info']) {
1306 if ($atts['date_format']) {
1307 $dateFormat = $atts['date_format'];
1308 } else {
1309 $dateFormat = get_option('date_format') . ' ' . get_option('time_format');
1310 }
1311 return date($dateFormat, strtotime($form->created_at));
1312 } elseif ('updated_at' == $atts['info']) {
1313 if ($atts['date_format']) {
1314 $dateFormat = $atts['date_format'];
1315 } else {
1316 $dateFormat = get_option('date_format') . ' ' . get_option('time_format');
1317 }
1318 return date($dateFormat, strtotime($form->updated_at));
1319 } elseif ('payment_total' == $atts['info']) {
1320 if (!defined('FLUENTFORMPRO')) {
1321 return '';
1322 }
1323
1324 global $wpdb;
1325 $countQuery = wpFluent()
1326 ->table('fluentform_submissions')
1327 ->select(wpFluent()->raw('SUM(payment_total) as payment_total'))
1328 ->where('form_id', $formId);
1329
1330 if ('trashed' != $atts['status'] && 'no' == $atts['with_trashed']) {
1331 $countQuery = $countQuery->where('status', '!=', 'trashed');
1332 }
1333
1334 if ('all' == $atts['status']) {
1335 // ...
1336 } elseif ('favourites' == $atts['status']) {
1337 $countQuery = $countQuery->where('is_favourite', '=', 1);
1338 } else {
1339 $countQuery = $countQuery->where('status', '=', sanitize_key($atts['status']));
1340 }
1341
1342 if ('all' == $atts['payment_status']) {
1343 // ...
1344 } elseif ($atts['payment_status']) {
1345 $countQuery = $countQuery->where('payment_status', '=', sanitize_key($atts['payment_status']));
1346 }
1347
1348 $row = $countQuery->first();
1349
1350 $total = 0;
1351 if ($row) {
1352 $total = $row->payment_total;
1353 }
1354
1355 if ($atts['substract_from']) {
1356 $total = intval($atts['substract_from'] * 100) - $total;
1357 }
1358
1359 if ('yes' == $atts['hide_on_zero'] && !$total) {
1360 return '';
1361 }
1362
1363 if ('yes' == $atts['currency_formatted']) {
1364 $currency = \FluentFormPro\Payments\PaymentHelper::getFormCurrency($formId);
1365 return \FluentFormPro\Payments\PaymentHelper::formatMoney($total, $currency);
1366 }
1367
1368 if (!$total) {
1369 return 0;
1370 }
1371
1372 return $total / 100;
1373 }
1374
1375 return '';
1376 });
1377
1378 $this->app->addShortCode('ff_get', function ($atts) {
1379 $atts = shortcode_atts([
1380 'param' => '',
1381 ], $atts);
1382
1383 $value = $this->app->request->get($atts['param']);
1384
1385 if ($atts['param'] && $value) {
1386 if (is_array($value)) {
1387 return implode(', ', $value);
1388 }
1389 return esc_html($value);
1390 }
1391 return '';
1392 });
1393
1394 $this->app->addShortcode('ff_entry',function($atts){
1395 ob_start();
1396
1397 $atts = shortcode_atts([
1398 'form_id' => '',
1399 'serial_number' => '',
1400 'field' => '',
1401 'is_html' => true,
1402 ], $atts);
1403
1404 if (empty($atts['form_id']) || empty($atts['field'])) {
1405 return '';
1406 }
1407
1408
1409 $formId = (int) $atts['form_id'];
1410 $form = wpFluent()->table('fluentform_forms')->find($formId);
1411 if (!$form) {
1412 return __('Form not found.', 'fluentform');
1413 }
1414 $isHtml = $atts['is_html'] === 'true' ? true : false;
1415 $submission = (new \FluentForm\App\Services\Submission\SubmissionService())->findBySerialID($formId, $atts['serial_number'],$isHtml);
1416 if (!$submission) {
1417 return __('No entry found.', 'fluentform');
1418 }
1419
1420 $input = $submission->user_inputs;
1421 $field = sanitize_text_field($atts['field']);
1422 $fieldVal = ArrayHelper::get($input, $field, '');
1423
1424 $response = FormDataParser::formatValue($fieldVal);
1425 echo $atts['is_html'] ? wp_kses_post($response) : esc_html($response);
1426
1427 return ob_get_clean();
1428 });
1429
1430 }
1431 }
1432