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 +1029 -432 3.6.51 → 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,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,167 +619,331 @@
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
617 - // Finally, replace the patterns with the replacements and return the output HTML.
618 - 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);
619 900 }
620 901
621 902 /**
622 903 * Register renderer actions for compiling each element
623 904 *
624 - * @return void
905 + * @return void
625 906 */
626 907 public function addRendererActions()
627 908 {
628 909 $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'],
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'],
641 924
642 925 'TermsAndConditions@compile' => [
643 - 'fluentform_render_item_terms_and_condition',
644 - 'fluentform_render_item_gdpr_agreement'
926 + 'fluentform/render_item_terms_and_condition',
927 + 'fluentform/render_item_gdpr_agreement',
645 928 ],
646 929
647 930 'TabularGrid@compile' => [
648 - 'fluentform_render_item_tabular_grid'
931 + 'fluentform/render_item_tabular_grid',
649 932 ],
650 933
651 934 'Checkable@compile' => [
652 - 'fluentform_render_item_input_radio',
653 - 'fluentform_render_item_input_checkbox',
935 + 'fluentform/render_item_input_radio',
936 + 'fluentform/render_item_input_checkbox',
654 937 ],
655 938
656 939 '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',
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',
663 946 ],
664 947 ];
665 948
666 949 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
@@ -666,10 +949,10 @@
666 949 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
667 950 foreach ($actionMappings as $handler => $actions) {
668 951 foreach ($actions as $action) {
669 952 $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());
953 + list($class, $method) = $this->app->parseHookHandler($path . $handler);
954 + call_user_func_array([$class, $method], func_get_args());
672 955 }, 10, 2);
673 956 }
674 957 }
675 958 }
@@ -676,30 +959,47 @@
676 959
677 960 /**
678 961 * Register dynamic value shortcode parser (filter default value)
679 962 *
680 - * @return void
963 + * @return void
681 964 */
682 965 public function addFluentFormDefaultValueParser()
683 966 {
684 - $this->app->addFilter('fluentform_parse_default_value', function ($value, $form) {
967 + $this->app->addFilter('fluentform/parse_default_value', function ($value, $form) {
685 968 return EditorShortcodeParser::filter($value, $form);
686 969 }, 10, 2);
687 970 }
688 971
689 972 /**
690 - * Register filter to check whether the form is renderable
973 + * Register filter to check whether the form is renderable or active
691 974 *
692 - * @return mixed
975 + * @return mixed
693 976 */
694 977 public function addIsRenderableFilter()
695 978 {
696 - $this->app->addFilter('fluentform_is_form_renderable', function ($isRenderable, $form) {
697 - $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 + }
698 986
699 - 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) {
700 1000 if (in_array($key, $checkables)) {
701 - $isRenderable['status'] = $this->{$key}($restrictions, $form, $isRenderable);
1001 + $isRenderable['status'] = $this->{$key}($restrictionSettings, $form, $isRenderable);
702 1002 if (!$isRenderable['status']) {
703 1003 $isRenderable['status'] = false;
704 1004 return $isRenderable;
705 1005 }
@@ -704,8 +1004,12 @@
704 1004 return $isRenderable;
705 1005 }
706 1006 }
707 1007 }
1008 + if($form->status == 'unpublished'){
1009 + $isRenderable['status'] = false;
1010 + $isRenderable['message'] = apply_filters('fluentform/unpublished_form_submission_message',__('Invalid Form!', 'fluentform'));
1011 + }
708 1012
709 1013 return $isRenderable;
710 1014 }, 10, 2);
711 1015 }
@@ -718,12 +1022,14 @@
718 1022 * @return bool
719 1023 */
720 1024 private function limitNumberOfEntries($restrictions, $form, &$isRenderable)
721 1025 {
722 - if (!$restrictions['enabled']) {
1026 +
1027 + if (!Arr::isTrue($restrictions, 'enabled') || !isset($restrictions['period']) || !isset($restrictions['numberOfEntries'])) {
723 1028 return true;
724 1029 }
725 1030
1031 +
726 1032 $col = 'created_at';
727 1033 $period = $restrictions['period'];
728 1034 $maxAllowedEntries = $restrictions['numberOfEntries'];
729 1035
@@ -734,27 +1040,27 @@
734 1040 $query = wpFluent()->table('fluentform_submissions')
735 1041 ->where('form_id', $form->id)
736 1042 ->where('status', '!=', 'trashed');
737 1043
738 - if ($period == 'day') {
1044 + if ('day' == $period) {
739 1045 $year = "YEAR(`{$col}`) = YEAR(NOW())";
740 1046 $month = "MONTH(`{$col}`) = MONTH(NOW())";
741 1047 $day = "DAY(`{$col}`) = DAY(NOW())";
742 - $query->where(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
743 - } elseif ($period == 'week') {
744 - $query->where(
1048 + $query->whereRaw(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
1049 + } elseif ('week' == $period) {
1050 + $query->whereRaw(
745 1051 wpFluent()->raw("YEARWEEK(`{$col}`, 1) = YEARWEEK(CURDATE(), 1)")
746 1052 );
747 - } elseif ($period == 'month') {
1053 + } elseif ('month' == $period) {
748 1054 $year = "YEAR(`{$col}`) = YEAR(NOW())";
749 1055 $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') {
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) {
754 1060 $ip = $this->app->request->getIp();
755 1061 $query->where('ip', $ip);
756 - } else if ($period == 'per_user_id') {
1062 + } elseif ('per_user_id' == $period) {
757 1063 $userId = get_current_user_id();
758 1064 if (!$userId) {
759 1065 return true;
760 1066 }
@@ -762,11 +1068,10 @@
762 1068 }
763 1069
764 1070 $count = $query->count();
765 1071
766 -
767 1072 if ($count >= $maxAllowedEntries) {
768 - $isRenderable['message'] = $restrictions['limitReachedMsg'];
1073 + $isRenderable['message'] = apply_filters('fluentform/entry_limit_reached_message', $restrictions['limitReachedMsg'], $form);
769 1074 return false;
770 1075 }
771 1076
772 1077 return true;
@@ -772,9 +1077,9 @@
772 1077 return true;
773 1078 }
774 1079
775 1080 /**
776 - * Check if form has scheduled date and open for submission
1081 + * Check if form has scheduled date & weekdays and open for submission
777 1082 *
778 1083 * @param array $restrictions
779 1084 *
780 1085 * @return bool
@@ -780,9 +1085,9 @@
780 1085 * @return bool
781 1086 */
782 1087 private function scheduleForm($restrictions, $form, &$isRenderable)
783 1088 {
784 - if (!$restrictions['enabled']) {
1089 + if (!Arr::isTrue($restrictions, 'enabled')) {
785 1090 return true;
786 1091 }
787 1092
788 1093 $time = time();
@@ -789,16 +1094,23 @@
789 1094 $start = strtotime($restrictions['start']);
790 1095 $end = strtotime($restrictions['end']);
791 1096
792 1097 if ($time < $start) {
793 - $isRenderable['message'] = $restrictions['pendingMsg'];
1098 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_pending_message', $restrictions['pendingMsg'], $form->id);
1099 + return false;
1100 + }
794 1101
1102 + if ($time >= $end) {
1103 + $isRenderable['message'] = apply_filters('fluentform/schedule_form_expired_message', $restrictions['expiredMsg'], $form->id);
1104 +
795 1105 return false;
796 1106 }
797 1107
798 - 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)) {
799 1112 $isRenderable['message'] = $restrictions['expiredMsg'];
800 -
801 1113 return false;
802 1114 }
803 1115
804 1116 return true;
@@ -812,14 +1124,14 @@
812 1124 * @return bool
813 1125 */
814 1126 private function requireLogin($restrictions, $form, &$isRenderable)
815 1127 {
816 - if (!$restrictions['enabled']) {
1128 + if (!Arr::isTrue($restrictions, 'enabled')) {
817 1129 return true;
818 1130 }
819 1131
820 1132 if (!($isLoggedIn = is_user_logged_in())) {
821 - $isRenderable['message'] = $restrictions['requireLoginMsg'];
1133 + $isRenderable['message'] = apply_filters('fluentform/form_requires_login_message', $restrictions['requireLoginMsg'], $form);
822 1134 }
823 1135
824 1136 return $isLoggedIn;
825 1137 }
@@ -826,9 +1138,9 @@
826 1138
827 1139 /**
828 1140 * Register fluentform_submission_inserted actions
829 1141 *
830 - * @return void
1142 + * @return void
831 1143 */
832 1144 public function addFluentformSubmissionInsertedFilter()
833 1145 {
834 1146 (new EmailNotificationActions($this->app))->register();
@@ -836,16 +1148,22 @@
836 1148
837 1149 /**
838 1150 * Add inline scripts [Add localized script using same var]
839 1151 *
840 - * @return void
1152 + * @return void
841 1153 */
842 1154 private function addInlineVars()
843 1155 {
844 - if (!defined('ELEMENTOR_PRO_VERSION')) {
1156 + if (!defined('ELEMENTOR_PRO_VERSION') || $this->elementorPopUpHandler) {
845 1157 return '';
846 1158 }
847 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 +
848 1166 $actionName = 'wp_footer';
849 1167 if (is_admin()) {
850 1168 $actionName = 'admin_footer';
851 1169 }
@@ -852,13 +1170,28 @@
852 1170
853 1171 add_action($actionName, function () {
854 1172 ?>
855 1173 <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');
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 + }
859 1192 if (ffForms.length) {
860 - jQuery.each(ffForms, function (index, ffForm) {
1193 + jQuery.each(ffForms, function(index, ffForm) {
861 1194 jQuery(ffForm).trigger('reInitExtras');
862 1195 jQuery(document).trigger('ff_reinit', [ffForm]);
863 1196 });
864 1197 }
@@ -869,14 +1202,14 @@
869 1202 }, 999);
870 1203 return '';
871 1204 }
872 1205
873 - private function getDatei18n()
1206 + public static function getDatei18n()
874 1207 {
875 - $i18n = array(
1208 + $i18n = [
876 1209 'previousMonth' => __('Previous Month', 'fluentform'),
877 - 'nextMonth' => __('Next Month', 'fluentform'),
878 - 'months' => [
1210 + 'nextMonth' => __('Next Month', 'fluentform'),
1211 + 'months' => [
879 1212 'shorthand' => [
880 1213 __('Jan', 'fluentform'),
881 1214 __('Feb', 'fluentform'),
882 1215 __('Mar', 'fluentform'),
@@ -887,9 +1220,9 @@
887 1220 __('Aug', 'fluentform'),
888 1221 __('Sep', 'fluentform'),
889 1222 __('Oct', 'fluentform'),
890 1223 __('Nov', 'fluentform'),
891 - __('Dec', 'fluentform')
1224 + __('Dec', 'fluentform'),
892 1225 ],
893 1226 'longhand' => [
894 1227 __('January', 'fluentform'),
895 1228 __('February', 'fluentform'),
@@ -901,13 +1234,13 @@
901 1234 __('August', 'fluentform'),
902 1235 __('September', 'fluentform'),
903 1236 __('October', 'fluentform'),
904 1237 __('November', 'fluentform'),
905 - __('December', 'fluentform')
906 - ]
1238 + __('December', 'fluentform'),
1239 + ],
907 1240 ],
908 1241 'weekdays' => [
909 - 'longhand' => array(
1242 + 'longhand' => [
910 1243 __('Sunday', 'fluentform'),
911 1244 __('Monday', 'fluentform'),
912 1245 __('Tuesday', 'fluentform'),
913 1246 __('Wednesday', 'fluentform'),
@@ -912,11 +1245,11 @@
912 1245 __('Tuesday', 'fluentform'),
913 1246 __('Wednesday', 'fluentform'),
914 1247 __('Thursday', 'fluentform'),
915 1248 __('Friday', 'fluentform'),
916 - __('Saturday', 'fluentform')
917 - ),
918 - 'shorthand' => array(
1249 + __('Saturday', 'fluentform'),
1250 + ],
1251 + 'shorthand' => [
919 1252 __('Sun', 'fluentform'),
920 1253 __('Mon', 'fluentform'),
921 1254 __('Tue', 'fluentform'),
922 1255 __('Wed', 'fluentform'),
@@ -921,10 +1254,10 @@
921 1254 __('Tue', 'fluentform'),
922 1255 __('Wed', 'fluentform'),
923 1256 __('Thu', 'fluentform'),
924 1257 __('Fri', 'fluentform'),
925 - __('Sat', 'fluentform')
926 - )
1258 + __('Sat', 'fluentform'),
1259 + ],
927 1260 ],
928 1261 'daysInMonth' => [
929 1262 31,
930 1263 28,
@@ -936,20 +1269,21 @@
936 1269 31,
937 1270 30,
938 1271 31,
939 1272 30,
940 - 31
1273 + 31,
941 1274 ],
942 - 'rangeSeparator' => __(' to ', 'fluentform'),
1275 + 'rangeSeparator' => __(' to ', 'fluentform'),
943 1276 'weekAbbreviation' => __('Wk', 'fluentform'),
944 - 'scrollTitle' => __('Scroll to increment', 'fluentform'),
945 - 'toggleTitle' => __('Click to toggle', 'fluentform'),
946 - 'amPM' => [
1277 + 'scrollTitle' => __('Scroll to increment', 'fluentform'),
1278 + 'toggleTitle' => __('Click to toggle', 'fluentform'),
1279 + 'amPM' => [
947 1280 __('AM', 'fluentform'),
948 - __('PM', 'fluentform')
1281 + __('PM', 'fluentform'),
949 1282 ],
950 - 'yearAriaLabel' => __('Year', 'fluentform')
951 - );
1283 + 'yearAriaLabel' => __('Year', 'fluentform'),
1284 + 'firstDayOfWeek' => (int) get_option('start_of_week'),
1285 + ];
952 1286
953 1287 return apply_filters('fluentform/date_i18n', $i18n);
954 1288 }
955 1289
@@ -962,13 +1296,276 @@
962 1296 'form_step',
963 1297 'input_file',
964 1298 'input_image',
965 1299 'net_promoter_score',
966 - 'featured_image'
1300 + 'featured_image',
967 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 + }
968 1309
969 - if ($formBuilder->conditions || array_intersect($formBuilder->fieldLists, $advancedFields)) {
970 - 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;
971 1321 }
1322 + return Helper::getNumericValue($value, $formatter);
972 1323 }
973 1324
974 -}
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 +}