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 +1018 -430 3.6.516.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,117 +619,270 @@
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]);
601 853
602 -
603 854 $attrDefaultValues = [];
604 855
605 856 foreach ($patterns as $pattern) {
606 857 // The default value for each pattern will be resolved here.
607 - $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);
608 870 }
609 871
610 872 // Raising an event so that others can hook into it and modify the default values later.
611 - $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 + );
612 882
883 + $attrDefaultValues = (array) apply_filters('fluentform/parse_default_values', $attrDefaultValues);
884 +
613 885 if (isset($attrDefaultValues['{payment_total}'])) {
614 886 $attrDefaultValues['{payment_total}'] = '<span class="ff_order_total"></span>';
615 887 }
616 888
@@ -620,47 +892,49 @@
620 892
621 893 /**
622 894 * Register renderer actions for compiling each element
623 895 *
624 - * @return void
896 + * @return void
625 897 */
626 898 public function addRendererActions()
627 899 {
628 900 $actionMappings = [
629 - 'Select@compile' => ['fluentform_render_item_select'],
630 - 'Rating@compile' => ['fluentform_render_item_ratings'],
631 - 'Address@compile' => ['fluentform_render_item_address'],
632 - 'Name@compile' => ['fluentform_render_item_input_name'],
633 - 'TextArea@compile' => ['fluentform_render_item_textarea'],
634 - 'DateTime@compile' => ['fluentform_render_item_input_date'],
635 - 'Recaptcha@compile' => ['fluentform_render_item_recaptcha'],
636 - 'Container@compile' => ['fluentform_render_item_container'],
637 - 'CustomHtml@compile' => ['fluentform_render_item_custom_html'],
638 - 'SectionBreak@compile' => ['fluentform_render_item_section_break'],
639 - 'SubmitButton@compile' => ['fluentform_render_item_submit_button'],
640 - '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'],
641 915
642 916 'TermsAndConditions@compile' => [
643 - 'fluentform_render_item_terms_and_condition',
644 - 'fluentform_render_item_gdpr_agreement'
917 + 'fluentform/render_item_terms_and_condition',
918 + 'fluentform/render_item_gdpr_agreement',
645 919 ],
646 920
647 921 'TabularGrid@compile' => [
648 - 'fluentform_render_item_tabular_grid'
922 + 'fluentform/render_item_tabular_grid',
649 923 ],
650 924
651 925 'Checkable@compile' => [
652 - 'fluentform_render_item_input_radio',
653 - 'fluentform_render_item_input_checkbox',
926 + 'fluentform/render_item_input_radio',
927 + 'fluentform/render_item_input_checkbox',
654 928 ],
655 929
656 930 'Text@compile' => [
657 - 'fluentform_render_item_input_url',
658 - 'fluentform_render_item_input_text',
659 - 'fluentform_render_item_input_email',
660 - 'fluentform_render_item_input_number',
661 - 'fluentform_render_item_input_hidden',
662 - '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',
663 937 ],
664 938 ];
665 939
666 940 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
@@ -666,10 +940,10 @@
666 940 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
667 941 foreach ($actionMappings as $handler => $actions) {
668 942 foreach ($actions as $action) {
669 943 $this->app->addAction($action, function () use ($path, $handler) {
670 - list($class, $method) = $this->app->parseHandler($path . $handler);
671 - 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());
672 946 }, 10, 2);
673 947 }
674 948 }
675 949 }
@@ -676,30 +950,47 @@
676 950
677 951 /**
678 952 * Register dynamic value shortcode parser (filter default value)
679 953 *
680 - * @return void
954 + * @return void
681 955 */
682 956 public function addFluentFormDefaultValueParser()
683 957 {
684 - $this->app->addFilter('fluentform_parse_default_value', function ($value, $form) {
958 + $this->app->addFilter('fluentform/parse_default_value', function ($value, $form) {
685 959 return EditorShortcodeParser::filter($value, $form);
686 960 }, 10, 2);
687 961 }
688 962
689 963 /**
690 - * Register filter to check whether the form is renderable
964 + * Register filter to check whether the form is renderable or active
691 965 *
692 - * @return mixed
966 + * @return mixed
693 967 */
694 968 public function addIsRenderableFilter()
695 969 {
696 - $this->app->addFilter('fluentform_is_form_renderable', function ($isRenderable, $form) {
697 - $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 + }
698 977
699 - 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) {
700 991 if (in_array($key, $checkables)) {
701 - $isRenderable['status'] = $this->{$key}($restrictions, $form, $isRenderable);
992 + $isRenderable['status'] = $this->{$key}($restrictionSettings, $form, $isRenderable);
702 993 if (!$isRenderable['status']) {
703 994 $isRenderable['status'] = false;
704 995 return $isRenderable;
705 996 }
@@ -704,8 +995,12 @@
704 995 return $isRenderable;
705 996 }
706 997 }
707 998 }
999 + if($form->status == 'unpublished'){
1000 + $isRenderable['status'] = false;
1001 + $isRenderable['message'] = apply_filters('fluentform/unpublished_form_submission_message',__('Invalid Form!', 'fluentform'));
1002 + }
708 1003
709 1004 return $isRenderable;
710 1005 }, 10, 2);
711 1006 }
@@ -718,12 +1013,14 @@
718 1013 * @return bool
719 1014 */
720 1015 private function limitNumberOfEntries($restrictions, $form, &$isRenderable)
721 1016 {
722 - if (!$restrictions['enabled']) {
1017 +
1018 + if (!Arr::isTrue($restrictions, 'enabled') || !isset($restrictions['period']) || !isset($restrictions['numberOfEntries'])) {
723 1019 return true;
724 1020 }
725 1021
1022 +
726 1023 $col = 'created_at';
727 1024 $period = $restrictions['period'];
728 1025 $maxAllowedEntries = $restrictions['numberOfEntries'];
729 1026
@@ -734,27 +1031,27 @@
734 1031 $query = wpFluent()->table('fluentform_submissions')
735 1032 ->where('form_id', $form->id)
736 1033 ->where('status', '!=', 'trashed');
737 1034
738 - if ($period == 'day') {
1035 + if ('day' == $period) {
739 1036 $year = "YEAR(`{$col}`) = YEAR(NOW())";
740 1037 $month = "MONTH(`{$col}`) = MONTH(NOW())";
741 1038 $day = "DAY(`{$col}`) = DAY(NOW())";
742 - $query->where(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
743 - } elseif ($period == 'week') {
744 - $query->where(
1039 + $query->whereRaw(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
1040 + } elseif ('week' == $period) {
1041 + $query->whereRaw(
745 1042 wpFluent()->raw("YEARWEEK(`{$col}`, 1) = YEARWEEK(CURDATE(), 1)")
746 1043 );
747 - } elseif ($period == 'month') {
1044 + } elseif ('month' == $period) {
748 1045 $year = "YEAR(`{$col}`) = YEAR(NOW())";
749 1046 $month = "MONTH(`{$col}`) = MONTH(NOW())";
750 - $query->where(wpFluent()->raw("{$year} AND {$month}"));
751 - } elseif ($period == 'year') {
752 - $query->where(wpFluent()->raw("YEAR(`{$col}`) = YEAR(NOW())"));
753 - } 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) {
754 1051 $ip = $this->app->request->getIp();
755 1052 $query->where('ip', $ip);
756 - } else if ($period == 'per_user_id') {
1053 + } elseif ('per_user_id' == $period) {
757 1054 $userId = get_current_user_id();
758 1055 if (!$userId) {
759 1056 return true;
760 1057 }
@@ -762,11 +1059,10 @@
762 1059 }
763 1060
764 1061 $count = $query->count();
765 1062
766 -
767 1063 if ($count >= $maxAllowedEntries) {
768 - $isRenderable['message'] = $restrictions['limitReachedMsg'];
1064 + $isRenderable['message'] = apply_filters('fluentform/entry_limit_reached_message', $restrictions['limitReachedMsg'], $form);
769 1065 return false;
770 1066 }
771 1067
772 1068 return true;
@@ -772,9 +1068,9 @@
772 1068 return true;
773 1069 }
774 1070
775 1071 /**
776 - * Check if form has scheduled date and open for submission
1072 + * Check if form has scheduled date & weekdays and open for submission
777 1073 *
778 1074 * @param array $restrictions
779 1075 *
780 1076 * @return bool
@@ -780,9 +1076,9 @@
780 1076 * @return bool
781 1077 */
782 1078 private function scheduleForm($restrictions, $form, &$isRenderable)
783 1079 {
784 - if (!$restrictions['enabled']) {
1080 + if (!Arr::isTrue($restrictions, 'enabled')) {
785 1081 return true;
786 1082 }
787 1083
788 1084 $time = time();
@@ -789,16 +1085,23 @@
789 1085 $start = strtotime($restrictions['start']);
790 1086 $end = strtotime($restrictions['end']);
791 1087
792 1088 if ($time < $start) {
793 - $isRenderable['message'] = $restrictions['pendingMsg'];
1089 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_pending_message', $restrictions['pendingMsg'], $form->id);
1090 + return false;
1091 + }
794 1092
1093 + if ($time >= $end) {
1094 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_expired_message', $restrictions['expiredMsg'], $form->id);
1095 +
795 1096 return false;
796 1097 }
797 1098
798 - 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)) {
799 1103 $isRenderable['message'] = $restrictions['expiredMsg'];
800 -
801 1104 return false;
802 1105 }
803 1106
804 1107 return true;
@@ -812,14 +1115,14 @@
812 1115 * @return bool
813 1116 */
814 1117 private function requireLogin($restrictions, $form, &$isRenderable)
815 1118 {
816 - if (!$restrictions['enabled']) {
1119 + if (!Arr::isTrue($restrictions, 'enabled')) {
817 1120 return true;
818 1121 }
819 1122
820 1123 if (!($isLoggedIn = is_user_logged_in())) {
821 - $isRenderable['message'] = $restrictions['requireLoginMsg'];
1124 + $isRenderable['message'] = apply_filters('fluentform/form_requires_login_message', $restrictions['requireLoginMsg'], $form);
822 1125 }
823 1126
824 1127 return $isLoggedIn;
825 1128 }
@@ -826,9 +1129,9 @@
826 1129
827 1130 /**
828 1131 * Register fluentform_submission_inserted actions
829 1132 *
830 - * @return void
1133 + * @return void
831 1134 */
832 1135 public function addFluentformSubmissionInsertedFilter()
833 1136 {
834 1137 (new EmailNotificationActions($this->app))->register();
@@ -836,16 +1139,22 @@
836 1139
837 1140 /**
838 1141 * Add inline scripts [Add localized script using same var]
839 1142 *
840 - * @return void
1143 + * @return void
841 1144 */
842 1145 private function addInlineVars()
843 1146 {
844 - if (!defined('ELEMENTOR_PRO_VERSION')) {
1147 + if (!defined('ELEMENTOR_PRO_VERSION') || $this->elementorPopUpHandler) {
845 1148 return '';
846 1149 }
847 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 +
848 1157 $actionName = 'wp_footer';
849 1158 if (is_admin()) {
850 1159 $actionName = 'admin_footer';
851 1160 }
@@ -852,13 +1161,28 @@
852 1161
853 1162 add_action($actionName, function () {
854 1163 ?>
855 1164 <script type="text/javascript">
856 - <?php if(defined('ELEMENTOR_PRO_VERSION')): ?>
857 - jQuery(document).on('elementor/popup/show', function (event, id, instance) {
858 - 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 + }
859 1183 if (ffForms.length) {
860 - jQuery.each(ffForms, function (index, ffForm) {
1184 + jQuery.each(ffForms, function(index, ffForm) {
861 1185 jQuery(ffForm).trigger('reInitExtras');
862 1186 jQuery(document).trigger('ff_reinit', [ffForm]);
863 1187 });
864 1188 }
@@ -869,14 +1193,14 @@
869 1193 }, 999);
870 1194 return '';
871 1195 }
872 1196
873 - private function getDatei18n()
1197 + public static function getDatei18n()
874 1198 {
875 - $i18n = array(
1199 + $i18n = [
876 1200 'previousMonth' => __('Previous Month', 'fluentform'),
877 - 'nextMonth' => __('Next Month', 'fluentform'),
878 - 'months' => [
1201 + 'nextMonth' => __('Next Month', 'fluentform'),
1202 + 'months' => [
879 1203 'shorthand' => [
880 1204 __('Jan', 'fluentform'),
881 1205 __('Feb', 'fluentform'),
882 1206 __('Mar', 'fluentform'),
@@ -887,9 +1211,9 @@
887 1211 __('Aug', 'fluentform'),
888 1212 __('Sep', 'fluentform'),
889 1213 __('Oct', 'fluentform'),
890 1214 __('Nov', 'fluentform'),
891 - __('Dec', 'fluentform')
1215 + __('Dec', 'fluentform'),
892 1216 ],
893 1217 'longhand' => [
894 1218 __('January', 'fluentform'),
895 1219 __('February', 'fluentform'),
@@ -901,13 +1225,13 @@
901 1225 __('August', 'fluentform'),
902 1226 __('September', 'fluentform'),
903 1227 __('October', 'fluentform'),
904 1228 __('November', 'fluentform'),
905 - __('December', 'fluentform')
906 - ]
1229 + __('December', 'fluentform'),
1230 + ],
907 1231 ],
908 1232 'weekdays' => [
909 - 'longhand' => array(
1233 + 'longhand' => [
910 1234 __('Sunday', 'fluentform'),
911 1235 __('Monday', 'fluentform'),
912 1236 __('Tuesday', 'fluentform'),
913 1237 __('Wednesday', 'fluentform'),
@@ -912,11 +1236,11 @@
912 1236 __('Tuesday', 'fluentform'),
913 1237 __('Wednesday', 'fluentform'),
914 1238 __('Thursday', 'fluentform'),
915 1239 __('Friday', 'fluentform'),
916 - __('Saturday', 'fluentform')
917 - ),
918 - 'shorthand' => array(
1240 + __('Saturday', 'fluentform'),
1241 + ],
1242 + 'shorthand' => [
919 1243 __('Sun', 'fluentform'),
920 1244 __('Mon', 'fluentform'),
921 1245 __('Tue', 'fluentform'),
922 1246 __('Wed', 'fluentform'),
@@ -921,10 +1245,10 @@
921 1245 __('Tue', 'fluentform'),
922 1246 __('Wed', 'fluentform'),
923 1247 __('Thu', 'fluentform'),
924 1248 __('Fri', 'fluentform'),
925 - __('Sat', 'fluentform')
926 - )
1249 + __('Sat', 'fluentform'),
1250 + ],
927 1251 ],
928 1252 'daysInMonth' => [
929 1253 31,
930 1254 28,
@@ -936,20 +1260,21 @@
936 1260 31,
937 1261 30,
938 1262 31,
939 1263 30,
940 - 31
1264 + 31,
941 1265 ],
942 - 'rangeSeparator' => __(' to ', 'fluentform'),
1266 + 'rangeSeparator' => __(' to ', 'fluentform'),
943 1267 'weekAbbreviation' => __('Wk', 'fluentform'),
944 - 'scrollTitle' => __('Scroll to increment', 'fluentform'),
945 - 'toggleTitle' => __('Click to toggle', 'fluentform'),
946 - 'amPM' => [
1268 + 'scrollTitle' => __('Scroll to increment', 'fluentform'),
1269 + 'toggleTitle' => __('Click to toggle', 'fluentform'),
1270 + 'amPM' => [
947 1271 __('AM', 'fluentform'),
948 - __('PM', 'fluentform')
1272 + __('PM', 'fluentform'),
949 1273 ],
950 - 'yearAriaLabel' => __('Year', 'fluentform')
951 - );
1274 + 'yearAriaLabel' => __('Year', 'fluentform'),
1275 + 'firstDayOfWeek' => (int) get_option('start_of_week'),
1276 + ];
952 1277
953 1278 return apply_filters('fluentform/date_i18n', $i18n);
954 1279 }
955 1280
@@ -962,13 +1287,276 @@
962 1287 'form_step',
963 1288 'input_file',
964 1289 'input_image',
965 1290 'net_promoter_score',
966 - 'featured_image'
1291 + 'featured_image',
967 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 + }
968 1300
969 - if ($formBuilder->conditions || array_intersect($formBuilder->fieldLists, $advancedFields)) {
970 - 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;
971 1312 }
1313 + return Helper::getNumericValue($value, $formatter);
972 1314 }
973 1315
974 -}
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 +}