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