Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/fluentform/app/Services/Form/Updater.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 +
3 + namespace FluentForm\App\Services\Form;
4 +
5 + use Exception;
6 + use FluentForm\App\Models\Form;
7 + use FluentForm\App\Helpers\Helper;
8 + use FluentForm\App\Models\FormMeta;
9 + use FluentForm\Framework\Support\Arr;
10 + use FluentForm\App\Modules\Form\FormFieldsParser;
11 +
12 + class Updater
13 + {
14 + public function update($attributes = [])
15 + {
16 + $formId = (int)Arr::get($attributes, 'form_id');
17 + $formFields = Arr::get($attributes, 'formFields');
18 + $status = sanitize_text_field(Arr::get($attributes, 'status', 'published'));
19 + $title = sanitize_text_field(Arr::get($attributes, 'title'));
20 +
21 + $this->validate([
22 + 'title' => $title,
23 + 'formFields' => $formFields,
24 + ]);
25 +
26 + try {
27 + $form = Form::findOrFail($formId);
28 + } catch (Exception $e) {
29 + throw new \Exception("The form couldn't be found.");
30 + }
31 +
32 + $data = [
33 + 'title' => $title,
34 + 'status' => $status,
35 + 'updated_at' => current_time('mysql'),
36 + ];
37 +
38 + if ($formFields) {
39 + $formFields = apply_filters_deprecated(
40 + 'fluentform_form_fields_update',
41 + [
42 + $formFields,
43 + $formId
44 + ],
45 + FLUENTFORM_FRAMEWORK_UPGRADE,
46 + 'fluentform/form_fields_update',
47 + 'Use fluentform/form_fields_update instead of fluentform_form_fields_update.'
48 + );
49 + $formFields = apply_filters('fluentform/form_fields_update', $formFields, $formId);
50 + $formFields = $this->sanitizeFields($formFields);
51 + $data['form_fields'] = $formFields;
52 + /**
53 + * Fires before a Form is updated.
54 + * @since 5.2.1
55 + */
56 + do_action('fluentform/before_updating_form', $form, $data);
57 +
58 + $form->fill($data);
59 +
60 + if (FormFieldsParser::hasPaymentFields($form)) {
61 + $data['has_payment'] = 1;
62 + } elseif ($form->has_payment) {
63 + $data['has_payment'] = 0;
64 + }
65 +
66 + $this->updatePrimaryEmail($form);
67 +
68 + }
69 +
70 + $form->fill($data)->save();
71 +
72 + return $form;
73 + }
74 +
75 + private function validate($attributes)
76 + {
77 + if ($attributes['formFields']) {
78 + $duplicates = Helper::getDuplicateFieldNames($attributes['formFields']);
79 +
80 + if ($duplicates) {
81 + $duplicateString = implode(', ', $duplicates);
82 +
83 + throw new Exception(
84 + sprintf('Name attribute %s has duplicate value.', esc_html($duplicateString))
85 + );
86 + }
87 + }
88 +
89 + if (!$attributes['title']) {
90 + throw new Exception('The title field is required.');
91 + }
92 + }
93 +
94 + private function sanitizeFields($formFields)
95 + {
96 + if (fluentformCanUnfilteredHTML()) {
97 + return $formFields;
98 + }
99 +
100 + $fieldsArray = json_decode($formFields, true);
101 +
102 + if (isset($fieldsArray['submitButton'])) {
103 + $fieldsArray['submitButton']['settings']['button_ui']['text'] = fluentform_sanitize_html(
104 + $fieldsArray['submitButton']['settings']['button_ui']['text']
105 + );
106 +
107 + if (!empty($fieldsArray['submitButton']['settings']['button_ui']['img_url'])) {
108 + $fieldsArray['submitButton']['settings']['button_ui']['img_url'] = sanitize_url(
109 + $fieldsArray['submitButton']['settings']['button_ui']['img_url']
110 + );
111 + }
112 + }
113 + $fieldsArray['fields'] = $this->sanitizeFieldMaps($fieldsArray['fields']);
114 + $fieldsArray['fields'] = $this->sanitizeCustomSubmit($fieldsArray['fields']);
115 + if ($stepsWrapper = Arr::get($fieldsArray, 'stepsWrapper')) {
116 + $fieldsArray['stepsWrapper'] = $this->sanitizeStepsWrapper($stepsWrapper);
117 + }
118 +
119 + return json_encode($fieldsArray);
120 + }
121 +
122 + private function sanitizeFieldMaps($fields)
123 + {
124 + if (!is_array($fields)) {
125 + return $fields;
126 + }
127 +
128 + $attributesMap = [
129 + 'name' => 'sanitize_key',
130 + 'value' => 'sanitize_textarea_field',
131 + 'id' => 'sanitize_key',
132 + 'class' => 'sanitize_text_field',
133 + 'placeholder' => 'sanitize_text_field',
134 + ];
135 +
136 + $attributesKeys = array_keys($attributesMap);
137 +
138 + $settingsMap = [
139 + 'container_class' => 'sanitize_text_field',
140 + 'label' => 'fluentform_sanitize_html',
141 + 'tnc_html' => 'fluentform_sanitize_html',
142 + 'label_placement' => 'sanitize_text_field',
143 + 'help_message' => 'wp_kses_post',
144 + 'admin_field_label' => 'sanitize_text_field',
145 + 'prefix_label' => 'sanitize_text_field',
146 + 'suffix_label' => 'sanitize_text_field',
147 + 'unique_validation_message' => 'sanitize_text_field',
148 + 'advanced_options' => 'fluentform_options_sanitize',
149 + 'html_codes' => 'fluentform_sanitize_html',
150 + 'description' => 'fluentform_sanitize_html',
151 + 'grid_columns' => [Helper::class, 'sanitizeArrayKeysAndValues'],
152 + 'grid_rows' => [Helper::class, 'sanitizeArrayKeysAndValues'],
153 + ];
154 +
155 +
156 + $settingsKeys = array_keys($settingsMap);
157 +
158 + $stylePrefMap = [
159 + 'layout' => 'sanitize_key',
160 + 'media' => 'sanitize_url',
161 + 'alt_text' => 'sanitize_text_field',
162 + ];
163 + $stylePrefKeys = array_keys($stylePrefMap);
164 +
165 + foreach ($fields as $fieldIndex => &$field) {
166 + $element = Arr::get($field, 'element');
167 +
168 + if ('container' == $element) {
169 + $columns = $field['columns'];
170 + foreach ($columns as $columnIndex => $column) {
171 + $fields[$fieldIndex]['columns'][$columnIndex]['fields'] = $this->sanitizeFieldMaps($column['fields']);
172 + }
173 + continue;
174 + }
175 +
176 + if ('welcome_screen' == $element) {
177 + if ($value = Arr::get($field, 'settings.button_ui.text')) {
178 + $field['settings']['button_ui']['text'] = sanitize_text_field($value);
179 + }
180 + }
181 +
182 +
183 + if (!empty($field['attributes'])) {
184 + $attributes = array_filter(Arr::only($field['attributes'], $attributesKeys));
185 +
186 + foreach ($attributes as $key => $value) {
187 + $fields[$fieldIndex]['attributes'][$key] = call_user_func($attributesMap[$key], $value);
188 + }
189 + }
190 +
191 + if (!empty($field['settings'])) {
192 + $settings = array_filter(Arr::only($field['settings'], array_values($settingsKeys)));
193 + foreach ($settings as $key => $value) {
194 + $fields[$fieldIndex]['settings'][$key] = call_user_func($settingsMap[$key], $value);
195 + }
196 + }
197 + /*
198 + * Handle Name or address fields
199 + */
200 + if (!empty($field['fields'])) {
201 + $fields[$fieldIndex]['fields'] = $this->sanitizeFieldMaps($field['fields']);
202 + continue;
203 + }
204 +
205 + if (!empty($field['style_pref'])) {
206 + $settings = array_filter(Arr::only($field['style_pref'], $stylePrefKeys));
207 +
208 + foreach ($settings as $key => $value) {
209 + $fields[$fieldIndex]['style_pref'][$key] = call_user_func($stylePrefMap[$key], $value);
210 + }
211 + }
212 +
213 + $validationRules = Arr::get($field, 'settings.validation_rules');
214 + if (!empty($validationRules)) {
215 + foreach ($validationRules as $key => $rule) {
216 + if (isset($rule['message'])) {
217 + $message = $rule['message'];
218 + $field['settings']['validation_rules'][$key]['message'] = wp_kses_post($message);
219 + continue;
220 + }
221 + }
222 + }
223 + }
224 +
225 + return $fields;
226 + }
227 +
228 + private function updatePrimaryEmail($form)
229 + {
230 + $emailInputs = FormFieldsParser::getElement($form, ['input_email'], ['element', 'attributes']);
231 +
232 + if ($emailInputs) {
233 + $emailInput = array_shift($emailInputs);
234 + $emailInputName = Arr::get($emailInput, 'attributes.name');
235 + } else {
236 + $emailInputName = '';
237 + }
238 +
239 + FormMeta::persist($form->id, '_primary_email_field', $emailInputName);
240 + }
241 +
242 + private function sanitizeCustomSubmit($fields)
243 + {
244 + $customSubmitSanitizationMap = [
245 + 'hover_styles' => [
246 + 'backgroundColor' => [$this, 'sanitizeRgbColor'],
247 + 'borderColor' => [$this, 'sanitizeRgbColor'],
248 + 'color' => [$this, 'sanitizeRgbColor'],
249 + 'borderRadius' => 'sanitize_text_field',
250 + 'minWidth' => [$this, 'sanitizeMinWidth']
251 + ],
252 + 'normal_styles' => [
253 + 'backgroundColor' => [$this, 'sanitizeRgbColor'],
254 + 'borderColor' => [$this, 'sanitizeRgbColor'],
255 + 'color' => [$this, 'sanitizeRgbColor'],
256 + 'borderRadius' => 'sanitize_text_field',
257 + 'minWidth' => [$this, 'sanitizeMinWidth']
258 + ],
259 + 'button_ui' => [
260 + 'type' => 'sanitize_text_field',
261 + 'text' => 'sanitize_text_field',
262 + 'img_url' => 'esc_url_raw',
263 + ],
264 + ];
265 + foreach ($fields as $fieldIndex => $field) {
266 + $element = Arr::get($field, 'element');
267 +
268 + if ('custom_submit_button' == $element) {
269 + $styleAttr = ['hover_styles', 'normal_styles', 'button_ui'];
270 + foreach ($styleAttr as $attr) {
271 + if ($styleConfigs = Arr::get($field, 'settings.' . $attr)) {
272 + foreach ($styleConfigs as $key => $value) {
273 + if (isset($customSubmitSanitizationMap[$attr][$key])) {
274 + $sanitizeFunction = $customSubmitSanitizationMap[$attr][$key];
275 + $fields[$fieldIndex]['settings'][$attr][$key] = $sanitizeFunction($value);
276 + }
277 + }
278 + }
279 + }
280 + }
281 + elseif ('container' == $element) {
282 + $columns = $field['columns'];
283 + foreach ($columns as $columnIndex => $column) {
284 + $fields[$fieldIndex]['columns'][$columnIndex]['fields'] = $this->sanitizeCustomSubmit($column['fields']);
285 + }
286 + return $fields;
287 + }
288 + }
289 + return $fields;
290 + }
291 +
292 + private function sanitizeStepsWrapper($stepWrapper)
293 + {
294 + $stepsSanitizationMap = [
295 + 'prev_btn' => [
296 + 'type' => 'sanitize_text_field',
297 + 'text' => 'sanitize_text_field',
298 + 'img_url' => 'esc_url_raw',
299 + ],
300 + ];
301 +
302 + foreach ($stepWrapper as $fieldIndex => $field) {
303 + $element = Arr::get($field, 'element');
304 +
305 + if ($element === 'step_start' || $element === 'step_end') {
306 + if (!empty($field['settings']['step_titles']) && is_array($field['settings']['step_titles'])) {
307 + foreach ($field['settings']['step_titles'] as $index => $title) {
308 + $field['settings']['step_titles'][$index] = fluentform_sanitize_html($title);
309 + }
310 + }
311 +
312 + if (!empty($field['settings']['prev_btn']) && is_array($field['settings']['prev_btn'])) {
313 + foreach ($field['settings']['prev_btn'] as $key => $value) {
314 + if (isset($stepsSanitizationMap['prev_btn'][$key])) {
315 + $sanitizeFunction = $stepsSanitizationMap['prev_btn'][$key];
316 + $field['settings']['prev_btn'][$key] = $sanitizeFunction($value);
317 + }
318 + }
319 + }
320 +
321 + if (!empty($field['attributes']['class'])) {
322 + $field['attributes']['class'] = sanitize_text_field($field['attributes']['class']);
323 + }
324 + if (!empty($field['attributes']['id'])) {
325 + $field['attributes']['id'] = sanitize_text_field($field['attributes']['id']);
326 + }
327 + }
328 +
329 + if ($element === 'step_start' && isset($field['fields'])) {
330 + $field['fields'] = $this->sanitizeStepsWrapper($field['fields']);
331 + }
332 +
333 + $stepWrapper[$fieldIndex] = $field;
334 + }
335 +
336 + return $stepWrapper;
337 + }
338 +
339 + public function sanitizeMinWidth($value)
340 + {
341 + if (is_string($value) && preg_match('/^\d+%$/', $value)) {
342 + return $value;
343 + }
344 + return '';
345 + }
346 +
347 + public function sanitizeRgbColor($value) {
348 + if (preg_match('/^rgba?\((\d{1,3}\s*,\s*){2,3}(0|1|0?\.\d+)\)$/', $value)) {
349 + return $value;
350 + }
351 + return '';
352 + }
353 + }
354 +