PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.14
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.14
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
← All changes | app/Modules/Component/Component.php +1025 -427 3.6.226.2.14 View file →
@@ -1,15 +1,20 @@
1 1 <?php
2 2
3 3 namespace FluentForm\App\Modules\Component;
4 4
5 +defined('ABSPATH') or die;
6 +
5 7 use FluentForm\App\Helpers\Helper;
6 8 use FluentForm\App\Modules\Acl\Acl;
9 +use FluentForm\App\Modules\Form\FormDataParser;
7 10 use FluentForm\App\Services\FormBuilder\EditorShortcodeParser;
8 11 use FluentForm\App\Services\FormBuilder\Notifications\EmailNotificationActions;
9 12 use FluentForm\Framework\Foundation\Application;
10 13 use FluentForm\Framework\Helpers\ArrayHelper;
14 +use FluentForm\Framework\Helpers\ArrayHelper as Arr;
11 15
16 +
12 17 class Component
13 18 {
14 19 /**
15 20 * FluentForm\Framework\Foundation\Application
@@ -18,8 +23,15 @@
18 23 */
19 24 protected $app = null;
20 25
21 26 /**
27 + * Determine whether to register Elementor PopUp handler.
28 + *
29 + * @var bool
30 + */
31 + protected $elementorPopUpHandler = false;
32 +
33 + /**
22 34 * Biuld the instance of this class
23 35 *
24 36 * @param \FluentForm\Framework\Foundation\Application $app
25 37 */
@@ -33,20 +45,20 @@
33 45 $app = $this->app;
34 46
35 47 // We will just register the scripts here. We will not load any scripts from here
36 48
37 - $fluentFormPublicCss = $app->publicUrl('css/fluent-forms-public.css');
38 - $fluentFormPublicDefaultCss = $app->publicUrl('css/fluentform-public-default.css');
49 + $fluentFormPublicCss = fluentFormMix('css/fluent-forms-public.css');
50 + $fluentFormPublicDefaultCss = fluentFormMix('css/fluentform-public-default.css');
39 51
40 52 if (is_rtl()) {
41 - $fluentFormPublicCss = $app->publicUrl('css/fluent-forms-public-rtl.css');
42 - $fluentFormPublicDefaultCss = $app->publicUrl('css/fluentform-public-default-rtl.css');
53 + $fluentFormPublicCss = fluentFormMix('css/fluent-forms-public-rtl.css');
54 + $fluentFormPublicDefaultCss = fluentFormMix('css/fluentform-public-default-rtl.css');
43 55 }
44 56
45 57 wp_register_style(
46 58 'fluent-form-styles',
47 59 $fluentFormPublicCss,
48 - array(),
60 + [],
49 61 FLUENTFORM_VERSION
50 62 );
51 63
52 64 wp_register_style(
@@ -51,16 +63,16 @@
51 63
52 64 wp_register_style(
53 65 'fluentform-public-default',
54 66 $fluentFormPublicDefaultCss,
55 - array(),
67 + [],
56 68 FLUENTFORM_VERSION
57 69 );
58 70
59 71 wp_register_script(
60 72 'fluent-form-submission',
61 - $app->publicUrl('js/form-submission.js'),
62 - array('jquery'),
73 + fluentFormMix('js/form-submission.js'),
74 + ['jquery'],
63 75 FLUENTFORM_VERSION,
64 76 true
65 77 );
66 78
@@ -65,43 +77,67 @@
65 77 );
66 78
67 79 wp_register_script(
68 80 'fluentform-advanced',
69 - $app->publicUrl('js/fluentform-advanced.js'),
70 - array('jquery', 'fluent-form-submission'),
81 + fluentFormMix('js/fluentform-advanced.js'),
82 + ['jquery'],
71 83 FLUENTFORM_VERSION,
72 84 true
73 85 );
74 86
75 87 // Date Pickckr Style
76 - wp_register_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(
77 99 'flatpickr',
78 - $app->publicUrl('libs/flatpickr/flatpickr.min.css')
100 + fluentFormMix('libs/flatpickr/flatpickr.min.js'),
101 + ['jquery'],
102 + '4.6.9',
103 + true
79 104 );
80 105
81 - // Date Pickckr Script
82 106 wp_register_script(
83 - 'flatpickr',
84 - $app->publicUrl('libs/flatpickr/flatpickr.js'),
85 - array('jquery'),
86 - false,
107 + 'choices',
108 + fluentFormMix('libs/choices/choices.min.js'),
109 + [],
110 + '9.0.1',
87 111 true
88 112 );
89 113
114 + wp_register_style(
115 + 'ff_choices',
116 + fluentFormMix('css/choices.css'),
117 + [],
118 + FLUENTFORM_VERSION
119 + );
120 +
90 121 wp_register_script(
91 - 'selectWoo',
92 - $app->publicUrl('libs/selectWoo/selectWoo.full.min.js'),
93 - array('jquery'),
94 - '1.0.6',
122 + 'form-save-progress',
123 + fluentFormMix('js/form-save-progress.js'),
124 + ['jquery'],
125 + FLUENTFORM_VERSION,
95 126 true
96 127 );
97 128
98 - wp_register_style(
99 - 'select2',
100 - $app->publicUrl('libs/selectWoo/select2.css')
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.'
101 137 );
102 138
103 - do_action('fluentform_scripts_registered');
139 + $this->app->doAction('fluentform/scripts_registered');
104 140
105 141 $this->maybeLoadFluentFormStyles();
106 142 }
107 143
@@ -108,49 +144,110 @@
108 144 protected function maybeLoadFluentFormStyles()
109 145 {
110 146 global $post;
111 147
112 - if (!$post) {
148 + $postId = isset($post->ID) ? $post->ID : false;
149 + if (!$postId) {
113 150 return;
114 151 }
152 + $fluentFormIds = get_post_meta($postId, '_has_fluentform', true);
153 + $hasFluentformMeta = is_a($post, 'WP_Post') && $fluentFormIds;
115 154
116 - $fluentFormIds = get_post_meta($post->ID, '_has_fluentform', true);
117 - $hasFluentformMeta = is_a($post, 'WP_Post') && $fluentFormIds;
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 + );
118 165
119 - if ($hasFluentformMeta || apply_filters('fluentform_load_styles', false, $post)) {
166 + if ($hasFluentformMeta || apply_filters('fluentform/load_styles', $loadStyle, $post)) {
120 167 wp_enqueue_style('fluent-form-styles');
121 - wp_enqueue_style('fluentform-public-default');
122 - do_action('fluentform_pre_load_scripts', $post);
123 - wp_enqueue_script('fluent-form-submission');
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 + }
124 199 }
125 200 }
126 201
127 202 /**
128 203 * Get all the available components
204 + * @deprecated Use \FluentForm\App\Http\Controllers\FormController::resources
205 + * @return void
129 206 *
130 - * @return void
131 207 * @throws \Exception
132 208 * @throws \FluentForm\Framework\Exception\UnResolveableEntityException
133 209 */
134 210 public function index()
135 211 {
136 - $this->app->doAction(
212 + $formId = intval($this->app->request->get('formId'));
213 +
214 + $components = $this->app->make('components');
215 +
216 + do_action_deprecated(
137 217 'fluent_editor_init',
138 - $components = $this->app->make('components')
218 + [
219 + $components
220 + ],
221 + FLUENTFORM_FRAMEWORK_UPGRADE,
222 + 'fluentform/editor_init',
223 + 'Use fluentform/editor_init instead of fluent_editor_init.'
139 224 );
140 225
226 + $this->app->doAction('fluentform/editor_init', $components);
227 +
141 228 $editorComponents = $components->sort()->toArray();
142 - $editorComponents = $this->app->applyFilters('fluent_editor_components', $editorComponents);
143 - $countries = $this->app->load($this->app->appPath('Services/FormBuilder/CountryNames.php'));
144 229
145 - wp_send_json_success(array(
146 - 'countries' => $countries,
147 - 'components' => $editorComponents,
148 - 'disabled_components' => $this->getDisabledComponents()
149 - ));
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 + ]);
150 248 }
151 249
152 -
153 250 /**
154 251 * Get disabled components
155 252 *
156 253 * @return array
@@ -157,82 +254,185 @@
157 254 */
158 255 private function getDisabledComponents()
159 256 {
160 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);
161 260
162 - $disabled = array(
163 - 'recaptcha' => array(
164 - 'contentComponent' => 'recaptcha',
165 - 'disabled' => $isReCaptchaDisabled
166 - ),
167 - 'input_image' => array(
168 - 'disabled' => true
169 - ),
170 - 'input_file' => array(
171 - 'disabled' => true
172 - ),
173 - 'shortcode' => array(
174 - 'disabled' => true
175 - ),
176 - 'action_hook' => array(
177 - 'disabled' => true
178 - ),
179 - 'form_step' => array(
180 - 'disabled' => true
181 - )
182 - );
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 + ];
183 316
184 - if (!defined('FLUENTFORMPRO')) {
185 - $disabled['ratings'] = array(
186 - 'disabled' => true
187 - );
188 - $disabled['tabular_grid'] = array(
189 - 'disabled' => true
190 - );
191 - $disabled['phone'] = array(
192 - 'disabled' => true
193 - );
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 + }
194 424
195 - $disabled['net_promoter_score'] = array(
196 - 'disabled' => true
197 - );
198 -
199 - $disabled['repeater_field'] = array(
200 - 'disabled' => true
201 - );
202 -
203 - $disabled['custom_submit_button'] = array(
204 - 'disabled' => true
205 - );
206 -
207 - $disabled['rangeslider'] = array(
208 - 'disabled' => true
209 - );
210 -
211 - $disabled['color-picker'] = array(
212 - 'disabled' => true
213 - );
214 -
215 - $disabled['multi_payment_component'] = array(
216 - 'disabled' => true,
217 - 'is_payment' => true
218 - );
219 - $disabled['custom_payment_component'] = array(
220 - 'disabled' => true,
221 - 'is_payment' => true
222 - );
223 -
224 - $disabled['item_quantity_component'] = array(
225 - 'disabled' => true,
226 - 'is_payment' => true
227 - );
228 -
229 - $disabled['payment_method'] = array(
230 - 'disabled' => true,
231 - 'is_payment' => true
232 - );
233 - }
234 - return $this->app->applyFilters('fluentform_disabled_components', $disabled);
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);
235 435 }
236 436
237 437 /**
238 438 * Get available shortcodes for editor
@@ -237,8 +437,9 @@
237 437 /**
238 438 * Get available shortcodes for editor
239 439 *
240 440 * @return void
441 + *
241 442 * @throws \Exception
242 443 */
243 444 public function getEditorShortcodes()
244 445 {
@@ -246,11 +447,13 @@
246 447 wp_send_json_success(['shortcodes' => $editor_shortcodes], 200);
247 448 }
248 449
249 450 /**
451 + * @deprecated Use \FluentForm\App\Services\Form\FormService::shortcodes
250 452 * Get all available shortcodes for editor
251 453 *
252 454 * @return void
455 + *
253 456 * @throws \Exception
254 457 */
255 458 public function getAllEditorShortcodes()
256 459 {
@@ -261,332 +464,389 @@
261 464
262 465 /**
263 466 * Register the form renderer shortcode
264 467 *
265 - * @return void
468 + * @return void
266 469 */
267 470 public function addFluentFormShortCode()
268 471 {
269 - add_action('wp_enqueue_scripts', array($this, 'registerScripts'), 999);
472 + add_action('wp_enqueue_scripts', [$this, 'registerScripts'], 9);
270 473
271 474 $this->app->addShortCode('fluentform', function ($atts, $content) {
272 - $shortcodeDefaults = apply_filters('fluentform_shortcode_defaults', array(
273 - 'id' => null,
274 - 'title' => null,
275 - 'permission' => '',
475 + $data = [
476 + 'id' => null,
477 + 'title' => null,
478 + 'css_classes' => '',
479 + 'permission' => '',
480 + 'type' => 'classic',
481 + 'theme' => '',
276 482 'permission_message' => __('Sorry, You do not have permission to view this form', 'fluentform')
277 - ), $atts);
483 + ];
484 + /* This filter is deprecated, will be removed soon */
485 + $data = apply_filters('fluentform_shortcode_defaults', $data, $atts );
278 486
279 - $atts = shortcode_atts($shortcodeDefaults, $atts);
280 - return $this->renderForm($atts);
281 - });
487 + $shortcodeDefaults = apply_filters('fluentform/shortcode_defaults', $data, $atts);
282 488
283 - $this->app->addShortCode('fluentform_info', function ($atts) {
284 - $shortcodeDefaults = apply_filters('fluentform_info_shortcode_defaults', array(
285 - 'id' => null, // This is the form id
286 - 'info' => 'submission_count', // submission_count | created_at | updated_at | payment_total
287 - 'status' => 'all', // get submission cound of a particular entry status favourites | unread | read
288 - 'with_trashed' => 'no', // yes | no
289 - 'substract_from' => 0, // [fluentform_info id="2" info="submission_count" substract_from="20"]
290 - 'hide_on_zero' => 'no',
291 - 'payment_status' => 'paid', // it can be all / specific payment status
292 - 'currency_formatted' => 'yes',
293 - 'date_format' => ''
294 - ), $atts);
295 -
296 489 $atts = shortcode_atts($shortcodeDefaults, $atts);
297 - $formId = $atts['id'];
298 - $form = wpFluent()->table('fluentform_forms')->find($formId);
299 490
300 - if (!$form) {
301 - return '';
302 - }
303 -
304 - if ($atts['info'] == 'submission_count') {
305 - $countQuery = wpFluent()->table('fluentform_submissions')
306 - ->where('form_id', $formId);
307 -
308 - if ($atts['status'] != 'trashed' && $atts['with_trashed'] == 'no') {
309 - $countQuery = $countQuery->where('status', '!=', 'trashed');
310 - }
311 -
312 - if ($atts['status'] == 'all') {
313 - // ...
314 - } else if ($atts['status'] == 'favourites') {
315 - $countQuery = $countQuery->where('is_favourite', '=', 1);
316 - } else {
317 - $countQuery = $countQuery->where('status', '=', sanitize_text_field($atts['status']));
318 - }
319 -
320 - $total = $countQuery->count();
321 -
322 - if ($atts['substract_from']) {
323 - $total = intval($atts['substract_from']) - $total;
324 - }
325 -
326 - if ($atts['hide_on_zero'] == 'yes' && !$total || $total < 0) {
327 - return '';
328 - }
329 -
330 - return $total;
331 - } else if ($atts['info'] == 'created_at') {
332 - if ($atts['date_format']) {
333 - $dateFormat = $atts['date_format'];
334 - } else {
335 - $dateFormat = get_option('date_format') . ' ' . get_option('time_format');
336 - }
337 - return date($dateFormat, strtotime($form->created_at));
338 - } else if ($atts['info'] == 'updated_at') {
339 - if ($atts['date_format']) {
340 - $dateFormat = $atts['date_format'];
341 - } else {
342 - $dateFormat = get_option('date_format') . ' ' . get_option('time_format');
343 - }
344 - return date($dateFormat, strtotime($form->updated_at));
345 - } else if ($atts['info'] == 'payment_total') {
346 -
347 - if (!defined('FLUENTFORMPRO')) {
348 - return '';
349 - }
350 -
351 - global $wpdb;
352 - $countQuery = wpFluent()
353 - ->table('fluentform_submissions')
354 - ->select(wpFluent()->raw('SUM(total_paid) as payment_total'))
355 - ->where('form_id', $formId);
356 -
357 - if ($atts['status'] != 'trashed' && $atts['with_trashed'] == 'no') {
358 - $countQuery = $countQuery->where('status', '!=', 'trashed');
359 - }
360 -
361 - if ($atts['status'] == 'all') {
362 - // ...
363 - } else if ($atts['status'] == 'favourites') {
364 - $countQuery = $countQuery->where('is_favourite', '=', 1);
365 - } else {
366 - $countQuery = $countQuery->where('status', '=', sanitize_text_field($atts['status']));
367 - }
368 -
369 - if ($atts['payment_status'] == 'all') {
370 - // ...
371 - } else if ($atts['payment_status']) {
372 - $countQuery = $countQuery->where('payment_status', '=', sanitize_text_field($atts['payment_status']));
373 - }
374 -
375 - $row = $countQuery->first();
376 -
377 - $total = 0;
378 - if ($row) {
379 - $total = $row->payment_total;
380 - }
381 -
382 - if ($atts['substract_from']) {
383 - $total = intval($atts['substract_from'] * 100) - $total;
384 - }
385 -
386 - if ($atts['hide_on_zero'] == 'yes' && !$total) {
387 - return '';
388 - }
389 -
390 - if ($atts['currency_formatted'] == 'yes') {
391 - $currency = \FluentFormPro\Payments\PaymentHelper::getFormCurrency($formId);
392 - return \FluentFormPro\Payments\PaymentHelper::formatMoney($total, $currency);
393 - }
394 -
395 - if (!$total) {
396 - return 0;
397 - }
398 -
399 - return $total / 100;
400 - }
401 -
402 - return '';
491 + return $this->renderForm($atts);
403 492 });
404 -
405 - $this->app->addShortCode('ff_get', function ($atts) {
406 - $atts = shortcode_atts(array(
407 - 'param' => '',
408 - ), $atts);
409 - if ($atts['param'] && isset($_GET[$atts['param']])) {
410 - $value = $_GET[$atts['param']];
411 - if (is_array($value)) {
412 - return implode(', ', $value);
413 - }
414 - return esc_html($value);
415 - }
416 - return '';
417 - });
418 -
493 +
494 + $this->registerHelperShortCodes();
419 495 }
420 496
421 497 public function renderForm($atts)
422 498 {
423 499 $form_id = $atts['id'];
424 -
500 + $query = wpFluent()->table('fluentform_forms');
501 +
502 + if (! $this->app->request->get('preview_id')) {
503 + $query->where('status', 'published');
504 + }
505 +
425 506 if ($form_id) {
426 - $form = wpFluent()->table('fluentform_forms')->find($form_id);
427 - } else if ($formTitle = $atts['title']) {
428 - $form = wpFluent()->table('fluentform_forms')->where('title', $formTitle)->first();
507 + $form = $query->find($form_id);
508 + } elseif ($formTitle = $atts['title']) {
509 + $form = $query->where('title', $formTitle)->first();
429 510 } else {
430 - return;
511 + return '';
431 512 }
432 513
433 514 if (!$form) {
434 - return;
515 + return '';
435 516 }
436 517
437 518 if (!empty($atts['permission'])) {
438 519 if (!current_user_can($atts['permission'])) {
439 - return "<div id='ff_form_{$form->id}' class='ff_form_not_render'>{$atts['permission_message']}</div>";
520 + return $this->getNotRenderableHtml($form->id, $atts['permission_message']);
440 521 }
441 522 }
442 523
443 - if(is_feed()) {
524 + if (is_feed()) {
444 525 global $post;
445 - $feedText = sprintf( __( 'The form can be filled in the actual <a href="%s">website url</a>.', 'fluentform' ), get_permalink($post));
446 - $feedText = apply_filters('fluentform_shortcode_feed_text', $feedText, $form);
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);
447 541 return $feedText;
448 542 }
543 +
544 + $form->settings = Helper::getFormMeta($form->id, 'formSettings', []);
449 545
450 - $formSettings = wpFluent()
451 - ->table('fluentform_form_meta')
452 - ->where('form_id', $form_id)
453 - ->where('meta_key', 'formSettings')
454 - ->first();
455 -
456 - if (!$formSettings) {
457 - return;
546 + if (empty($form->settings)) {
547 + return '';
458 548 }
459 549
460 550 $form->fields = json_decode($form->form_fields, true);
461 -
462 - if (!$form->fields['fields']) {
463 - return;
551 + if (!is_array($form->fields) || empty($form->fields['fields'])) {
552 + return '';
464 553 }
465 554
466 - $form->settings = json_decode($formSettings->value, true);
467 - $form = $this->app->applyFilters('fluentform_rendering_form', $form);
468 -
469 - $isRenderable = array(
470 - 'status' => true,
471 - 'message' => ''
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.'
472 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);
473 573
474 - $isRenderable = $this->app->applyFilters('fluentform_is_form_renderable', $isRenderable, $form);
475 -
476 574 if (is_array($isRenderable) && !$isRenderable['status']) {
477 - return "<div id='ff_form_{$form->id}' class='ff_form_not_render'>{$isRenderable['message']}</div>";
575 + return $this->getNotRenderableHtml($form->id, $isRenderable['message']);
478 576 }
479 577
480 578 $instanceCssClass = Helper::getFormInstaceClass($form->id);
481 579
482 580 $form->instance_css_class = $instanceCssClass;
581 + $form->instance_index = Helper::$formInstance;
483 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 +
484 590 $formBuilder = $this->app->make('formBuilder');
485 - $output = $formBuilder->build($form, $instanceCssClass . ' ff-form-loading', $instanceCssClass);
591 +
592 + $cssClasses = trim($instanceCssClass . ' ff-form-loading');
593 +
594 + $output = $formBuilder->build($form, $cssClasses, $instanceCssClass, $atts);
595 +
486 596 $output = $this->replaceEditorSmartCodes($output, $form);
487 597
488 -
489 598 if (!wp_script_is('fluent-form-submission', 'registered')) {
490 599 $this->registerScripts();
491 600 }
492 601
493 602 wp_enqueue_style('fluent-form-styles');
494 - if (apply_filters('fluentform_load_default_public', true, $form)) {
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)) {
495 617 wp_enqueue_style('fluentform-public-default');
496 618 }
497 - wp_enqueue_script('fluent-form-submission');
498 -
499 619 /*
500 620 * We will load fluentform-advanced if the form has certain fields or feature
501 621 */
502 622 $this->maybeHasAdvandedFields($form, $formBuilder);
623 + if (!Helper::isElementorEditor()) {
624 + wp_enqueue_script('fluent-form-submission');
625 + }
503 626
627 + /* translators: %activeStep% is the current step number, %totalStep% is the total number of steps, %stepTitle% is the step title */
504 628 $stepText = __('Step %activeStep% of %totalStep% - %stepTitle%', 'fluentform');
505 - $stepText = apply_filters('fluentform_step_string', $stepText);
506 - $vars = apply_filters('fluentform_global_form_vars', array(
507 - 'ajaxUrl' => admin_url('admin-ajax.php'),
508 - 'forms' => array(),
509 - 'step_text' => $stepText,
510 - 'is_rtl' => is_rtl(),
511 - 'date_i18n' => $this->getDatei18n(),
512 - 'pro_version' => (defined('FLUENTFORMPRO_VERSION')) ? FLUENTFORMPRO_VERSION : false,
513 - 'fluentform_version' => FLUENTFORM_VERSION,
514 - 'force_init' => false,
515 - 'stepAnimationDuration' => 350,
516 - 'upload_completed_txt' => __('100% Completed', 'fluentform'),
517 - 'upload_start_txt' => __('0% Completed', 'fluentform'),
518 - 'uploading_txt' => __('Uploading', 'fluentform')
519 - ));
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 + );
520 639
521 - wp_localize_script('fluent-form-submission', 'fluentFormVars', $vars);
640 + $stepText = apply_filters('fluentform/step_string', $stepText);
522 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 +
523 714 $formSettings = $form->settings;
524 715
525 716 $formSettings = ArrayHelper::only($formSettings, ['layout', 'id']);
526 717
718 + // Ensure restrictions array exists before setting denyEmptySubmission
719 + if (!isset($formSettings['restrictions']) || !is_array($formSettings['restrictions'])) {
720 + $formSettings['restrictions'] = [];
721 + }
722 +
527 723 $formSettings['restrictions']['denyEmptySubmission'] = [
528 - 'enabled' => false
724 + 'enabled' => false,
529 725 ];
530 726
727 + if (!empty($formBuilder->validationRules)) {
728 + $formBuilder->validationRules = fluentform_backend_sanitizer($formBuilder->validationRules, [
729 + 'message' => 'fluentform_sanitize_html'
730 + ]);
731 + }
531 732
532 - $form_vars = array(
533 - 'id' => $form->id,
534 - 'settings' => $formSettings,
535 - 'form_instance' => $instanceCssClass,
733 + $form_vars = [
734 + 'id' => $form->id,
735 + 'ajaxUrl' => admin_url('admin-ajax.php'),
736 + 'settings' => $formSettings,
737 + 'form_instance' => $instanceCssClass,
536 738 'form_id_selector' => 'fluentform_' . $form->id,
537 - 'rules' => $formBuilder->validationRules
538 - );
739 + 'rules' => $formBuilder->validationRules,
740 + 'debounce_time' => apply_filters('fluentform/show_hide_elements_debounce_time', 300),
741 + ];
539 742
540 743 if ($conditionals = $formBuilder->conditions) {
541 744 $form_vars['conditionals'] = $conditionals;
542 745 }
543 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 +
544 755 if ($form->has_payment) {
545 - do_action('fluentform_rending_payment_form', $form);
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);
546 766 }
547 767
548 768 $otherScripts = '';
549 - ob_start();
550 - ?>
551 - <script type="text/javascript">
552 - window.fluent_form_<?php echo $instanceCssClass; ?> = <?php echo json_encode($form_vars);?>;
553 - <?php if(wp_doing_ajax()): ?>
554 - function initFFInstance_<?php echo $form_vars['id']; ?>() {
555 - if(!window.fluentFormApp) {
556 - console.log('No fluentFormApp found');
557 - return;
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 + }
558 788 }
559 - var ajax_formInstance = window.fluentFormApp(jQuery('form.<?php echo $form_vars['form_instance']; ?>'));
560 - if (ajax_formInstance) {
561 - ajax_formInstance.initFormHandlers();
562 - }
563 - }
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 + }
564 801
565 - initFFInstance_<?php echo $form_vars['id']; ?>();
566 - <?php endif; ?>
567 - </script>
568 - <?php
569 - $this->addInlineVars();
570 - $otherScripts .= ob_get_clean();
571 802
572 - if (!apply_filters('fluentform-disabled_analytics', false)) {
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)) {
573 814 if (!Acl::hasAnyFormPermission($form->id)) {
574 - (new \FluentForm\App\Modules\Form\Analytics($this->app))->record($form->id);
815 + (new \FluentForm\App\Services\Analytics\AnalyticsService())->store($form->id);
575 816 }
576 817 }
818 +
577 819 return $output . $otherScripts;
578 820 }
579 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 +
580 829 /**
581 830 * Process the output HTML to generate the default values.
582 831 *
583 - * @param string $output
832 + * @param string $output
584 833 * @param \stdClass $form
834 + *
585 835 * @return string
586 836 */
587 837 public function replaceEditorSmartCodes($output, $form)
588 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 +
589 849 // Get the patterns for default values from the output HTML string.
590 850 // The example of a pattern would be for user ID: {user.ID}
591 851 preg_match_all('/{(.*?)}/', $output, $matches);
592 852 $patterns = array_unique($matches[0]);
@@ -594,14 +854,35 @@
594 854 $attrDefaultValues = [];
595 855
596 856 foreach ($patterns as $pattern) {
597 857 // The default value for each pattern will be resolved here.
598 - $attrDefaultValues[$pattern] = apply_filters('fluentform_parse_default_value', $pattern, $form);
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);
599 870 }
600 871
601 872 // Raising an event so that others can hook into it and modify the default values later.
602 - $attrDefaultValues = (array)apply_filters('fluentform_parse_default_values', $attrDefaultValues);
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 + );
603 882
883 + $attrDefaultValues = (array) apply_filters('fluentform/parse_default_values', $attrDefaultValues);
884 +
604 885 if (isset($attrDefaultValues['{payment_total}'])) {
605 886 $attrDefaultValues['{payment_total}'] = '<span class="ff_order_total"></span>';
606 887 }
607 888
@@ -611,47 +892,49 @@
611 892
612 893 /**
613 894 * Register renderer actions for compiling each element
614 895 *
615 - * @return void
896 + * @return void
616 897 */
617 898 public function addRendererActions()
618 899 {
619 900 $actionMappings = [
620 - 'Select@compile' => ['fluentform_render_item_select'],
621 - 'Rating@compile' => ['fluentform_render_item_ratings'],
622 - 'Address@compile' => ['fluentform_render_item_address'],
623 - 'Name@compile' => ['fluentform_render_item_input_name'],
624 - 'TextArea@compile' => ['fluentform_render_item_textarea'],
625 - 'DateTime@compile' => ['fluentform_render_item_input_date'],
626 - 'Recaptcha@compile' => ['fluentform_render_item_recaptcha'],
627 - 'Container@compile' => ['fluentform_render_item_container'],
628 - 'CustomHtml@compile' => ['fluentform_render_item_custom_html'],
629 - 'SectionBreak@compile' => ['fluentform_render_item_section_break'],
630 - 'SubmitButton@compile' => ['fluentform_render_item_submit_button'],
631 - 'SelectCountry@compile' => ['fluentform_render_item_select_country'],
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'],
632 915
633 916 'TermsAndConditions@compile' => [
634 - 'fluentform_render_item_terms_and_condition',
635 - 'fluentform_render_item_gdpr_agreement'
917 + 'fluentform/render_item_terms_and_condition',
918 + 'fluentform/render_item_gdpr_agreement',
636 919 ],
637 920
638 921 'TabularGrid@compile' => [
639 - 'fluentform_render_item_tabular_grid'
922 + 'fluentform/render_item_tabular_grid',
640 923 ],
641 924
642 925 'Checkable@compile' => [
643 - 'fluentform_render_item_input_radio',
644 - 'fluentform_render_item_input_checkbox',
926 + 'fluentform/render_item_input_radio',
927 + 'fluentform/render_item_input_checkbox',
645 928 ],
646 929
647 930 'Text@compile' => [
648 - 'fluentform_render_item_input_url',
649 - 'fluentform_render_item_input_text',
650 - 'fluentform_render_item_input_email',
651 - 'fluentform_render_item_input_number',
652 - 'fluentform_render_item_input_hidden',
653 - 'fluentform_render_item_input_password',
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',
654 937 ],
655 938 ];
656 939
657 940 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
@@ -657,10 +940,10 @@
657 940 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
658 941 foreach ($actionMappings as $handler => $actions) {
659 942 foreach ($actions as $action) {
660 943 $this->app->addAction($action, function () use ($path, $handler) {
661 - list($class, $method) = $this->app->parseHandler($path . $handler);
662 - call_user_func_array(array($class, $method), func_get_args());
944 + list($class, $method) = $this->app->parseHookHandler($path . $handler);
945 + call_user_func_array([$class, $method], func_get_args());
663 946 }, 10, 2);
664 947 }
665 948 }
666 949 }
@@ -667,30 +950,47 @@
667 950
668 951 /**
669 952 * Register dynamic value shortcode parser (filter default value)
670 953 *
671 - * @return void
954 + * @return void
672 955 */
673 956 public function addFluentFormDefaultValueParser()
674 957 {
675 - $this->app->addFilter('fluentform_parse_default_value', function ($value, $form) {
958 + $this->app->addFilter('fluentform/parse_default_value', function ($value, $form) {
676 959 return EditorShortcodeParser::filter($value, $form);
677 960 }, 10, 2);
678 961 }
679 962
680 963 /**
681 - * Register filter to check whether the form is renderable
964 + * Register filter to check whether the form is renderable or active
682 965 *
683 - * @return mixed
966 + * @return mixed
684 967 */
685 968 public function addIsRenderableFilter()
686 969 {
687 - $this->app->addFilter('fluentform_is_form_renderable', function ($isRenderable, $form) {
688 - $checkables = array('limitNumberOfEntries', 'scheduleForm', 'requireLogin');
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 + }
689 977
690 - foreach ($form->settings['restrictions'] as $key => $restrictions) {
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) {
691 991 if (in_array($key, $checkables)) {
692 - $isRenderable['status'] = $this->{$key}($restrictions, $form, $isRenderable);
992 + $isRenderable['status'] = $this->{$key}($restrictionSettings, $form, $isRenderable);
693 993 if (!$isRenderable['status']) {
694 994 $isRenderable['status'] = false;
695 995 return $isRenderable;
696 996 }
@@ -695,8 +995,12 @@
695 995 return $isRenderable;
696 996 }
697 997 }
698 998 }
999 + if($form->status == 'unpublished'){
1000 + $isRenderable['status'] = false;
1001 + $isRenderable['message'] = apply_filters('fluentform/unpublished_form_submission_message',__('Invalid Form!', 'fluentform'));
1002 + }
699 1003
700 1004 return $isRenderable;
701 1005 }, 10, 2);
702 1006 }
@@ -709,12 +1013,14 @@
709 1013 * @return bool
710 1014 */
711 1015 private function limitNumberOfEntries($restrictions, $form, &$isRenderable)
712 1016 {
713 - if (!$restrictions['enabled']) {
1017 +
1018 + if (!Arr::isTrue($restrictions, 'enabled') || !isset($restrictions['period']) || !isset($restrictions['numberOfEntries'])) {
714 1019 return true;
715 1020 }
716 1021
1022 +
717 1023 $col = 'created_at';
718 1024 $period = $restrictions['period'];
719 1025 $maxAllowedEntries = $restrictions['numberOfEntries'];
720 1026
@@ -725,27 +1031,27 @@
725 1031 $query = wpFluent()->table('fluentform_submissions')
726 1032 ->where('form_id', $form->id)
727 1033 ->where('status', '!=', 'trashed');
728 1034
729 - if ($period == 'day') {
1035 + if ('day' == $period) {
730 1036 $year = "YEAR(`{$col}`) = YEAR(NOW())";
731 1037 $month = "MONTH(`{$col}`) = MONTH(NOW())";
732 1038 $day = "DAY(`{$col}`) = DAY(NOW())";
733 - $query->where(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
734 - } elseif ($period == 'week') {
735 - $query->where(
1039 + $query->whereRaw(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
1040 + } elseif ('week' == $period) {
1041 + $query->whereRaw(
736 1042 wpFluent()->raw("YEARWEEK(`{$col}`, 1) = YEARWEEK(CURDATE(), 1)")
737 1043 );
738 - } elseif ($period == 'month') {
1044 + } elseif ('month' == $period) {
739 1045 $year = "YEAR(`{$col}`) = YEAR(NOW())";
740 1046 $month = "MONTH(`{$col}`) = MONTH(NOW())";
741 - $query->where(wpFluent()->raw("{$year} AND {$month}"));
742 - } elseif ($period == 'year') {
743 - $query->where(wpFluent()->raw("YEAR(`{$col}`) = YEAR(NOW())"));
744 - } else if ($period == 'per_user_ip') {
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) {
745 1051 $ip = $this->app->request->getIp();
746 1052 $query->where('ip', $ip);
747 - } else if ($period == 'per_user_id') {
1053 + } elseif ('per_user_id' == $period) {
748 1054 $userId = get_current_user_id();
749 1055 if (!$userId) {
750 1056 return true;
751 1057 }
@@ -753,11 +1059,10 @@
753 1059 }
754 1060
755 1061 $count = $query->count();
756 1062
757 -
758 1063 if ($count >= $maxAllowedEntries) {
759 - $isRenderable['message'] = $restrictions['limitReachedMsg'];
1064 + $isRenderable['message'] = apply_filters('fluentform/entry_limit_reached_message', $restrictions['limitReachedMsg'], $form);
760 1065 return false;
761 1066 }
762 1067
763 1068 return true;
@@ -763,9 +1068,9 @@
763 1068 return true;
764 1069 }
765 1070
766 1071 /**
767 - * Check if form has scheduled date and open for submission
1072 + * Check if form has scheduled date & weekdays and open for submission
768 1073 *
769 1074 * @param array $restrictions
770 1075 *
771 1076 * @return bool
@@ -771,9 +1076,9 @@
771 1076 * @return bool
772 1077 */
773 1078 private function scheduleForm($restrictions, $form, &$isRenderable)
774 1079 {
775 - if (!$restrictions['enabled']) {
1080 + if (!Arr::isTrue($restrictions, 'enabled')) {
776 1081 return true;
777 1082 }
778 1083
779 1084 $time = time();
@@ -780,16 +1085,23 @@
780 1085 $start = strtotime($restrictions['start']);
781 1086 $end = strtotime($restrictions['end']);
782 1087
783 1088 if ($time < $start) {
784 - $isRenderable['message'] = $restrictions['pendingMsg'];
1089 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_pending_message', $restrictions['pendingMsg'], $form->id);
1090 + return false;
1091 + }
785 1092
1093 + if ($time >= $end) {
1094 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_expired_message', $restrictions['expiredMsg'], $form->id);
1095 +
786 1096 return false;
787 1097 }
788 1098
789 - if ($time >= $end) {
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)) {
790 1103 $isRenderable['message'] = $restrictions['expiredMsg'];
791 -
792 1104 return false;
793 1105 }
794 1106
795 1107 return true;
@@ -803,14 +1115,14 @@
803 1115 * @return bool
804 1116 */
805 1117 private function requireLogin($restrictions, $form, &$isRenderable)
806 1118 {
807 - if (!$restrictions['enabled']) {
1119 + if (!Arr::isTrue($restrictions, 'enabled')) {
808 1120 return true;
809 1121 }
810 1122
811 1123 if (!($isLoggedIn = is_user_logged_in())) {
812 - $isRenderable['message'] = $restrictions['requireLoginMsg'];
1124 + $isRenderable['message'] = apply_filters('fluentform/form_requires_login_message', $restrictions['requireLoginMsg'], $form);
813 1125 }
814 1126
815 1127 return $isLoggedIn;
816 1128 }
@@ -817,9 +1129,9 @@
817 1129
818 1130 /**
819 1131 * Register fluentform_submission_inserted actions
820 1132 *
821 - * @return void
1133 + * @return void
822 1134 */
823 1135 public function addFluentformSubmissionInsertedFilter()
824 1136 {
825 1137 (new EmailNotificationActions($this->app))->register();
@@ -827,16 +1139,22 @@
827 1139
828 1140 /**
829 1141 * Add inline scripts [Add localized script using same var]
830 1142 *
831 - * @return void
1143 + * @return void
832 1144 */
833 1145 private function addInlineVars()
834 1146 {
835 - if (!defined('ELEMENTOR_PRO_VERSION')) {
1147 + if (!defined('ELEMENTOR_PRO_VERSION') || $this->elementorPopUpHandler) {
836 1148 return '';
837 1149 }
838 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 +
839 1157 $actionName = 'wp_footer';
840 1158 if (is_admin()) {
841 1159 $actionName = 'admin_footer';
842 1160 }
@@ -843,14 +1161,30 @@
843 1161
844 1162 add_action($actionName, function () {
845 1163 ?>
846 1164 <script type="text/javascript">
847 - <?php if(defined('ELEMENTOR_PRO_VERSION')): ?>
848 - jQuery(document).on('elementor/popup/show', function (event, id, instance) {
849 - var ffForms = jQuery('#elementor-popup-modal-' + id).find('form.frm-fluent-form');
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 + }
850 1183 if (ffForms.length) {
851 - jQuery.each(ffForms, function (index, ffForm) {
1184 + jQuery.each(ffForms, function(index, ffForm) {
852 1185 jQuery(ffForm).trigger('reInitExtras');
1186 + jQuery(document).trigger('ff_reinit', [ffForm]);
853 1187 });
854 1188 }
855 1189 });
856 1190 <?php endif; ?>
@@ -859,14 +1193,14 @@
859 1193 }, 999);
860 1194 return '';
861 1195 }
862 1196
863 - private function getDatei18n()
1197 + public static function getDatei18n()
864 1198 {
865 - $i18n = array(
1199 + $i18n = [
866 1200 'previousMonth' => __('Previous Month', 'fluentform'),
867 - 'nextMonth' => __('Next Month', 'fluentform'),
868 - 'months' => [
1201 + 'nextMonth' => __('Next Month', 'fluentform'),
1202 + 'months' => [
869 1203 'shorthand' => [
870 1204 __('Jan', 'fluentform'),
871 1205 __('Feb', 'fluentform'),
872 1206 __('Mar', 'fluentform'),
@@ -877,9 +1211,9 @@
877 1211 __('Aug', 'fluentform'),
878 1212 __('Sep', 'fluentform'),
879 1213 __('Oct', 'fluentform'),
880 1214 __('Nov', 'fluentform'),
881 - __('Dec', 'fluentform')
1215 + __('Dec', 'fluentform'),
882 1216 ],
883 1217 'longhand' => [
884 1218 __('January', 'fluentform'),
885 1219 __('February', 'fluentform'),
@@ -891,13 +1225,13 @@
891 1225 __('August', 'fluentform'),
892 1226 __('September', 'fluentform'),
893 1227 __('October', 'fluentform'),
894 1228 __('November', 'fluentform'),
895 - __('December', 'fluentform')
896 - ]
1229 + __('December', 'fluentform'),
1230 + ],
897 1231 ],
898 1232 'weekdays' => [
899 - 'longhand' => array(
1233 + 'longhand' => [
900 1234 __('Sunday', 'fluentform'),
901 1235 __('Monday', 'fluentform'),
902 1236 __('Tuesday', 'fluentform'),
903 1237 __('Wednesday', 'fluentform'),
@@ -902,11 +1236,11 @@
902 1236 __('Tuesday', 'fluentform'),
903 1237 __('Wednesday', 'fluentform'),
904 1238 __('Thursday', 'fluentform'),
905 1239 __('Friday', 'fluentform'),
906 - __('Saturday', 'fluentform')
907 - ),
908 - 'shorthand' => array(
1240 + __('Saturday', 'fluentform'),
1241 + ],
1242 + 'shorthand' => [
909 1243 __('Sun', 'fluentform'),
910 1244 __('Mon', 'fluentform'),
911 1245 __('Tue', 'fluentform'),
912 1246 __('Wed', 'fluentform'),
@@ -911,10 +1245,10 @@
911 1245 __('Tue', 'fluentform'),
912 1246 __('Wed', 'fluentform'),
913 1247 __('Thu', 'fluentform'),
914 1248 __('Fri', 'fluentform'),
915 - __('Sat', 'fluentform')
916 - )
1249 + __('Sat', 'fluentform'),
1250 + ],
917 1251 ],
918 1252 'daysInMonth' => [
919 1253 31,
920 1254 28,
@@ -926,20 +1260,21 @@
926 1260 31,
927 1261 30,
928 1262 31,
929 1263 30,
930 - 31
1264 + 31,
931 1265 ],
932 - 'rangeSeparator' => __(' to ', 'fluentform'),
1266 + 'rangeSeparator' => __(' to ', 'fluentform'),
933 1267 'weekAbbreviation' => __('Wk', 'fluentform'),
934 - 'scrollTitle' => __('Scroll to increment', 'fluentform'),
935 - 'toggleTitle' => __('Click to toggle', 'fluentform'),
936 - 'amPM' => [
1268 + 'scrollTitle' => __('Scroll to increment', 'fluentform'),
1269 + 'toggleTitle' => __('Click to toggle', 'fluentform'),
1270 + 'amPM' => [
937 1271 __('AM', 'fluentform'),
938 - __('PM', 'fluentform')
1272 + __('PM', 'fluentform'),
939 1273 ],
940 - 'yearAriaLabel' => __('Year', 'fluentform')
941 - );
1274 + 'yearAriaLabel' => __('Year', 'fluentform'),
1275 + 'firstDayOfWeek' => (int) get_option('start_of_week'),
1276 + ];
942 1277
943 1278 return apply_filters('fluentform/date_i18n', $i18n);
944 1279 }
945 1280
@@ -952,13 +1287,276 @@
952 1287 'form_step',
953 1288 'input_file',
954 1289 'input_image',
955 1290 'net_promoter_score',
956 - 'featured_image'
1291 + 'featured_image',
957 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 + }
958 1300
959 - if ($formBuilder->conditions || array_intersect($formBuilder->fieldLists, $advancedFields)) {
960 - wp_enqueue_script('fluentform-advanced');
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;
961 1312 }
1313 + return Helper::getNumericValue($value, $formatter);
962 1314 }
963 1315
964 -}
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 + if ('' === $atts['param']) {
1453 + return '';
1454 + }
1455 +
1456 + $value = $this->app->request->get($atts['param']);
1457 +
1458 + if (null === $value || '' === $value) {
1459 + return '';
1460 + }
1461 +
1462 + return esc_html(Helper::flattenRequestValue($value));
1463 + });
1464 +
1465 + $this->app->addShortcode('ff_entry',function($atts){
1466 + ob_start();
1467 +
1468 + $atts = shortcode_atts([
1469 + 'form_id' => '',
1470 + 'serial_number' => '',
1471 + 'field' => '',
1472 + 'is_html' => true,
1473 + ], $atts);
1474 +
1475 + if (empty($atts['form_id']) || empty($atts['field'])) {
1476 + return '';
1477 + }
1478 +
1479 +
1480 + $formId = (int) $atts['form_id'];
1481 + $form = wpFluent()->table('fluentform_forms')->find($formId);
1482 + if (!$form) {
1483 + return __('Form not found.', 'fluentform');
1484 + }
1485 + $isHtml = $atts['is_html'] === 'true' ? true : false;
1486 + $submission = (new \FluentForm\App\Services\Submission\SubmissionService())->findBySerialID($formId, $atts['serial_number'],$isHtml);
1487 + if (!$submission) {
1488 + return __('No entry found.', 'fluentform');
1489 + }
1490 +
1491 + $input = $submission->user_inputs;
1492 + $field = sanitize_text_field($atts['field']);
1493 + $fieldVal = ArrayHelper::get($input, $field, '');
1494 +
1495 + $response = FormDataParser::formatValue($fieldVal);
1496 + echo $atts['is_html'] ? wp_kses_post($response) : esc_html($response);
1497 +
1498 + return ob_get_clean();
1499 + });
1500 +
1501 + }
1502 +
1503 + private function localizeJavaScriptMessages($form)
1504 + {
1505 + // Form submission messages
1506 + $submissionMessages = [
1507 + 'file_upload_in_progress' => __('File upload in progress. Please wait...', 'fluentform'),
1508 + 'javascript_handler_failed' => __('Javascript handler could not be loaded. Form submission has been failed. Reload the page and try again', 'fluentform')
1509 + ];
1510 + $submissionMessages = apply_filters('fluentform/form_submission_messages', $submissionMessages, $form);
1511 + wp_localize_script('fluent-form-submission', 'fluentform_submission_messages_' . $form->id, $submissionMessages);
1512 +
1513 + // Payment handler messages
1514 + $paymentMessages = [
1515 + 'stock_out_message' => __('This Item is Stock Out', 'fluentform'),
1516 + 'item_label' => __('Item', 'fluentform'),
1517 + 'price_label' => __('Price', 'fluentform'),
1518 + 'qty_label' => __('Qty', 'fluentform'),
1519 + 'line_total_label' => __('Line Total', 'fluentform'),
1520 + 'sub_total_label' => __('Sub Total', 'fluentform'),
1521 + 'discount_label' => __('Discount', 'fluentform'),
1522 + 'total_label' => __('Total', 'fluentform'),
1523 + 'signup_fee_label' => __('Signup Fee', 'fluentform'),
1524 + 'trial_label' => __('Trial', 'fluentform'),
1525 + 'processing_text' => __('Processing...', 'fluentform'),
1526 + 'confirming_text' => __('Confirming...', 'fluentform')
1527 + ];
1528 + $paymentMessages = apply_filters('fluentform/payment_handler_messages', $paymentMessages, $form);
1529 + wp_localize_script('fluent-form-submission', 'fluentform_payment_messages_' . $form->id, $paymentMessages);
1530 +
1531 + // Form save progress messages
1532 + $saveProgressMessages = [
1533 + 'copy_button' => __('Copy', 'fluentform'),
1534 + 'email_button' => __('Email', 'fluentform'),
1535 + 'email_placeholder' => __('Your Email Here', 'fluentform'),
1536 + 'copy_success' => __('Copied', 'fluentform')
1537 + ];
1538 + $saveProgressMessages = apply_filters('fluentform/form_save_progress_messages', $saveProgressMessages, $form);
1539 + wp_localize_script('fluent-form-submission', 'fluentform_save_progress_messages_' . $form->id, $saveProgressMessages);
1540 +
1541 + // Address autocomplete messages
1542 + $addressMessages = [
1543 + 'please_wait' => __('Please wait ...', 'fluentform'),
1544 + 'location_not_determined' => __('Could not determine address from location.', 'fluentform'),
1545 + 'address_fetch_failed' => __('Failed to fetch address from coordinates.', 'fluentform'),
1546 + 'geolocation_failed' => __('Geolocation failed or was denied.', 'fluentform'),
1547 + 'geolocation_not_supported' => __('Geolocation is not supported by this browser.', 'fluentform')
1548 + ];
1549 + $addressMessages = apply_filters('fluentform/address_autocomplete_messages', $addressMessages, $form);
1550 + wp_localize_script('fluent-form-submission', 'fluentform_address_messages_' . $form->id, $addressMessages);
1551 +
1552 + // Payment gateway messages
1553 + $gatewayMessages = [
1554 + 'request_failed' => __('Request failed. Please try again', 'fluentform'),
1555 + 'payment_failed' => __('Payment process failed!', 'fluentform'),
1556 + 'no_method_found' => __('No method found', 'fluentform'),
1557 + 'processing_text' => __('Processing...', 'fluentform')
1558 + ];
1559 + $gatewayMessages = apply_filters('fluentform/payment_gateway_messages', $gatewayMessages, $form);
1560 + wp_localize_script('fluent-form-submission', 'fluentform_gateway_messages_' . $form->id, $gatewayMessages);
1561 + }
1562 +}