PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 3.6.65
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v3.6.65
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
fluentform / app / Modules / Component / Component.php

Component.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 3.6.65, at app/Modules/Component/Component.php

991 lines 32.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\App\Modules\Component;
4
5 use FluentForm\App\Helpers\Helper;
6 use FluentForm\App\Modules\Acl\Acl;
7 use FluentForm\App\Services\FormBuilder\EditorShortcodeParser;
8 use FluentForm\App\Services\FormBuilder\Notifications\EmailNotificationActions;
9 use FluentForm\Framework\Foundation\Application;
10 use FluentForm\Framework\Helpers\ArrayHelper;
11
12 class Component
13 {
14 /**
15 * FluentForm\Framework\Foundation\Application
16 *
17 * @var $app
18 */
19 protected $app = null;
20
21 /**
22 * Biuld the instance of this class
23 *
24 * @param \FluentForm\Framework\Foundation\Application $app
25 */
26 public function __construct(Application $app)
27 {
28 $this->app = $app;
29 }
30
31 public function registerScripts()
32 {
33 $app = $this->app;
34
35 // We will just register the scripts here. We will not load any scripts from here
36
37 $fluentFormPublicCss = $app->publicUrl('css/fluent-forms-public.css');
38 $fluentFormPublicDefaultCss = $app->publicUrl('css/fluentform-public-default.css');
39
40 if (is_rtl()) {
41 $fluentFormPublicCss = $app->publicUrl('css/fluent-forms-public-rtl.css');
42 $fluentFormPublicDefaultCss = $app->publicUrl('css/fluentform-public-default-rtl.css');
43 }
44
45 wp_register_style(
46 'fluent-form-styles',
47 $fluentFormPublicCss,
48 array(),
49 FLUENTFORM_VERSION
50 );
51
52 wp_register_style(
53 'fluentform-public-default',
54 $fluentFormPublicDefaultCss,
55 array(),
56 FLUENTFORM_VERSION
57 );
58
59 wp_register_script(
60 'fluent-form-submission',
61 $app->publicUrl('js/form-submission.js'),
62 array('jquery'),
63 FLUENTFORM_VERSION,
64 true
65 );
66
67 wp_register_script(
68 'fluentform-advanced',
69 $app->publicUrl('js/fluentform-advanced.js'),
70 array('jquery'),
71 FLUENTFORM_VERSION,
72 true
73 );
74
75 // Date Pickckr Style
76 //fix for essential addon event picker conflict
77 if (!wp_script_is( 'flatpickr', 'registered' )) {
78 wp_register_style(
79 'flatpickr',
80 $app->publicUrl('libs/flatpickr/flatpickr.min.css')
81 );
82 }
83 // Date Pickckr Script
84 wp_register_script(
85 'flatpickr',
86 $app->publicUrl('libs/flatpickr/flatpickr.js'),
87 array('jquery'),
88 false,
89 true
90 );
91
92 wp_register_script(
93 'choices',
94 $app->publicUrl('libs/choices/choices.min.js'),
95 array(),
96 '9.0.1',
97 true
98 );
99
100 wp_register_style(
101 'ff_choices',
102 $app->publicUrl('css/choices.css'),
103 [],
104 FLUENTFORM_VERSION
105 );
106
107 do_action('fluentform_scripts_registered');
108
109 $this->maybeLoadFluentFormStyles();
110 }
111
112 protected function maybeLoadFluentFormStyles()
113 {
114 global $post;
115
116 if (!$post) {
117 return;
118 }
119
120 $fluentFormIds = get_post_meta($post->ID, '_has_fluentform', true);
121 $hasFluentformMeta = is_a($post, 'WP_Post') && $fluentFormIds;
122
123 if ($hasFluentformMeta || apply_filters('fluentform_load_styles', false, $post)) {
124 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');
128 }
129 }
130
131 /**
132 * Get all the available components
133 *
134 * @return void
135 * @throws \Exception
136 * @throws \FluentForm\Framework\Exception\UnResolveableEntityException
137 */
138 public function index()
139 {
140 $this->app->doAction(
141 'fluent_editor_init',
142 $components = $this->app->make('components')
143 );
144
145 $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
149 wp_send_json_success(array(
150 'countries' => $countries,
151 'components' => $editorComponents,
152 'disabled_components' => $this->getDisabledComponents()
153 ));
154 }
155
156
157 /**
158 * Get disabled components
159 *
160 * @return array
161 */
162 private function getDisabledComponents()
163 {
164 $isReCaptchaDisabled = !get_option('_fluentform_reCaptcha_keys_status', false);
165
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 );
187
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 );
198
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);
239 }
240
241 /**
242 * Get available shortcodes for editor
243 *
244 * @return void
245 * @throws \Exception
246 */
247 public function getEditorShortcodes()
248 {
249 $editor_shortcodes = fluentFormEditorShortCodes();
250 wp_send_json_success(['shortcodes' => $editor_shortcodes], 200);
251 }
252
253 /**
254 * Get all available shortcodes for editor
255 *
256 * @return void
257 * @throws \Exception
258 */
259 public function getAllEditorShortcodes()
260 {
261 wp_send_json(fluentFormGetAllEditorShortCodes(
262 $this->app->request->get('formId')
263 ), 200);
264 }
265
266 /**
267 * Register the form renderer shortcode
268 *
269 * @return void
270 */
271 public function addFluentFormShortCode()
272 {
273
274 add_action('wp_enqueue_scripts', array($this, 'registerScripts'), 999);
275
276 $this->app->addShortCode('fluentform', function ($atts, $content) {
277 $shortcodeDefaults = apply_filters('fluentform_shortcode_defaults', array(
278 'id' => null,
279 'title' => null,
280 'permission' => '',
281 'permission_message' => __('Sorry, You do not have permission to view this form', 'fluentform')
282 ), $atts);
283
284 $atts = shortcode_atts($shortcodeDefaults, $atts);
285 return $this->renderForm($atts);
286 });
287
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 $atts = shortcode_atts($shortcodeDefaults, $atts);
302 $formId = $atts['id'];
303 $form = wpFluent()->table('fluentform_forms')->find($formId);
304
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 '';
408 });
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
424 }
425
426 public function renderForm($atts)
427 {
428 $form_id = $atts['id'];
429
430 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();
434 } else {
435 return;
436 }
437
438 if (!$form) {
439 return;
440 }
441
442 if (!empty($atts['permission'])) {
443 if (!current_user_can($atts['permission'])) {
444 return "<div id='ff_form_{$form->id}' class='ff_form_not_render'>{$atts['permission_message']}</div>";
445 }
446 }
447
448 if(is_feed()) {
449 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);
452 return $feedText;
453 }
454
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;
463 }
464
465 $form->fields = json_decode($form->form_fields, true);
466
467 if (!$form->fields['fields']) {
468 return;
469 }
470
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' => ''
477 );
478
479 $isRenderable = $this->app->applyFilters('fluentform_is_form_renderable', $isRenderable, $form);
480
481 if (is_array($isRenderable) && !$isRenderable['status']) {
482 return "<div id='ff_form_{$form->id}' class='ff_form_not_render'>{$isRenderable['message']}</div>";
483 }
484
485 $instanceCssClass = Helper::getFormInstaceClass($form->id);
486
487 $form->instance_css_class = $instanceCssClass;
488 $form->instance_index = Helper::$formInstance;
489
490 $formBuilder = $this->app->make('formBuilder');
491 $output = $formBuilder->build($form, $instanceCssClass . ' ff-form-loading', $instanceCssClass);
492 $output = $this->replaceEditorSmartCodes($output, $form);
493
494 if (!wp_script_is('fluent-form-submission', 'registered')) {
495 $this->registerScripts();
496 }
497
498 wp_enqueue_style('fluent-form-styles');
499 if (apply_filters('fluentform_load_default_public', true, $form)) {
500 wp_enqueue_style('fluentform-public-default');
501 }
502 /*
503 * We will load fluentform-advanced if the form has certain fields or feature
504 */
505 $this->maybeHasAdvandedFields($form, $formBuilder);
506 wp_enqueue_script('fluent-form-submission');
507
508 $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'),
527 'itemSelectText' => __('Press to select', 'fluentform'),
528 'maxItemTextLang' => 'Only %%maxItemCount%% values can be added'
529 ]
530 ));
531
532 wp_localize_script('fluent-form-submission', 'fluentFormVars', $vars);
533
534 $formSettings = $form->settings;
535
536 $formSettings = ArrayHelper::only($formSettings, ['layout', 'id']);
537
538 $formSettings['restrictions']['denyEmptySubmission'] = [
539 'enabled' => false
540 ];
541
542 $form_vars = array(
543 'id' => $form->id,
544 'settings' => $formSettings,
545 'form_instance' => $instanceCssClass,
546 'form_id_selector' => 'fluentform_' . $form->id,
547 'rules' => $formBuilder->validationRules
548 );
549
550 if ($conditionals = $formBuilder->conditions) {
551 $form_vars['conditionals'] = $conditionals;
552 }
553
554 if ($form->has_payment) {
555 do_action('fluentform_rending_payment_form', $form);
556 }
557
558 $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;
568 }
569 var ajax_formInstance = window.fluentFormApp(jQuery('form.<?php echo $form_vars['form_instance']; ?>'));
570 if (ajax_formInstance) {
571 ajax_formInstance.initFormHandlers();
572 }
573 }
574
575 initFFInstance_<?php echo $form_vars['id']; ?>();
576 <?php endif; ?>
577 </script>
578 <?php
579 $this->addInlineVars();
580 $otherScripts .= ob_get_clean();
581
582 if (!apply_filters('fluentform-disabled_analytics', false)) {
583 if (!Acl::hasAnyFormPermission($form->id)) {
584 (new \FluentForm\App\Modules\Form\Analytics($this->app))->record($form->id);
585 }
586 }
587 return $output . $otherScripts;
588 }
589
590 /**
591 * Process the output HTML to generate the default values.
592 *
593 * @param string $output
594 * @param \stdClass $form
595 * @return string
596 */
597 public function replaceEditorSmartCodes($output, $form)
598 {
599 // Get the patterns for default values from the output HTML string.
600 // The example of a pattern would be for user ID: {user.ID}
601 preg_match_all('/{(.*?)}/', $output, $matches);
602 $patterns = array_unique($matches[0]);
603
604
605 $attrDefaultValues = [];
606
607 foreach ($patterns as $pattern) {
608 // The default value for each pattern will be resolved here.
609 $attrDefaultValues[$pattern] = apply_filters('fluentform_parse_default_value', $pattern, $form);
610 }
611
612 // 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);
614
615 if (isset($attrDefaultValues['{payment_total}'])) {
616 $attrDefaultValues['{payment_total}'] = '<span class="ff_order_total"></span>';
617 }
618
619 // Finally, replace the patterns with the replacements and return the output HTML.
620 return str_replace(array_keys($attrDefaultValues), array_values($attrDefaultValues), $output);
621 }
622
623 /**
624 * Register renderer actions for compiling each element
625 *
626 * @return void
627 */
628 public function addRendererActions()
629 {
630 $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'],
643
644 'TermsAndConditions@compile' => [
645 'fluentform_render_item_terms_and_condition',
646 'fluentform_render_item_gdpr_agreement'
647 ],
648
649 'TabularGrid@compile' => [
650 'fluentform_render_item_tabular_grid'
651 ],
652
653 'Checkable@compile' => [
654 'fluentform_render_item_input_radio',
655 'fluentform_render_item_input_checkbox',
656 ],
657
658 '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',
665 ],
666 ];
667
668 $path = 'FluentForm\App\Services\FormBuilder\Components\\';
669 foreach ($actionMappings as $handler => $actions) {
670 foreach ($actions as $action) {
671 $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());
674 }, 10, 2);
675 }
676 }
677 }
678
679 /**
680 * Register dynamic value shortcode parser (filter default value)
681 *
682 * @return void
683 */
684 public function addFluentFormDefaultValueParser()
685 {
686 $this->app->addFilter('fluentform_parse_default_value', function ($value, $form) {
687 return EditorShortcodeParser::filter($value, $form);
688 }, 10, 2);
689 }
690
691 /**
692 * Register filter to check whether the form is renderable
693 *
694 * @return mixed
695 */
696 public function addIsRenderableFilter()
697 {
698 $this->app->addFilter('fluentform_is_form_renderable', function ($isRenderable, $form) {
699 $checkables = array('limitNumberOfEntries', 'scheduleForm', 'requireLogin');
700
701 foreach ($form->settings['restrictions'] as $key => $restrictions) {
702 if (in_array($key, $checkables)) {
703 $isRenderable['status'] = $this->{$key}($restrictions, $form, $isRenderable);
704 if (!$isRenderable['status']) {
705 $isRenderable['status'] = false;
706 return $isRenderable;
707 }
708 }
709 }
710
711 return $isRenderable;
712 }, 10, 2);
713 }
714
715 /**
716 * Check if limit is set on form submits and it's valid yet
717 *
718 * @param array $restrictions
719 *
720 * @return bool
721 */
722 private function limitNumberOfEntries($restrictions, $form, &$isRenderable)
723 {
724 if (!$restrictions['enabled']) {
725 return true;
726 }
727
728 $col = 'created_at';
729 $period = $restrictions['period'];
730 $maxAllowedEntries = $restrictions['numberOfEntries'];
731
732 if (!$maxAllowedEntries) {
733 return true;
734 }
735
736 $query = wpFluent()->table('fluentform_submissions')
737 ->where('form_id', $form->id)
738 ->where('status', '!=', 'trashed');
739
740 if ($period == 'day') {
741 $year = "YEAR(`{$col}`) = YEAR(NOW())";
742 $month = "MONTH(`{$col}`) = MONTH(NOW())";
743 $day = "DAY(`{$col}`) = DAY(NOW())";
744 $query->where(wpFluent()->raw("{$year} AND {$month} AND {$day}"));
745 } elseif ($period == 'week') {
746 $query->where(
747 wpFluent()->raw("YEARWEEK(`{$col}`, 1) = YEARWEEK(CURDATE(), 1)")
748 );
749 } elseif ($period == 'month') {
750 $year = "YEAR(`{$col}`) = YEAR(NOW())";
751 $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') {
756 $ip = $this->app->request->getIp();
757 $query->where('ip', $ip);
758 } else if ($period == 'per_user_id') {
759 $userId = get_current_user_id();
760 if (!$userId) {
761 return true;
762 }
763 $query->where('user_id', $userId);
764 }
765
766 $count = $query->count();
767
768
769 if ($count >= $maxAllowedEntries) {
770 $isRenderable['message'] = $restrictions['limitReachedMsg'];
771 return false;
772 }
773
774 return true;
775 }
776
777 /**
778 * Check if form has scheduled date and open for submission
779 *
780 * @param array $restrictions
781 *
782 * @return bool
783 */
784 private function scheduleForm($restrictions, $form, &$isRenderable)
785 {
786 if (!$restrictions['enabled']) {
787 return true;
788 }
789
790 $time = time();
791 $start = strtotime($restrictions['start']);
792 $end = strtotime($restrictions['end']);
793
794 if ($time < $start) {
795 $isRenderable['message'] = $restrictions['pendingMsg'];
796
797 return false;
798 }
799
800 if ($time >= $end) {
801 $isRenderable['message'] = $restrictions['expiredMsg'];
802
803 return false;
804 }
805
806 return true;
807 }
808
809 /**
810 * * Check if form requires loged in user and user is logged in
811 *
812 * @param array $restrictions
813 *
814 * @return bool
815 */
816 private function requireLogin($restrictions, $form, &$isRenderable)
817 {
818 if (!$restrictions['enabled']) {
819 return true;
820 }
821
822 if (!($isLoggedIn = is_user_logged_in())) {
823 $isRenderable['message'] = $restrictions['requireLoginMsg'];
824 }
825
826 return $isLoggedIn;
827 }
828
829 /**
830 * Register fluentform_submission_inserted actions
831 *
832 * @return void
833 */
834 public function addFluentformSubmissionInsertedFilter()
835 {
836 (new EmailNotificationActions($this->app))->register();
837 }
838
839 /**
840 * Add inline scripts [Add localized script using same var]
841 *
842 * @return void
843 */
844 private function addInlineVars()
845 {
846 if (!defined('ELEMENTOR_PRO_VERSION')) {
847 return '';
848 }
849
850 $actionName = 'wp_footer';
851 if (is_admin()) {
852 $actionName = 'admin_footer';
853 }
854
855 add_action($actionName, function () {
856 ?>
857 <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');
861 if (ffForms.length) {
862 jQuery.each(ffForms, function (index, ffForm) {
863 jQuery(ffForm).trigger('reInitExtras');
864 jQuery(document).trigger('ff_reinit', [ffForm]);
865 });
866 }
867 });
868 <?php endif; ?>
869 </script>
870 <?php
871 }, 999);
872 return '';
873 }
874
875 private function getDatei18n()
876 {
877 $i18n = array(
878 'previousMonth' => __('Previous Month', 'fluentform'),
879 'nextMonth' => __('Next Month', 'fluentform'),
880 'months' => [
881 'shorthand' => [
882 __('Jan', 'fluentform'),
883 __('Feb', 'fluentform'),
884 __('Mar', 'fluentform'),
885 __('Apr', 'fluentform'),
886 __('May', 'fluentform'),
887 __('Jun', 'fluentform'),
888 __('Jul', 'fluentform'),
889 __('Aug', 'fluentform'),
890 __('Sep', 'fluentform'),
891 __('Oct', 'fluentform'),
892 __('Nov', 'fluentform'),
893 __('Dec', 'fluentform')
894 ],
895 'longhand' => [
896 __('January', 'fluentform'),
897 __('February', 'fluentform'),
898 __('March', 'fluentform'),
899 __('April', 'fluentform'),
900 __('May', 'fluentform'),
901 __('June', 'fluentform'),
902 __('July', 'fluentform'),
903 __('August', 'fluentform'),
904 __('September', 'fluentform'),
905 __('October', 'fluentform'),
906 __('November', 'fluentform'),
907 __('December', 'fluentform')
908 ]
909 ],
910 'weekdays' => [
911 'longhand' => array(
912 __('Sunday', 'fluentform'),
913 __('Monday', 'fluentform'),
914 __('Tuesday', 'fluentform'),
915 __('Wednesday', 'fluentform'),
916 __('Thursday', 'fluentform'),
917 __('Friday', 'fluentform'),
918 __('Saturday', 'fluentform')
919 ),
920 'shorthand' => array(
921 __('Sun', 'fluentform'),
922 __('Mon', 'fluentform'),
923 __('Tue', 'fluentform'),
924 __('Wed', 'fluentform'),
925 __('Thu', 'fluentform'),
926 __('Fri', 'fluentform'),
927 __('Sat', 'fluentform')
928 )
929 ],
930 'daysInMonth' => [
931 31,
932 28,
933 31,
934 30,
935 31,
936 30,
937 31,
938 31,
939 30,
940 31,
941 30,
942 31
943 ],
944 'rangeSeparator' => __(' to ', 'fluentform'),
945 'weekAbbreviation' => __('Wk', 'fluentform'),
946 'scrollTitle' => __('Scroll to increment', 'fluentform'),
947 'toggleTitle' => __('Click to toggle', 'fluentform'),
948 'amPM' => [
949 __('AM', 'fluentform'),
950 __('PM', 'fluentform')
951 ],
952 'yearAriaLabel' => __('Year', 'fluentform')
953 );
954
955 return apply_filters('fluentform/date_i18n', $i18n);
956 }
957
958 protected function maybeHasAdvandedFields($form, $formBuilder)
959 {
960 $advancedFields = [
961 'step_start',
962 'repeater_field',
963 'ratings',
964 'form_step',
965 'input_file',
966 'input_image',
967 'net_promoter_score',
968 'featured_image'
969 ];
970
971 if ($formBuilder->conditions || array_intersect($formBuilder->fieldLists, $advancedFields)) {
972 wp_enqueue_script('fluentform-advanced');
973 }
974 }
975
976 public function registerInputSanitizers()
977 {
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);
980 }
981
982 public function getNumericInputValue($value, $field)
983 {
984 $formatter = ArrayHelper::get($field, 'raw.settings.numeric_formatter');
985 if(!$formatter) {
986 return $value;
987 }
988 return Helper::getNumericValue($value, $formatter);
989 }
990 }
991