PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.15
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.15
6.2.15 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 All 197 releases
← All changes | app/Modules/Component/Component.php +1036 -429 3.6.31 → 6.2.15 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.8',
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.min.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,64 +854,96 @@
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
608 - // Finally, replace the patterns with the replacements and return the output HTML.
609 - return str_replace(array_keys($attrDefaultValues), array_values($attrDefaultValues), $output);
889 + // Replace in a single pass. str_replace() with arrays re-scans text an earlier key inserted,
890 + // so ?a=javascript{get.b}&b=:alert(1) would assemble a script URL from two escaped values.
891 + $replacements = [];
892 + foreach ($attrDefaultValues as $pattern => $replacement) {
893 + // strtr() returns false on an empty key before PHP 8.
894 + if ('' !== (string) $pattern && (is_scalar($replacement) || null === $replacement)) {
895 + $replacements[(string) $pattern] = (string) $replacement;
896 + }
897 + }
898 +
899 + return strtr($output, $replacements);
610 900 }
611 901
612 902 /**
613 903 * Register renderer actions for compiling each element
614 904 *
615 - * @return void
905 + * @return void
616 906 */
617 907 public function addRendererActions()
618 908 {
619 909 $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'],
910 + 'Select@compile' => ['fluentform/render_item_select'],
911 + 'Rating@compile' => ['fluentform/render_item_ratings'],
912 + 'Address@compile' => ['fluentform/render_item_address'],
913 + 'Name@compile' => ['fluentform/render_item_input_name'],
914 + 'TextArea@compile' => ['fluentform/render_item_textarea'],
915 + 'DateTime@compile' => ['fluentform/render_item_input_date'],
916 + 'Recaptcha@compile' => ['fluentform/render_item_recaptcha'],
917 + 'Hcaptcha@compile' => ['fluentform/render_item_hcaptcha'],
918 + 'Turnstile@compile' => ['fluentform/render_item_turnstile'],
919 + 'Container@compile' => ['fluentform/render_item_container'],
920 + 'CustomHtml@compile' => ['fluentform/render_item_custom_html'],
921 + 'SectionBreak@compile' => ['fluentform/render_item_section_break'],
922 + 'SubmitButton@compile' => ['fluentform/render_item_submit_button'],
923 + 'SelectCountry@compile' => ['fluentform/render_item_select_country'],
632 924
633 925 'TermsAndConditions@compile' => [
634 - 'fluentform_render_item_terms_and_condition',
635 - 'fluentform_render_item_gdpr_agreement'
926 + 'fluentform/render_item_terms_and_condition',
927 + 'fluentform/render_item_gdpr_agreement',
636 928 ],
637 929
638 930 'TabularGrid@compile' => [
639 - 'fluentform_render_item_tabular_grid'
931 + 'fluentform/render_item_tabular_grid',
640 932 ],
641 933
642 934 'Checkable@compile' => [
643 - 'fluentform_render_item_input_radio',
644 - 'fluentform_render_item_input_checkbox',
935 + 'fluentform/render_item_input_radio',
936 + 'fluentform/render_item_input_checkbox',
645 937 ],
646 938
647 939 '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',
940 + 'fluentform/render_item_input_url',
941 + 'fluentform/render_item_input_text',
942 + 'fluentform/render_item_input_email',
943 + 'fluentform/render_item_input_number',
944 + 'fluentform/render_item_input_hidden',
945 + 'fluentform/render_item_input_password',
654 946 ],
655 947 ];
656 948
657 949 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
@@ -657,10 +949,10 @@
657 949 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
658 950 foreach ($actionMappings as $handler => $actions) {
659 951 foreach ($actions as $action) {
660 952 $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());
953 + list($class, $method) = $this->app->parseHookHandler($path . $handler);
954 + call_user_func_array([$class, $method], func_get_args());
663 955 }, 10, 2);
664 956 }
665 957 }
666 958 }
@@ -667,30 +959,47 @@
667 959
668 960 /**
669 961 * Register dynamic value shortcode parser (filter default value)
670 962 *
671 - * @return void
963 + * @return void
672 964 */
673 965 public function addFluentFormDefaultValueParser()
674 966 {
675 - $this->app->addFilter('fluentform_parse_default_value', function ($value, $form) {
967 + $this->app->addFilter('fluentform/parse_default_value', function ($value, $form) {
676 968 return EditorShortcodeParser::filter($value, $form);
677 969 }, 10, 2);
678 970 }
679 971
680 972 /**
681 - * Register filter to check whether the form is renderable
973 + * Register filter to check whether the form is renderable or active
682 974 *
683 - * @return mixed
975 + * @return mixed
684 976 */
685 977 public function addIsRenderableFilter()
686 978 {
687 - $this->app->addFilter('fluentform_is_form_renderable', function ($isRenderable, $form) {
688 - $checkables = array('limitNumberOfEntries', 'scheduleForm', 'requireLogin');
979 + $this->app->addFilter('fluentform/is_form_renderable', function ($isRenderable, $form) {
980 + if (
981 + $this->app->request->get('design_mode')
982 + && Acl::hasAnyFormPermission()
983 + ) {
984 + return $isRenderable;
985 + }
689 986
690 - foreach ($form->settings['restrictions'] as $key => $restrictions) {
987 + $checkables = ['limitNumberOfEntries', 'scheduleForm', 'requireLogin'];
988 +
989 + // Ensure settings is an array
990 + if (!isset($form->settings) || !is_array($form->settings)) {
991 + $form->settings = [];
992 + }
993 +
994 + // Ensure restrictions exists and is an array before iterating
995 + $restrictions = isset($form->settings['restrictions']) && is_array($form->settings['restrictions'])
996 + ? $form->settings['restrictions']
997 + : [];
998 +
999 + foreach ($restrictions as $key => $restrictionSettings) {
691 1000 if (in_array($key, $checkables)) {
692 - $isRenderable['status'] = $this->{$key}($restrictions, $form, $isRenderable);
1001 + $isRenderable['status'] = $this->{$key}($restrictionSettings, $form, $isRenderable);
693 1002 if (!$isRenderable['status']) {
694 1003 $isRenderable['status'] = false;
695 1004 return $isRenderable;
696 1005 }
@@ -695,8 +1004,12 @@
695 1004 return $isRenderable;
696 1005 }
697 1006 }
698 1007 }
1008 + if($form->status == 'unpublished'){
1009 + $isRenderable['status'] = false;
1010 + $isRenderable['message'] = apply_filters('fluentform/unpublished_form_submission_message',__('Invalid Form!', 'fluentform'));
1011 + }
699 1012
700 1013 return $isRenderable;
701 1014 }, 10, 2);
702 1015 }
@@ -709,12 +1022,14 @@
709 1022 * @return bool
710 1023 */
711 1024 private function limitNumberOfEntries($restrictions, $form, &$isRenderable)
712 1025 {
713 - if (!$restrictions['enabled']) {
1026 +
1027 + if (!Arr::isTrue($restrictions, 'enabled') || !isset($restrictions['period']) || !isset($restrictions['numberOfEntries'])) {
714 1028 return true;
715 1029 }
716 1030
1031 +
717 1032 $col = 'created_at';
718 1033 $period = $restrictions['period'];
719 1034 $maxAllowedEntries = $restrictions['numberOfEntries'];
720 1035
@@ -725,27 +1040,27 @@
725 1040 $query = wpFluent()->table('fluentform_submissions')
726 1041 ->where('form_id', $form->id)
727 1042 ->where('status', '!=', 'trashed');
728 1043
729 - if ($period == 'day') {
1044 + if ('day' == $period) {
730 1045 $year = "YEAR(`{$col}`) = YEAR(NOW())";
731 1046 $month = "MONTH(`{$col}`) = MONTH(NOW())";
732 1047 $day = "DAY(`{$col}`) = DAY(NOW())";
733 - $query->where(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
734 - } elseif ($period == 'week') {
735 - $query->where(
1048 + $query->whereRaw(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
1049 + } elseif ('week' == $period) {
1050 + $query->whereRaw(
736 1051 wpFluent()->raw("YEARWEEK(`{$col}`, 1) = YEARWEEK(CURDATE(), 1)")
737 1052 );
738 - } elseif ($period == 'month') {
1053 + } elseif ('month' == $period) {
739 1054 $year = "YEAR(`{$col}`) = YEAR(NOW())";
740 1055 $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') {
1056 + $query->whereRaw(wpFluent()->raw("{$year} AND {$month}"));
1057 + } elseif ('year' == $period) {
1058 + $query->whereRaw(wpFluent()->raw("YEAR(`{$col}`) = YEAR(NOW())"));
1059 + } elseif ('per_user_ip' == $period) {
745 1060 $ip = $this->app->request->getIp();
746 1061 $query->where('ip', $ip);
747 - } else if ($period == 'per_user_id') {
1062 + } elseif ('per_user_id' == $period) {
748 1063 $userId = get_current_user_id();
749 1064 if (!$userId) {
750 1065 return true;
751 1066 }
@@ -753,11 +1068,10 @@
753 1068 }
754 1069
755 1070 $count = $query->count();
756 1071
757 -
758 1072 if ($count >= $maxAllowedEntries) {
759 - $isRenderable['message'] = $restrictions['limitReachedMsg'];
1073 + $isRenderable['message'] = apply_filters('fluentform/entry_limit_reached_message', $restrictions['limitReachedMsg'], $form);
760 1074 return false;
761 1075 }
762 1076
763 1077 return true;
@@ -763,9 +1077,9 @@
763 1077 return true;
764 1078 }
765 1079
766 1080 /**
767 - * Check if form has scheduled date and open for submission
1081 + * Check if form has scheduled date & weekdays and open for submission
768 1082 *
769 1083 * @param array $restrictions
770 1084 *
771 1085 * @return bool
@@ -771,9 +1085,9 @@
771 1085 * @return bool
772 1086 */
773 1087 private function scheduleForm($restrictions, $form, &$isRenderable)
774 1088 {
775 - if (!$restrictions['enabled']) {
1089 + if (!Arr::isTrue($restrictions, 'enabled')) {
776 1090 return true;
777 1091 }
778 1092
779 1093 $time = time();
@@ -780,16 +1094,23 @@
780 1094 $start = strtotime($restrictions['start']);
781 1095 $end = strtotime($restrictions['end']);
782 1096
783 1097 if ($time < $start) {
784 - $isRenderable['message'] = $restrictions['pendingMsg'];
1098 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_pending_message', $restrictions['pendingMsg'], $form->id);
1099 + return false;
1100 + }
785 1101
1102 + if ($time >= $end) {
1103 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_expired_message', $restrictions['expiredMsg'], $form->id);
1104 +
786 1105 return false;
787 1106 }
788 1107
789 - if ($time >= $end) {
1108 + $weekDayToday = date('l'); //day of the week
1109 + $selectedWeekDays = ArrayHelper::get($restrictions, 'selectedDays');
1110 + //skip if it was not set initially and $selectedWeekDays is null
1111 + if ($selectedWeekDays && is_array($selectedWeekDays) && !in_array($weekDayToday, $selectedWeekDays)) {
790 1112 $isRenderable['message'] = $restrictions['expiredMsg'];
791 -
792 1113 return false;
793 1114 }
794 1115
795 1116 return true;
@@ -803,14 +1124,14 @@
803 1124 * @return bool
804 1125 */
805 1126 private function requireLogin($restrictions, $form, &$isRenderable)
806 1127 {
807 - if (!$restrictions['enabled']) {
1128 + if (!Arr::isTrue($restrictions, 'enabled')) {
808 1129 return true;
809 1130 }
810 1131
811 1132 if (!($isLoggedIn = is_user_logged_in())) {
812 - $isRenderable['message'] = $restrictions['requireLoginMsg'];
1133 + $isRenderable['message'] = apply_filters('fluentform/form_requires_login_message', $restrictions['requireLoginMsg'], $form);
813 1134 }
814 1135
815 1136 return $isLoggedIn;
816 1137 }
@@ -817,9 +1138,9 @@
817 1138
818 1139 /**
819 1140 * Register fluentform_submission_inserted actions
820 1141 *
821 - * @return void
1142 + * @return void
822 1143 */
823 1144 public function addFluentformSubmissionInsertedFilter()
824 1145 {
825 1146 (new EmailNotificationActions($this->app))->register();
@@ -827,16 +1148,22 @@
827 1148
828 1149 /**
829 1150 * Add inline scripts [Add localized script using same var]
830 1151 *
831 - * @return void
1152 + * @return void
832 1153 */
833 1154 private function addInlineVars()
834 1155 {
835 - if (!defined('ELEMENTOR_PRO_VERSION')) {
1156 + if (!defined('ELEMENTOR_PRO_VERSION') || $this->elementorPopUpHandler) {
836 1157 return '';
837 1158 }
838 1159
1160 + // Previously this handler was registered for every form
1161 + // in a single page. So multiple event handlers were
1162 + // registered. This flag ensures the handler is
1163 + // registered just once, since one is enough!
1164 + $this->elementorPopUpHandler = true;
1165 +
839 1166 $actionName = 'wp_footer';
840 1167 if (is_admin()) {
841 1168 $actionName = 'admin_footer';
842 1169 }
@@ -843,14 +1170,30 @@
843 1170
844 1171 add_action($actionName, function () {
845 1172 ?>
846 1173 <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');
1174 + <?php if (defined('ELEMENTOR_PRO_VERSION')): ?>
1175 +
1176 + window.addEventListener('elementor/popup/show', function (e) {
1177 + var ffForms = jQuery('#elementor-popup-modal-' + e.detail.id).find('form.frm-fluent-form');
1178 +
1179 + /**
1180 + * Support conversation form in elementor popup
1181 + * No regular form found, check for conversational form
1182 + */
1183 + if (!ffForms.length) {
1184 + const elements = document.getElementsByClassName('ffc_conv_form');
1185 + if (elements.length) {
1186 + let jsEvent = new CustomEvent('ff-elm-conv-form-event', {
1187 + detail: elements
1188 + });
1189 + document.dispatchEvent(jsEvent);
1190 + }
1191 + }
850 1192 if (ffForms.length) {
851 - jQuery.each(ffForms, function (index, ffForm) {
1193 + jQuery.each(ffForms, function(index, ffForm) {
852 1194 jQuery(ffForm).trigger('reInitExtras');
1195 + jQuery(document).trigger('ff_reinit', [ffForm]);
853 1196 });
854 1197 }
855 1198 });
856 1199 <?php endif; ?>
@@ -859,14 +1202,14 @@
859 1202 }, 999);
860 1203 return '';
861 1204 }
862 1205
863 - private function getDatei18n()
1206 + public static function getDatei18n()
864 1207 {
865 - $i18n = array(
1208 + $i18n = [
866 1209 'previousMonth' => __('Previous Month', 'fluentform'),
867 - 'nextMonth' => __('Next Month', 'fluentform'),
868 - 'months' => [
1210 + 'nextMonth' => __('Next Month', 'fluentform'),
1211 + 'months' => [
869 1212 'shorthand' => [
870 1213 __('Jan', 'fluentform'),
871 1214 __('Feb', 'fluentform'),
872 1215 __('Mar', 'fluentform'),
@@ -877,9 +1220,9 @@
877 1220 __('Aug', 'fluentform'),
878 1221 __('Sep', 'fluentform'),
879 1222 __('Oct', 'fluentform'),
880 1223 __('Nov', 'fluentform'),
881 - __('Dec', 'fluentform')
1224 + __('Dec', 'fluentform'),
882 1225 ],
883 1226 'longhand' => [
884 1227 __('January', 'fluentform'),
885 1228 __('February', 'fluentform'),
@@ -891,13 +1234,13 @@
891 1234 __('August', 'fluentform'),
892 1235 __('September', 'fluentform'),
893 1236 __('October', 'fluentform'),
894 1237 __('November', 'fluentform'),
895 - __('December', 'fluentform')
896 - ]
1238 + __('December', 'fluentform'),
1239 + ],
897 1240 ],
898 1241 'weekdays' => [
899 - 'longhand' => array(
1242 + 'longhand' => [
900 1243 __('Sunday', 'fluentform'),
901 1244 __('Monday', 'fluentform'),
902 1245 __('Tuesday', 'fluentform'),
903 1246 __('Wednesday', 'fluentform'),
@@ -902,11 +1245,11 @@
902 1245 __('Tuesday', 'fluentform'),
903 1246 __('Wednesday', 'fluentform'),
904 1247 __('Thursday', 'fluentform'),
905 1248 __('Friday', 'fluentform'),
906 - __('Saturday', 'fluentform')
907 - ),
908 - 'shorthand' => array(
1249 + __('Saturday', 'fluentform'),
1250 + ],
1251 + 'shorthand' => [
909 1252 __('Sun', 'fluentform'),
910 1253 __('Mon', 'fluentform'),
911 1254 __('Tue', 'fluentform'),
912 1255 __('Wed', 'fluentform'),
@@ -911,10 +1254,10 @@
911 1254 __('Tue', 'fluentform'),
912 1255 __('Wed', 'fluentform'),
913 1256 __('Thu', 'fluentform'),
914 1257 __('Fri', 'fluentform'),
915 - __('Sat', 'fluentform')
916 - )
1258 + __('Sat', 'fluentform'),
1259 + ],
917 1260 ],
918 1261 'daysInMonth' => [
919 1262 31,
920 1263 28,
@@ -926,20 +1269,21 @@
926 1269 31,
927 1270 30,
928 1271 31,
929 1272 30,
930 - 31
1273 + 31,
931 1274 ],
932 - 'rangeSeparator' => __(' to ', 'fluentform'),
1275 + 'rangeSeparator' => __(' to ', 'fluentform'),
933 1276 'weekAbbreviation' => __('Wk', 'fluentform'),
934 - 'scrollTitle' => __('Scroll to increment', 'fluentform'),
935 - 'toggleTitle' => __('Click to toggle', 'fluentform'),
936 - 'amPM' => [
1277 + 'scrollTitle' => __('Scroll to increment', 'fluentform'),
1278 + 'toggleTitle' => __('Click to toggle', 'fluentform'),
1279 + 'amPM' => [
937 1280 __('AM', 'fluentform'),
938 - __('PM', 'fluentform')
1281 + __('PM', 'fluentform'),
939 1282 ],
940 - 'yearAriaLabel' => __('Year', 'fluentform')
941 - );
1283 + 'yearAriaLabel' => __('Year', 'fluentform'),
1284 + 'firstDayOfWeek' => (int) get_option('start_of_week'),
1285 + ];
942 1286
943 1287 return apply_filters('fluentform/date_i18n', $i18n);
944 1288 }
945 1289
@@ -952,13 +1296,276 @@
952 1296 'form_step',
953 1297 'input_file',
954 1298 'input_image',
955 1299 'net_promoter_score',
956 - 'featured_image'
1300 + 'featured_image',
957 1301 ];
1302 + $advancedFields = apply_filters('fluentform/fields_requiring_advanced_script', $advancedFields);
1303 +
1304 + // Only enqueue advanced script if NOT in Elementor editor mode
1305 + if (!Helper::isElementorEditor() && ($formBuilder->conditions || array_intersect($formBuilder->fieldLists, $advancedFields))) {
1306 + wp_enqueue_script('fluentform-advanced');
1307 + }
1308 + }
958 1309
959 - if ($formBuilder->conditions || array_intersect($formBuilder->fieldLists, $advancedFields)) {
960 - wp_enqueue_script('fluentform-advanced');
1310 + public function registerInputSanitizers()
1311 + {
1312 + add_filter('fluentform/input_data_input_number', [$this, 'getNumericInputValue'], 10, 2);
1313 + add_filter('fluentform/input_data_custom_payment_component', [$this, 'getNumericInputValue'], 10, 2);
1314 + }
1315 +
1316 + public function getNumericInputValue($value, $field)
1317 + {
1318 + $formatter = ArrayHelper::get($field, 'raw.settings.numeric_formatter');
1319 + if (!$formatter) {
1320 + return $value;
961 1321 }
1322 + return Helper::getNumericValue($value, $formatter);
962 1323 }
963 1324
964 -}
1325 +
1326 + public function registerHelperShortCodes()
1327 + {
1328 + $this->app->addShortCode('fluentform_info', function ($atts) {
1329 + $data = [
1330 + 'id' => null, // This is the form id
1331 + 'info' => 'submission_count', // submission_count | created_at | updated_at | payment_total
1332 + 'status' => 'all', // get submission cound of a particular entry status favourites | unread | read
1333 + 'with_trashed' => 'no', // yes | no
1334 + 'substract_from' => 0, // [fluentform_info id="2" info="submission_count" substract_from="20"]
1335 + 'hide_on_zero' => 'no',
1336 + 'payment_status' => 'all', // it can be all / specific payment status
1337 + 'currency_formatted' => 'yes',
1338 + 'date_format' => '',
1339 + ];
1340 + /* This filter is deprecated, will be removed soon */
1341 + $data = apply_filters('fluentform_info_shortcode_defaults', $data, $atts );
1342 +
1343 + $shortcodeDefaults = apply_filters('fluentform/info_shortcode_defaults', $data, $atts);
1344 +
1345 + $atts = shortcode_atts($shortcodeDefaults, $atts);
1346 + $formId = $atts['id'];
1347 + $form = wpFluent()->table('fluentform_forms')->find($formId);
1348 +
1349 + if (!$form) {
1350 + return '';
1351 + }
1352 +
1353 + if ('submission_count' == $atts['info']) {
1354 + $countQuery = wpFluent()->table('fluentform_submissions')
1355 + ->where('form_id', $formId);
1356 +
1357 + if ('trashed' != $atts['status'] && 'no' == $atts['with_trashed']) {
1358 + $countQuery = $countQuery->where('status', '!=', 'trashed');
1359 + }
1360 +
1361 + if ('all' == $atts['status']) {
1362 + // ...
1363 + } elseif ('favourites' == $atts['status']) {
1364 + $countQuery = $countQuery->where('is_favourite', '=', 1);
1365 + } else {
1366 + $countQuery = $countQuery->where('status', '=', sanitize_key($atts['status']));
1367 + }
1368 + if ($atts['payment_status'] && defined('FLUENTFORMPRO') && 'all' != $atts['payment_status']) {
1369 + $countQuery = $countQuery->where('payment_status', '=', sanitize_key($atts['payment_status']));
1370 + }
1371 +
1372 + $total = $countQuery->count();
1373 +
1374 + if ($atts['substract_from']) {
1375 + $total = intval($atts['substract_from']) - $total;
1376 + }
1377 +
1378 + if ('yes' == $atts['hide_on_zero'] && !$total || $total < 0) {
1379 + return '';
1380 + }
1381 +
1382 + return $total;
1383 + } elseif ('created_at' == $atts['info']) {
1384 + if ($atts['date_format']) {
1385 + $dateFormat = $atts['date_format'];
1386 + } else {
1387 + $dateFormat = get_option('date_format') . ' ' . get_option('time_format');
1388 + }
1389 + return esc_html(date($dateFormat, strtotime($form->created_at)));
1390 + } elseif ('updated_at' == $atts['info']) {
1391 + if ($atts['date_format']) {
1392 + $dateFormat = $atts['date_format'];
1393 + } else {
1394 + $dateFormat = get_option('date_format') . ' ' . get_option('time_format');
1395 + }
1396 + return esc_html(date($dateFormat, strtotime($form->updated_at)));
1397 + } elseif ('payment_total' == $atts['info']) {
1398 + if (!defined('FLUENTFORMPRO')) {
1399 + return '';
1400 + }
1401 +
1402 + global $wpdb;
1403 + $countQuery = wpFluent()
1404 + ->table('fluentform_submissions')
1405 + ->select(wpFluent()->raw('SUM(payment_total) as payment_total'))
1406 + ->where('form_id', $formId);
1407 +
1408 + if ('trashed' != $atts['status'] && 'no' == $atts['with_trashed']) {
1409 + $countQuery = $countQuery->where('status', '!=', 'trashed');
1410 + }
1411 +
1412 + if ('all' == $atts['status']) {
1413 + // ...
1414 + } elseif ('favourites' == $atts['status']) {
1415 + $countQuery = $countQuery->where('is_favourite', '=', 1);
1416 + } else {
1417 + $countQuery = $countQuery->where('status', '=', sanitize_key($atts['status']));
1418 + }
1419 +
1420 + if ('all' == $atts['payment_status']) {
1421 + // ...
1422 + } elseif ($atts['payment_status']) {
1423 + $countQuery = $countQuery->where('payment_status', '=', sanitize_key($atts['payment_status']));
1424 + }
1425 +
1426 + $row = $countQuery->first();
1427 +
1428 + $total = 0;
1429 + if ($row) {
1430 + $total = $row->payment_total;
1431 + }
1432 +
1433 + if ($atts['substract_from']) {
1434 + $total = intval($atts['substract_from'] * 100) - $total;
1435 + }
1436 +
1437 + if ('yes' == $atts['hide_on_zero'] && !$total) {
1438 + return '';
1439 + }
1440 +
1441 + if ('yes' == $atts['currency_formatted']) {
1442 + $currency = \FluentFormPro\Payments\PaymentHelper::getFormCurrency($formId);
1443 + return \FluentFormPro\Payments\PaymentHelper::formatMoney($total, $currency);
1444 + }
1445 +
1446 + if (!$total) {
1447 + return 0;
1448 + }
1449 +
1450 + return $total / 100;
1451 + }
1452 +
1453 + return '';
1454 + });
1455 +
1456 + $this->app->addShortCode('ff_get', function ($atts) {
1457 + $atts = shortcode_atts([
1458 + 'param' => '',
1459 + ], $atts);
1460 +
1461 + if ('' === $atts['param']) {
1462 + return '';
1463 + }
1464 +
1465 + $value = $this->app->request->get($atts['param']);
1466 +
1467 + if (null === $value || '' === $value) {
1468 + return '';
1469 + }
1470 +
1471 + return esc_html(Helper::flattenRequestValue($value));
1472 + });
1473 +
1474 + $this->app->addShortcode('ff_entry',function($atts){
1475 + ob_start();
1476 +
1477 + $atts = shortcode_atts([
1478 + 'form_id' => '',
1479 + 'serial_number' => '',
1480 + 'field' => '',
1481 + 'is_html' => true,
1482 + ], $atts);
1483 +
1484 + if (empty($atts['form_id']) || empty($atts['field'])) {
1485 + return '';
1486 + }
1487 +
1488 +
1489 + $formId = (int) $atts['form_id'];
1490 + $form = wpFluent()->table('fluentform_forms')->find($formId);
1491 + if (!$form) {
1492 + return __('Form not found.', 'fluentform');
1493 + }
1494 + $isHtml = $atts['is_html'] === 'true' ? true : false;
1495 + $submission = (new \FluentForm\App\Services\Submission\SubmissionService())->findBySerialID($formId, $atts['serial_number'],$isHtml);
1496 + if (!$submission) {
1497 + return __('No entry found.', 'fluentform');
1498 + }
1499 +
1500 + $input = $submission->user_inputs;
1501 + $field = sanitize_text_field($atts['field']);
1502 + $fieldVal = ArrayHelper::get($input, $field, '');
1503 +
1504 + $response = FormDataParser::formatValue($fieldVal);
1505 + echo $atts['is_html'] ? wp_kses_post($response) : esc_html($response);
1506 +
1507 + return ob_get_clean();
1508 + });
1509 +
1510 + }
1511 +
1512 + private function localizeJavaScriptMessages($form)
1513 + {
1514 + // Form submission messages
1515 + $submissionMessages = [
1516 + 'file_upload_in_progress' => __('File upload in progress. Please wait...', 'fluentform'),
1517 + 'javascript_handler_failed' => __('Javascript handler could not be loaded. Form submission has been failed. Reload the page and try again', 'fluentform')
1518 + ];
1519 + $submissionMessages = apply_filters('fluentform/form_submission_messages', $submissionMessages, $form);
1520 + wp_localize_script('fluent-form-submission', 'fluentform_submission_messages_' . $form->id, $submissionMessages);
1521 +
1522 + // Payment handler messages
1523 + $paymentMessages = [
1524 + 'stock_out_message' => __('This Item is Stock Out', 'fluentform'),
1525 + 'item_label' => __('Item', 'fluentform'),
1526 + 'price_label' => __('Price', 'fluentform'),
1527 + 'qty_label' => __('Qty', 'fluentform'),
1528 + 'line_total_label' => __('Line Total', 'fluentform'),
1529 + 'sub_total_label' => __('Sub Total', 'fluentform'),
1530 + 'discount_label' => __('Discount', 'fluentform'),
1531 + 'total_label' => __('Total', 'fluentform'),
1532 + 'signup_fee_label' => __('Signup Fee', 'fluentform'),
1533 + 'trial_label' => __('Trial', 'fluentform'),
1534 + 'processing_text' => __('Processing...', 'fluentform'),
1535 + 'confirming_text' => __('Confirming...', 'fluentform')
1536 + ];
1537 + $paymentMessages = apply_filters('fluentform/payment_handler_messages', $paymentMessages, $form);
1538 + wp_localize_script('fluent-form-submission', 'fluentform_payment_messages_' . $form->id, $paymentMessages);
1539 +
1540 + // Form save progress messages
1541 + $saveProgressMessages = [
1542 + 'copy_button' => __('Copy', 'fluentform'),
1543 + 'email_button' => __('Email', 'fluentform'),
1544 + 'email_placeholder' => __('Your Email Here', 'fluentform'),
1545 + 'copy_success' => __('Copied', 'fluentform')
1546 + ];
1547 + $saveProgressMessages = apply_filters('fluentform/form_save_progress_messages', $saveProgressMessages, $form);
1548 + wp_localize_script('fluent-form-submission', 'fluentform_save_progress_messages_' . $form->id, $saveProgressMessages);
1549 +
1550 + // Address autocomplete messages
1551 + $addressMessages = [
1552 + 'please_wait' => __('Please wait ...', 'fluentform'),
1553 + 'location_not_determined' => __('Could not determine address from location.', 'fluentform'),
1554 + 'address_fetch_failed' => __('Failed to fetch address from coordinates.', 'fluentform'),
1555 + 'geolocation_failed' => __('Geolocation failed or was denied.', 'fluentform'),
1556 + 'geolocation_not_supported' => __('Geolocation is not supported by this browser.', 'fluentform')
1557 + ];
1558 + $addressMessages = apply_filters('fluentform/address_autocomplete_messages', $addressMessages, $form);
1559 + wp_localize_script('fluent-form-submission', 'fluentform_address_messages_' . $form->id, $addressMessages);
1560 +
1561 + // Payment gateway messages
1562 + $gatewayMessages = [
1563 + 'request_failed' => __('Request failed. Please try again', 'fluentform'),
1564 + 'payment_failed' => __('Payment process failed!', 'fluentform'),
1565 + 'no_method_found' => __('No method found', 'fluentform'),
1566 + 'processing_text' => __('Processing...', 'fluentform')
1567 + ];
1568 + $gatewayMessages = apply_filters('fluentform/payment_gateway_messages', $gatewayMessages, $form);
1569 + wp_localize_script('fluent-form-submission', 'fluentform_gateway_messages_' . $form->id, $gatewayMessages);
1570 + }
1571 +}