PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.12
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.12
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 / Parser / Extractor.php

Extractor.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 6.2.12, at app/Services/Parser/Extractor.php

455 lines 13.0 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\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 = \FluentForm\App\Helpers\Helper::flattenAdvancedOptions(
264 Arr::get($this->field, 'settings.advanced_options', [])
265 );
266
267 if(
268 !$newOptions
269 && Arr::get($this->field,'element') == 'multi_payment_component'
270 && Arr::get($this->field,'attributes.type') != 'single'
271 ) {
272 $pricingOptions = Arr::get($this->field, 'settings.pricing_options', []);
273 foreach ($pricingOptions as $pricingOption) {
274 $newOptions[] = [
275 'value' => $pricingOption['label'],
276 'label' => $pricingOption['label']
277 ];
278 }
279 }
280
281 $options = [];
282 if($newOptions) {
283 foreach ($newOptions as $option) {
284 $value = sanitize_text_field($option['value']);
285 $options[$value] = sanitize_text_field($option['label']);
286 }
287 }
288 }
289 $this->result[$this->attribute]['options'] = $options;
290 }
291 return $this;
292 }
293
294 /**
295 * Set the advanced options of the form field.
296 *
297 * @return $this
298 */
299 protected function setAdvancedOptions()
300 {
301 if (in_array('advanced_options', $this->with)) {
302 $this->result[$this->attribute]['advanced_options'] = Arr::get($this->field, 'settings.advanced_options', []);
303 }
304 return $this;
305 }
306
307 protected function setSettings()
308 {
309 if (in_array('settings', $this->with)) {
310 $this->result[$this->attribute]['settings'] = Arr::get($this->field, 'settings', []);
311 }
312 return $this;
313 }
314
315 /**
316 * Set the attributes of the form field.
317 *
318 * @return $this
319 */
320 protected function setAttributes()
321 {
322 if (in_array('attributes', $this->with)) {
323 $this->result[$this->attribute]['attributes'] = Arr::get($this->field, 'attributes');
324 }
325
326
327 return $this;
328 }
329
330 /**
331 * Set the validation rules and conditions of the form field.
332 *
333 * @return $this
334 */
335 protected function setValidations()
336 {
337 if (in_array('rules', $this->with)) {
338 $this->result[$this->attribute]['rules'] = Arr::get(
339 $this->field,
340 'settings.validation_rules'
341 );
342
343 $this->handleMaxLengthValidation();
344
345 $this->result[$this->attribute]['conditionals'] = Arr::get(
346 $this->field,
347 'settings.conditional_logics'
348 );
349 }
350
351 return $this;
352 }
353
354 protected function handleMaxLengthValidation()
355 {
356 $maxLength = Arr::get($this->field, 'attributes.maxlength');
357 $fieldHasMaxValidation = Arr::get($this->field, 'settings.validation_rules.max');
358 $shouldSetMaxValidation = $maxLength && !$fieldHasMaxValidation;
359
360 if ($shouldSetMaxValidation) {
361 $message = Helper::getGlobalDefaultMessage('max');
362 if (!$message) {
363 $message = __('Validation fails for maximum value', 'fluentform');
364 }
365 $this->result[$this->attribute]['rules']['max'] = [
366 'value' => $maxLength,
367 'message' => $message,
368 ];
369 }
370
371 return $this;
372 }
373
374 /**
375 * Handle the child fields of complex form fields (address, name, repeater).
376 *
377 * This method processes fields that have sub-fields (like address field having
378 * address_line_1, city, state, etc.) and prepares them for shortcode generation.
379 *
380 * @return $this
381 */
382 protected function handleCustomField()
383 {
384 // If this field is a custom field we'll assume it has it's child fields
385 // under the `fields` key. Then we are gonna modify those child fields'
386 // attribute `name`, `label` & `conditional_logics` properties using
387 // the parent field. The current implementation will modify those
388 // properties in a way so that we can use dot notation to access.
389 $customFields = Arr::get($this->field, 'fields');
390
391 if ($customFields) {
392 $parentAttribute = Arr::get($this->field, 'attributes.name');
393
394 $parentConditionalLogics = Arr::get($this->field, 'settings.conditional_logics', []);
395
396 $isAddressOrNameField = in_array(Arr::get($this->field, 'element'), ['address', 'input_name']);
397
398 $isRepeatField = Arr::get($this->field, 'element') === 'input_repeat' || Arr::get($this->field, 'element') == 'repeater_field';
399
400 // Allow plugins to modify custom fields before processing
401 $customFields = apply_filters('fluentform/extractor_parser_custom_fields', $customFields, $this->field);
402
403 foreach ($customFields as $index => $customField) {
404 // If the current field is in fact `address` || `name` field
405 // then we have to only keep the enabled child fields
406 // by the user from the form editor settings.
407 if ($isAddressOrNameField) {
408 $subFieldName = Arr::get($customField, 'attributes.name');
409 if (!Arr::get($customField, 'settings.visible', false) && !in_array($subFieldName, ['latitude', 'longitude'])) {
410 unset($customFields[$index]);
411 continue;
412 }
413 }
414
415 // Depending on whether the parent field is a repeat field or not
416 // the modified attribute name of the child field will vary.
417 if ($isRepeatField) {
418 $modifiedAttribute = $parentAttribute.'['.$index.'].*';
419 } else {
420 $modifiedAttribute = $parentAttribute.'['.Arr::get($customField, 'attributes.name').']';
421 }
422
423 $modifiedLabel = $parentAttribute.'['.Arr::get($customField, 'settings.label').']';
424
425 $customField['attributes']['name'] = $modifiedAttribute;
426
427 $customField['settings']['label'] = $modifiedLabel;
428
429 // Now, we'll replace the `conditional_logics` property
430 $customField['settings']['conditional_logics'] = $parentConditionalLogics;
431
432 // Now that this field's properties are handled we can pass
433 // it to the extract field method to extract it's data.
434 $this->extractField($customField);
435 }
436 }
437
438 return $this;
439 }
440
441 /**
442 * Set the raw field of the form field.
443 *
444 * @return $this
445 */
446 protected function setRaw()
447 {
448 if (in_array('raw', $this->with)) {
449 $this->result[$this->attribute]['raw'] = $this->field;
450 }
451
452 return $this;
453 }
454 }
455