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
← All changes | app/Services/Parser/Extractor.php +149 -63 3.6.656.2.14 View file →
@@ -1,8 +1,10 @@
1 1 <?php
2 2
3 3 namespace FluentForm\App\Services\Parser;
4 4
5 +use FluentForm\App\Helpers\Helper;
6 +use FluentForm\App\Services\ConditionAssesor;
5 7 use FluentForm\Framework\Helpers\ArrayHelper as Arr;
6 8
7 9 class Extractor
8 10 {
@@ -20,9 +22,9 @@
20 22 */
21 23 protected $with;
22 24
23 25 /**
24 - * The supported form input types defined for Fluent Form.
26 + * The supported form input types defined for Fluent Forms.
25 27 *
26 28 * @var array
27 29 */
28 30 protected $inputTypes;
@@ -86,11 +88,13 @@
86 88 {
87 89 foreach ($fields as $field) {
88 90 // If the field is a Container (collection of other fields)
89 91 // then we will recursively call this function to resolve.
90 - if ($field['element'] === 'container') {
91 - foreach ($field['columns'] as $item) {
92 - $this->looper($item['fields']);
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);
93 97 }
94 98 }
95 99
96 100 // Now the field is supposed to be a flat field.
@@ -95,9 +99,10 @@
95 99
96 100 // Now the field is supposed to be a flat field.
97 101 // We can extract the desired keys as we want.
98 102 else {
99 - if (in_array($field['element'], $this->inputTypes)) {
103 + $element = Arr::get($field, 'element');
104 + if ($element && in_array($element, $this->inputTypes)) {
100 105 $this->extractField($field);
101 106 }
102 107 }
103 108 }
@@ -103,8 +108,58 @@
103 108 }
104 109 }
105 110
106 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 + /**
107 162 * Extract the form field.
108 163 *
109 164 * @param array $field
110 165 * @return $this
@@ -155,9 +210,9 @@
155 210 * @return $this
156 211 */
157 212 protected function setElement()
158 213 {
159 - $this->result[$this->attribute]['element'] = $this->field['element'];
214 + $this->result[$this->attribute]['element'] = Arr::get($this->field, 'element', '');
160 215 return $this;
161 216 }
162 217
163 218
@@ -201,12 +256,14 @@
201 256 */
202 257 protected function setOptions()
203 258 {
204 259 if (in_array('options', $this->with)) {
205 - $options = Arr::get($this->field, 'options', []);
260 + $options = Arr::get($this->field, 'options', []);
206 261
207 - if(!$options) {
208 - $newOptions = Arr::get($this->field, 'settings.advanced_options', []);
262 + if(!$options) {
263 + $newOptions = \FluentForm\App\Helpers\Helper::flattenAdvancedOptions(
264 + Arr::get($this->field, 'settings.advanced_options', [])
265 + );
209 266
210 267 if(
211 268 !$newOptions
212 269 && Arr::get($this->field,'element') == 'multi_payment_component'
@@ -282,8 +339,10 @@
282 339 $this->field,
283 340 'settings.validation_rules'
284 341 );
285 342
343 + $this->handleMaxLengthValidation();
344 +
286 345 $this->result[$this->attribute]['conditionals'] = Arr::get(
287 346 $this->field,
288 347 'settings.conditional_logics'
289 348 );
@@ -291,68 +350,95 @@
291 350
292 351 return $this;
293 352 }
294 353
295 - /**
296 - * Handle the child fields of the custom field.
297 - *
298 - * @return $this
299 - */
300 - protected function handleCustomField()
354 + protected function handleMaxLengthValidation()
301 355 {
302 - // If this field is a custom field we'll assume it has it's child fields
303 - // under the `fields` key. Then we are gonna modify those child fields'
304 - // attribute `name`, `label` & `conditional_logics` properties using
305 - // the parent field. The current implementation will modify those
306 - // properties in a way so that we can use dot notation to access.
307 - $customFields = Arr::get($this->field, 'fields');
356 + $maxLength = Arr::get($this->field, 'attributes.maxlength');
357 + $fieldHasMaxValidation = Arr::get($this->field, 'settings.validation_rules.max');
358 + $shouldSetMaxValidation = $maxLength && !$fieldHasMaxValidation;
308 359
309 - if ($customFields) {
310 - $parentAttribute = Arr::get($this->field, 'attributes.name');
311 -
312 - $parentConditionalLogics = Arr::get($this->field, 'settings.conditional_logics', []);
313 -
314 - $isAddressOrNameField = in_array(Arr::get($this->field, 'element'), ['address', 'input_name']);
315 -
316 - $isRepeatField = Arr::get($this->field, 'element') === 'input_repeat' || Arr::get($this->field, 'element') == 'repeater_field';
317 -
318 - foreach ($customFields as $index => $customField) {
319 - // If the current field is in fact `address` || `name` field
320 - // then we have to only keep the enabled child fields
321 - // by the user from the form editor settings.
322 - if ($isAddressOrNameField) {
323 - if (!Arr::get($customField, 'settings.visible', false)) {
324 - unset($customFields[$index]);
325 - continue;
326 - }
327 - }
328 -
329 - // Depending on whether the parent field is a repeat field or not
330 - // the modified attribute name of the child field will vary.
331 - if ($isRepeatField) {
332 - $modifiedAttribute = $parentAttribute.'['.$index.'].*';
333 - } else {
334 - $modifiedAttribute = $parentAttribute.'['.Arr::get($customField, 'attributes.name').']';
335 - }
336 -
337 - $modifiedLabel = $parentAttribute.'['.Arr::get($customField, 'settings.label').']';
338 -
339 - $customField['attributes']['name'] = $modifiedAttribute;
340 -
341 - $customField['settings']['label'] = $modifiedLabel;
342 -
343 - // Now, we'll replace the `conditional_logics` property
344 - $customField['settings']['conditional_logics'] = $parentConditionalLogics;
345 -
346 - // Now that this field's properties are handled we can pass
347 - // it to the extract field method to extract it's data.
348 - $this->extractField($customField);
360 + if ($shouldSetMaxValidation) {
361 + $message = Helper::getGlobalDefaultMessage('max');
362 + if (!$message) {
363 + $message = __('Validation fails for maximum value', 'fluentform');
349 364 }
365 + $this->result[$this->attribute]['rules']['max'] = [
366 + 'value' => $maxLength,
367 + 'message' => $message,
368 + ];
350 369 }
351 370
352 371 return $this;
353 372 }
354 -
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 +
355 441 /**
356 442 * Set the raw field of the form field.
357 443 *
358 444 * @return $this
@@ -361,8 +447,8 @@
361 447 {
362 448 if (in_array('raw', $this->with)) {
363 449 $this->result[$this->attribute]['raw'] = $this->field;
364 450 }
365 -
451 +
366 452 return $this;
367 453 }
368 454 }