Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/fluentform/app/Services/Parser/Extractor.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
1 + <?php
2 +
3 + namespace FluentForm\App\Services\Parser;
4 +
5 + use FluentForm\App\Helpers\Helper;
6 + use FluentForm\App\Services\ConditionAssesor;
7 + use FluentForm\Framework\Helpers\ArrayHelper as Arr;
8 +
9 + class Extractor
10 + {
11 + /**
12 + * The form field settings.
13 + *
14 + * @var array
15 + */
16 + protected $fields;
17 +
18 + /**
19 + * The properties that need to be extracted.
20 + *
21 + * @var array
22 + */
23 + protected $with;
24 +
25 + /**
26 + * The supported form input types defined for Fluent Forms.
27 + *
28 + * @var array
29 + */
30 + protected $inputTypes;
31 +
32 + /**
33 + * The extracted result.
34 + *
35 + * @var array
36 + */
37 + protected $result = [];
38 +
39 + /**
40 + * The current form field that's being set when we loop
41 + * through all the form fields in the looper method.
42 + *
43 + * @var array
44 + */
45 + protected $field = [];
46 +
47 + /**
48 + * The current field attribute that's being set when we loop
49 + * through all the form fields in the looper method.
50 + *
51 + * @var string
52 + */
53 + protected $attribute;
54 +
55 + /**
56 + * Extractor constructor.
57 + *
58 + * @param array $fields
59 + * @param array $with
60 + * @param array $inputTypes
61 + */
62 + public function __construct($fields, $with, $inputTypes)
63 + {
64 + $this->fields = $fields;
65 + $this->with = $with;
66 + $this->inputTypes = $inputTypes;
67 + }
68 +
69 + /**
70 + * The extractor initializer for getting the extracted data.
71 + *
72 + * @return array
73 + */
74 + public function extract()
75 + {
76 + $this->looper($this->fields);
77 +
78 + return $this->result;
79 + }
80 +
81 + /**
82 + * The recursive looper method to loop each
83 + * of the fields and extract it's data.
84 + *
85 + * @param array $fields
86 + */
87 + protected function looper($fields = [])
88 + {
89 + foreach ($fields as $field) {
90 + // If the field is a Container (collection of other fields)
91 + // then we will recursively call this function to resolve.
92 + if (Arr::get($field, 'element') === 'container') {
93 + $columns = Arr::get($field, 'columns', []);
94 + foreach ($columns as $item) {
95 + $itemFields = Arr::get($item, 'fields', []);
96 + $this->looper($itemFields);
97 + }
98 + }
99 +
100 + // Now the field is supposed to be a flat field.
101 + // We can extract the desired keys as we want.
102 + else {
103 + $element = Arr::get($field, 'element');
104 + if ($element && in_array($element, $this->inputTypes)) {
105 + $this->extractField($field);
106 + }
107 + }
108 + }
109 + }
110 +
111 + /**
112 + * The extractor initializer for getting the extracted data.
113 + *
114 + * @return array
115 + */
116 + public function extractEssentials($formData)
117 + {
118 + $this->looperEssential($formData, $this->fields);
119 +
120 + return $this->result;
121 + }
122 +
123 + /**
124 + * The recursive looper method to loop each
125 + * of the fields and extract it's data.
126 + *
127 + * @param array $fields
128 + */
129 + protected function looperEssential($formData, $fields = [])
130 + {
131 + foreach ($fields as $field) {
132 + $field['conditionals'] = Arr::get($field, 'settings.conditional_logics', []);
133 +
134 + $matched = ConditionAssesor::evaluate($field, $formData);
135 +
136 + if (!$matched) {
137 + continue;
138 + }
139 +
140 + // If the field is a Container (collection of other fields)
141 + // then we will recursively call this function to resolve.
142 + if (Arr::get($field, 'element') === 'container') {
143 + $columns = Arr::get($field, 'columns', []);
144 + foreach ($columns as $item) {
145 + $itemFields = Arr::get($item, 'fields', []);
146 + $this->looperEssential($formData, $itemFields);
147 + }
148 + }
149 +
150 + // Now the field is supposed to be a flat field.
151 + // We can extract the desired keys as we want.
152 + else {
153 + $element = Arr::get($field, 'element');
154 + if ($element && in_array($element, $this->inputTypes)) {
155 + $this->extractField($field);
156 + }
157 + }
158 + }
159 + }
160 +
161 + /**
162 + * Extract the form field.
163 + *
164 + * @param array $field
165 + * @return $this
166 + */
167 + protected function extractField($field)
168 + {
169 + // Before starting the extraction we'll set the current
170 + // field and it's attribute name at first. And then we
171 + // will proceed to extract the field settings that
172 + // the developer demanded using $with initially.
173 + $this->prepareIteration($field, Arr::get($field, 'attributes.name'))
174 + ->setElement()
175 + ->setAdminLabel()
176 + ->setLabel()
177 + ->setOptions()
178 + ->setAdvancedOptions()
179 + ->setSettings()
180 + ->setRaw()
181 + ->setAttributes()
182 + ->setValidations()
183 + ->handleCustomField();
184 +
185 + return $this;
186 + }
187 +
188 + /**
189 + * Set the field and attribute of the current iteration when
190 + * we loop through the form fields using the looper method.
191 + *
192 + * @param array $field
193 + * @param string $attribute
194 + * @return $this
195 + */
196 + protected function prepareIteration($field, $attribute)
197 + {
198 + $this->field = $field;
199 +
200 + $this->attribute = $attribute;
201 +
202 + return $this;
203 + }
204 +
205 + /**
206 + * Set the element of the form field.
207 + *
208 + * @param array $field
209 + * @param string $attributeName
210 + * @return $this
211 + */
212 + protected function setElement()
213 + {
214 + $this->result[$this->attribute]['element'] = Arr::get($this->field, 'element', '');
215 + return $this;
216 + }
217 +
218 +
219 + /**
220 + * Set the label of the form field.
221 + *
222 + * @return $this
223 + */
224 + protected function setLabel()
225 + {
226 + if (in_array('label', $this->with)) {
227 + $this->result[$this->attribute]['label'] = Arr::get($this->field, 'settings.label', '');
228 + }
229 +
230 + return $this;
231 + }
232 +
233 + /**
234 + * Set the admin label of the form field.
235 + *
236 + * @return $this
237 + */
238 + protected function setAdminLabel()
239 + {
240 + if (in_array('admin_label', $this->with)) {
241 + $adminLabel = Arr::get($this->field, 'settings.admin_field_label') ?:
242 + Arr::get($this->field, 'settings.label') ?:
243 + Arr::get($this->field, 'element');
244 +
245 + $this->result[$this->attribute]['admin_label'] = $adminLabel;
246 + }
247 +
248 +
249 + return $this;
250 + }
251 +
252 + /**
253 + * Set the options of the form field.
254 + *
255 + * @return $this
256 + */
257 + protected function setOptions()
258 + {
259 + if (in_array('options', $this->with)) {
260 + $options = Arr::get($this->field, 'options', []);
261 +
262 + if(!$options) {
263 + $newOptions = Arr::get($this->field, 'settings.advanced_options', []);
264 +
265 + if(
266 + !$newOptions
267 + && Arr::get($this->field,'element') == 'multi_payment_component'
268 + && Arr::get($this->field,'attributes.type') != 'single'
269 + ) {
270 + $pricingOptions = Arr::get($this->field, 'settings.pricing_options', []);
271 + foreach ($pricingOptions as $pricingOption) {
272 + $newOptions[] = [
273 + 'value' => $pricingOption['label'],
274 + 'label' => $pricingOption['label']
275 + ];
276 + }
277 + }
278 +
279 + $options = [];
280 + if($newOptions) {
281 + foreach ($newOptions as $option) {
282 + $value = sanitize_text_field($option['value']);
283 + $options[$value] = sanitize_text_field($option['label']);
284 + }
285 + }
286 + }
287 + $this->result[$this->attribute]['options'] = $options;
288 + }
289 + return $this;
290 + }
291 +
292 + /**
293 + * Set the advanced options of the form field.
294 + *
295 + * @return $this
296 + */
297 + protected function setAdvancedOptions()
298 + {
299 + if (in_array('advanced_options', $this->with)) {
300 + $this->result[$this->attribute]['advanced_options'] = Arr::get($this->field, 'settings.advanced_options', []);
301 + }
302 + return $this;
303 + }
304 +
305 + protected function setSettings()
306 + {
307 + if (in_array('settings', $this->with)) {
308 + $this->result[$this->attribute]['settings'] = Arr::get($this->field, 'settings', []);
309 + }
310 + return $this;
311 + }
312 +
313 + /**
314 + * Set the attributes of the form field.
315 + *
316 + * @return $this
317 + */
318 + protected function setAttributes()
319 + {
320 + if (in_array('attributes', $this->with)) {
321 + $this->result[$this->attribute]['attributes'] = Arr::get($this->field, 'attributes');
322 + }
323 +
324 +
325 + return $this;
326 + }
327 +
328 + /**
329 + * Set the validation rules and conditions of the form field.
330 + *
331 + * @return $this
332 + */
333 + protected function setValidations()
334 + {
335 + if (in_array('rules', $this->with)) {
336 + $this->result[$this->attribute]['rules'] = Arr::get(
337 + $this->field,
338 + 'settings.validation_rules'
339 + );
340 +
341 + $this->handleMaxLengthValidation();
342 +
343 + $this->result[$this->attribute]['conditionals'] = Arr::get(
344 + $this->field,
345 + 'settings.conditional_logics'
346 + );
347 + }
348 +
349 + return $this;
350 + }
351 +
352 + protected function handleMaxLengthValidation()
353 + {
354 + $maxLength = Arr::get($this->field, 'attributes.maxlength');
355 + $fieldHasMaxValidation = Arr::get($this->field, 'settings.validation_rules.max');
356 + $shouldSetMaxValidation = $maxLength && !$fieldHasMaxValidation;
357 +
358 + if ($shouldSetMaxValidation) {
359 + $this->result[$this->attribute]['rules']['max'] = [
360 + 'value' => $maxLength,
361 + "message" => Helper::getGlobalDefaultMessage('max'),
362 + ];
363 + }
364 +
365 + return $this;
366 + }
367 +
368 + /**
369 + * Handle the child fields of complex form fields (address, name, repeater).
370 + *
371 + * This method processes fields that have sub-fields (like address field having
372 + * address_line_1, city, state, etc.) and prepares them for shortcode generation.
373 + *
374 + * @return $this
375 + */
376 + protected function handleCustomField()
377 + {
378 + // If this field is a custom field we'll assume it has it's child fields
379 + // under the `fields` key. Then we are gonna modify those child fields'
380 + // attribute `name`, `label` & `conditional_logics` properties using
381 + // the parent field. The current implementation will modify those
382 + // properties in a way so that we can use dot notation to access.
383 + $customFields = Arr::get($this->field, 'fields');
384 +
385 + if ($customFields) {
386 + $parentAttribute = Arr::get($this->field, 'attributes.name');
387 +
388 + $parentConditionalLogics = Arr::get($this->field, 'settings.conditional_logics', []);
389 +
390 + $isAddressOrNameField = in_array(Arr::get($this->field, 'element'), ['address', 'input_name']);
391 +
392 + $isRepeatField = Arr::get($this->field, 'element') === 'input_repeat' || Arr::get($this->field, 'element') == 'repeater_field';
393 +
394 + // Allow plugins to modify custom fields before processing
395 + $customFields = apply_filters('fluentform/extractor_parser_custom_fields', $customFields, $this->field);
396 +
397 + foreach ($customFields as $index => $customField) {
398 + // If the current field is in fact `address` || `name` field
399 + // then we have to only keep the enabled child fields
400 + // by the user from the form editor settings.
401 + if ($isAddressOrNameField) {
402 + $subFieldName = Arr::get($customField, 'attributes.name');
403 + if (!Arr::get($customField, 'settings.visible', false) && !in_array($subFieldName, ['latitude', 'longitude'])) {
404 + unset($customFields[$index]);
405 + continue;
406 + }
407 + }
408 +
409 + // Depending on whether the parent field is a repeat field or not
410 + // the modified attribute name of the child field will vary.
411 + if ($isRepeatField) {
412 + $modifiedAttribute = $parentAttribute.'['.$index.'].*';
413 + } else {
414 + $modifiedAttribute = $parentAttribute.'['.Arr::get($customField, 'attributes.name').']';
415 + }
416 +
417 + $modifiedLabel = $parentAttribute.'['.Arr::get($customField, 'settings.label').']';
418 +
419 + $customField['attributes']['name'] = $modifiedAttribute;
420 +
421 + $customField['settings']['label'] = $modifiedLabel;
422 +
423 + // Now, we'll replace the `conditional_logics` property
424 + $customField['settings']['conditional_logics'] = $parentConditionalLogics;
425 +
426 + // Now that this field's properties are handled we can pass
427 + // it to the extract field method to extract it's data.
428 + $this->extractField($customField);
429 + }
430 + }
431 +
432 + return $this;
433 + }
434 +
435 + /**
436 + * Set the raw field of the form field.
437 + *
438 + * @return $this
439 + */
440 + protected function setRaw()
441 + {
442 + if (in_array('raw', $this->with)) {
443 + $this->result[$this->attribute]['raw'] = $this->field;
444 + }
445 +
446 + return $this;
447 + }
448 + }
449 +