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