PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.6
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.6
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 6.2.6, at app/Modules/Component/Component.php

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