PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.2
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.2
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.2, at app/Services/Parser/Extractor.php

453 lines 12.9 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 = 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 $message = Helper::getGlobalDefaultMessage('max');
360 if (!$message) {
361 $message = __('Validation fails for maximum value', 'fluentform');
362 }
363 $this->result[$this->attribute]['rules']['max'] = [
364 'value' => $maxLength,
365 'message' => $message,
366 ];
367 }
368
369 return $this;
370 }
371
372 /**
373 * Handle the child fields of complex form fields (address, name, repeater).
374 *
375 * This method processes fields that have sub-fields (like address field having
376 * address_line_1, city, state, etc.) and prepares them for shortcode generation.
377 *
378 * @return $this
379 */
380 protected function handleCustomField()
381 {
382 // If this field is a custom field we'll assume it has it's child fields
383 // under the `fields` key. Then we are gonna modify those child fields'
384 // attribute `name`, `label` & `conditional_logics` properties using
385 // the parent field. The current implementation will modify those
386 // properties in a way so that we can use dot notation to access.
387 $customFields = Arr::get($this->field, 'fields');
388
389 if ($customFields) {
390 $parentAttribute = Arr::get($this->field, 'attributes.name');
391
392 $parentConditionalLogics = Arr::get($this->field, 'settings.conditional_logics', []);
393
394 $isAddressOrNameField = in_array(Arr::get($this->field, 'element'), ['address', 'input_name']);
395
396 $isRepeatField = Arr::get($this->field, 'element') === 'input_repeat' || Arr::get($this->field, 'element') == 'repeater_field';
397
398 // Allow plugins to modify custom fields before processing
399 $customFields = apply_filters('fluentform/extractor_parser_custom_fields', $customFields, $this->field);
400
401 foreach ($customFields as $index => $customField) {
402 // If the current field is in fact `address` || `name` field
403 // then we have to only keep the enabled child fields
404 // by the user from the form editor settings.
405 if ($isAddressOrNameField) {
406 $subFieldName = Arr::get($customField, 'attributes.name');
407 if (!Arr::get($customField, 'settings.visible', false) && !in_array($subFieldName, ['latitude', 'longitude'])) {
408 unset($customFields[$index]);
409 continue;
410 }
411 }
412
413 // Depending on whether the parent field is a repeat field or not
414 // the modified attribute name of the child field will vary.
415 if ($isRepeatField) {
416 $modifiedAttribute = $parentAttribute.'['.$index.'].*';
417 } else {
418 $modifiedAttribute = $parentAttribute.'['.Arr::get($customField, 'attributes.name').']';
419 }
420
421 $modifiedLabel = $parentAttribute.'['.Arr::get($customField, 'settings.label').']';
422
423 $customField['attributes']['name'] = $modifiedAttribute;
424
425 $customField['settings']['label'] = $modifiedLabel;
426
427 // Now, we'll replace the `conditional_logics` property
428 $customField['settings']['conditional_logics'] = $parentConditionalLogics;
429
430 // Now that this field's properties are handled we can pass
431 // it to the extract field method to extract it's data.
432 $this->extractField($customField);
433 }
434 }
435
436 return $this;
437 }
438
439 /**
440 * Set the raw field of the form field.
441 *
442 * @return $this
443 */
444 protected function setRaw()
445 {
446 if (in_array('raw', $this->with)) {
447 $this->result[$this->attribute]['raw'] = $this->field;
448 }
449
450 return $this;
451 }
452 }
453