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
fluentform / app / Services / FormBuilder / Components / DateTime.php

DateTime.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.14, at app/Services/FormBuilder/Components/DateTime.php

221 lines 8.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\Services\FormBuilder\Components;
4
5 defined('ABSPATH') || die;
6
7 use FluentForm\App\Helpers\Helper;
8 use FluentForm\Framework\Helpers\ArrayHelper;
9
10 class DateTime extends BaseComponent
11 {
12 /**
13 * Compile and echo the html element
14 *
15 * @param array $data [element data]
16 * @param \stdClass $form [Form Object]
17 *
18 * @return void
19 */
20 public function compile($data, $form)
21 {
22 $elementName = $data['element'];
23 $data = apply_filters_deprecated(
24 'fluentform_rendering_field_data_' . $elementName,
25 [
26 $data,
27 $form,
28 ],
29 FLUENTFORM_FRAMEWORK_UPGRADE,
30 'fluentform/rendering_field_data_' . $elementName,
31 'Use fluentform/rendering_field_data_' . $elementName . ' instead of fluentform_rendering_field_data_' . $elementName
32 );
33 $data = apply_filters('fluentform/rendering_field_data_' . $elementName, $data, $form);
34
35 wp_enqueue_script('flatpickr');
36 wp_enqueue_style('flatpickr');
37
38 $data['attributes']['class'] = trim(
39 'ff-el-form-control ff-el-datepicker ' . $data['attributes']['class']
40 );
41 $dateFormat = $data['settings']['date_format'];
42
43 $data['attributes']['id'] = $this->makeElementId($data, $form);
44
45 if ($tabIndex = Helper::getNextTabIndex()) {
46 $data['attributes']['tabindex'] = $tabIndex;
47 }
48
49 $atts = $this->buildAttributes($data['attributes']);
50
51 $ariaRequired = 'false';
52 if (ArrayHelper::get($data, 'settings.validation_rules.required.value')) {
53 $ariaRequired = 'true';
54 }
55 $id = $data['attributes']['id'];
56
57 $ariaLabel = esc_html__(' Use arrow keys to navigate dates. Press enter to select a date.', 'fluentform');
58 $label = ArrayHelper::get($data, 'settings.label');
59 // SECURITY (FINDING-12): esc_attr the settings.label before interpolating it into the
60 // single-quoted aria-label; the save-time wp_kses does not encode quotes, so an unescaped
61 // label allows an attribute breakout (stored XSS).
62 $elMarkup = "<input aria-label='" . esc_attr($label) . $ariaLabel . "' aria-haspopup='dialog' data-type-datepicker data-format='" . esc_attr($dateFormat) . "' " . $atts . " aria-invalid='false' aria-required={$ariaRequired}>"; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $atts is escaped before being passed in.
63 $config = $this->getDateFormatConfigJSON($data['settings'], $form);
64 $customConfig = $this->getCustomConfig($data['settings'], $form);
65 $this->loadToFooter($config, $customConfig, $form, $id);
66 $html = $this->buildElementMarkup($elMarkup, $data, $form);
67
68 $html = apply_filters_deprecated(
69 'fluentform_rendering_field_html_' . $elementName,
70 [
71 $html,
72 $data,
73 $form,
74 ],
75 FLUENTFORM_FRAMEWORK_UPGRADE,
76 'fluentform/rendering_field_html_' . $elementName,
77 'Use fluentform/rendering_field_html_' . $elementName . ' instead of fluentform_rendering_field_html_' . $elementName
78 );
79
80 $this->printContent('fluentform/rendering_field_html_' . $elementName, $html, $data, $form);
81 }
82
83 public function getAvailableDateFormats()
84 {
85 $dateFormats = apply_filters('fluentform/available_date_formats', [
86 'm/d/Y' => 'm/d/Y - (Ex: 04/28/2018)', // USA
87 'd/m/Y' => 'd/m/Y - (Ex: 28/04/2018)', // Canada, UK
88 'd.m.Y' => 'd.m.Y - (Ex: 28.04.2019)', // Germany
89 'n/j/y' => 'n/j/y - (Ex: 4/28/18)',
90 'm/d/y' => 'm/d/y - (Ex: 04/28/18)',
91 'M/d/Y' => 'M/d/Y - (Ex: Apr/28/2018)',
92 'y/m/d' => 'y/m/d - (Ex: 18/04/28)',
93 'Y-m-d' => 'Y-m-d - (Ex: 2018-04-28)',
94 'd-M-y' => 'd-M-y - (Ex: 28-Apr-18)',
95 'm/d/Y h:i K' => 'm/d/Y h:i K - (Ex: 04/28/2018 08:55 PM)', // USA
96 'm/d/Y H:i' => 'm/d/Y H:i - (Ex: 04/28/2018 20:55)', // USA
97 'd/m/Y h:i K' => 'd/m/Y h:i K - (Ex: 28/04/2018 08:55 PM)', // Canada, UK
98 'd/m/Y H:i' => 'd/m/Y H:i - (Ex: 28/04/2018 20:55)', // Canada, UK
99 'd.m.Y h:i K' => 'd.m.Y h:i K - (Ex: 28.04.2019 08:55 PM)', // Germany
100 'd.m.Y H:i' => 'd.m.Y H:i - (Ex: 28.04.2019 20:55)', // Germany
101 'h:i K' => 'h:i K (Only Time Ex: 08:55 PM)',
102 'H:i' => 'H:i (Only Time Ex: 20:55)',
103 ]);
104
105 $formatted = [];
106 foreach ($dateFormats as $format => $label) {
107 $formatted[] = [
108 'label' => $label,
109 'value' => $format,
110 ];
111 }
112 return $formatted;
113 }
114
115 public function getDateFormatConfigJSON($settings, $form)
116 {
117 $dateFormat = ArrayHelper::get($settings, 'date_format');
118
119 if (! $dateFormat) {
120 $dateFormat = 'm/d/Y';
121 }
122
123 $hasTime = $this->hasTime($dateFormat);
124 $time24 = false;
125
126 if ($hasTime && false !== strpos($dateFormat, 'H')) {
127 $time24 = true;
128 }
129
130 $config = apply_filters('fluentform/frontend_date_format', [
131 'dateFormat' => $dateFormat,
132 'ariaDateFormat' =>'F j, Y',
133 'enableTime' => $hasTime,
134 'noCalendar' => ! $this->hasDate($dateFormat),
135 'disableMobile' => true,
136 'time_24hr' => $time24,
137 ], $settings, $form);
138
139 return json_encode($config, JSON_FORCE_OBJECT);
140 }
141
142 public function getCustomConfig($settings, $form = null)
143 {
144 $customConfigObject = trim((string) ArrayHelper::get($settings, 'date_config'));
145
146 if (
147 !$customConfigObject ||
148 '{' !== substr($customConfigObject, 0, 1) ||
149 '}' !== substr($customConfigObject, -1)
150 ) {
151 $customConfigObject = '{}';
152 } else {
153 $customConfigObject = str_ireplace('</script', '<\\/script', $customConfigObject);
154 }
155
156 return apply_filters('fluentform/date_time_custom_config', $customConfigObject, $settings, $form);
157 }
158
159 private function loadToFooter($config, $customConfigObject, $form, $id)
160 {
161 add_action('wp_footer', function () use ($config, $customConfigObject, $id, $form) {
162 ?>
163 <script type="text/javascript">
164 jQuery(document).ready(function($) {
165 function initPicker() {
166 if (typeof flatpickr == 'undefined') {
167 return;
168 }
169 flatpickr.localize(window.fluentFormVars.date_i18n);
170 var config = <?php echo fluentform_kses_js($config); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $config is escaped using fluentform_kses_js ?> ;
171 try {
172 var customConfig = <?php echo fluentform_kses_js($customConfigObject); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $config is escaped using fluentform_kses_js ?>;
173 } catch (e) {
174 var customConfig = {};
175 }
176
177 var config = $.extend({}, config, customConfig);
178 if (!config.locale) {
179 config.locale = 'default';
180 }
181 if (jQuery('#<?php echo esc_attr($id); ?>').length) {
182 flatpickr('#<?php echo esc_attr($id); ?>', config);
183 }
184 }
185 initPicker();
186 $(document).on(
187 'reInitExtras',
188 '.<?php echo esc_attr($form->instance_css_class); ?>',
189 function() {
190 initPicker();
191 }
192 );
193 });
194 </script>
195 <?php
196 }, 99999);
197 }
198
199 private function hasTime($string)
200 {
201 $timeStrings = ['H', 'h', 'G', 'i', 'S', 's', 'K'];
202 foreach ($timeStrings as $timeString) {
203 if (false != strpos($string, $timeString)) {
204 return true;
205 }
206 }
207 return false;
208 }
209
210 private function hasDate($string)
211 {
212 $dateStrings = ['d', 'D', 'l', 'j', 'J', 'w', 'W', 'F', 'm', 'n', 'M', 'U', 'Y', 'y', 'Z'];
213 foreach ($dateStrings as $dateString) {
214 if (false != strpos($string, $dateString)) {
215 return 'true';
216 }
217 }
218 return false;
219 }
220 }
221