PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 6.2.15
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v6.2.15
6.2.15 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 All 197 releases
← All changes | app/Services/Parser/Validations.php +55 -39 3.6.60 → 6.2.15 View file →
@@ -1,9 +1,8 @@
1 1 <?php
2 2
3 3 namespace FluentForm\App\Services\Parser;
4 4
5 -use FluentForm\App\Services\ConditionAssesor;
6 5 use FluentForm\Framework\Helpers\ArrayHelper as Arr;
7 6
8 7 class Validations
9 8 {
@@ -55,8 +54,21 @@
55 54 */
56 55 protected $messages = [];
57 56
58 57 /**
58 + * Rules the validator has no method for.
59 + *
60 + * Selection limits are counted against the field's own options in
61 + * Helper::validateSelectionLimits(), which runs later in the submission with
62 + * the raw field settings in hand — the only place the configured (or global)
63 + * message for the breach can be resolved. Emitting them here too would lean
64 + * on the validator silently ignoring rules it does not recognise.
65 + *
66 + * @var array
67 + */
68 + protected $rulesHandledElsewhere = ['min_selection', 'max_selection'];
69 +
70 + /**
59 71 * The validation extractor constructor.
60 72 *
61 73 * @param array $formFields
62 74 * @param array $formData
@@ -74,30 +86,30 @@
74 86 */
75 87 public function get()
76 88 {
77 89 foreach ($this->fields as $fieldName => $field) {
78 - /*
79 - * todo: isApplicable has some issue for radio / checkbox $applicable getting false
80 - * even it's required!
81 - */
82 - $applicable = $this->setFieldAccessor($fieldName)->isApplicable($field);
90 + $this->setFieldAccessor($fieldName);
83 91
84 - if ($applicable) {
85 - $fieldValue = $this->getFieldValue();
92 + $fieldValue = $this->getFieldValue();
86 93
87 - $rules = (array) $field['rules'];
94 + $rules = (array) $field['rules'];
88 95
89 - $hasRequiredRule = Arr::get($rules, 'required.value');
96 + $hasRequiredRule = Arr::get($rules, 'required.value');
90 97
91 - // If the field is a repeater we'll set some settings here.
92 - $this->setRepeater($fieldName, $field);
98 + // If the field is a repeater we'll set some settings here.
99 + $this->setRepeater($fieldName, $field);
93 100
94 - foreach ($rules as $ruleName => $rule) {
95 - if ($this->shouldNotSkipThisRule($rule, $fieldValue, $hasRequiredRule)) {
96 - $this->prepareValidations($fieldName, $ruleName, $rule);
97 - }
101 + foreach ($rules as $ruleName => $rule) {
102 + if (in_array($ruleName, $this->rulesHandledElsewhere, true)) {
103 + continue;
98 104 }
105 +
106 + if ($this->shouldNotSkipThisRule($rule, $fieldValue, $hasRequiredRule)) {
107 + $this->prepareValidations($fieldName, $ruleName, $rule);
108 + }
99 109 }
110 +
111 + $this->ensureStringTypeForSizeRules($fieldName, $rules);
100 112 }
101 113
102 114
103 115 return [$this->rules, $this->messages];
@@ -117,29 +129,8 @@
117 129 return $this;
118 130 }
119 131
120 132 /**
121 - * Determines if the field is applicable for extracting validations.
122 - *
123 - * @param array $field
124 - * @return boolean
125 - */
126 - protected function isApplicable($field)
127 - {
128 - // We need to evaluate if this field should be used to validate
129 - // the form data because it's possible that this field ain't
130 - // even present in the form data or it has conditional
131 - // logics that dictates it's presence in the rules.
132 -
133 - // NOTE: Previous code by Arif
134 - return Arr::has(
135 - $this->inputs, $this->accessor
136 - ) && ConditionAssesor::evaluate(
137 - $field, $this->inputs
138 - );
139 - }
140 -
141 - /**
142 133 * Get the field value from the form data.
143 134 *
144 135 * @return mixed
145 136 */
@@ -163,15 +154,15 @@
163 154 if ($isRepeater) {
164 155 $attribute = Arr::get($field, 'attributes.name');
165 156 $length = isset($attribute[0]) ? count($attribute[0]) : 0;
166 157 $this->repeater = [
167 - 'status' => $isRepeater,
158 + 'status' => true,
168 159 'attribute' => $attribute,
169 160 'length' => $length,
170 161 'rule' => rtrim($fieldName, '.*')
171 162 ];
172 163 } else {
173 - $this->repeater['status'] = $isRepeater;
164 + $this->repeater['status'] = false;
174 165 }
175 166
176 167 return $this;
177 168 }
@@ -248,6 +239,31 @@
248 239 implode(',', array_filter(array_values(str_replace('|', ',', $rule['value'])))) :
249 240 $rule['value'];
250 241
251 242 return $ruleName.':'.$ruleValue;
243 + }
244 +
245 + /**
246 + * Ensure fields with max/min rules but no numeric rule
247 + * are treated as strings for character-length validation.
248 + *
249 + * Without this, the WPFluent validator treats numeric-looking
250 + * input (e.g. phone "123456") as a number and compares the
251 + * numeric value against max/min instead of string length.
252 + *
253 + * @param string $fieldName
254 + * @param array $rules
255 + */
256 + protected function ensureStringTypeForSizeRules($fieldName, $rules)
257 + {
258 + if (!isset($this->rules[$fieldName])) {
259 + return;
260 + }
261 +
262 + $hasSizeRule = !empty($rules['max']['value']) || !empty($rules['min']['value']);
263 + $hasNumericRule = !empty($rules['numeric']['value']);
264 +
265 + if ($hasSizeRule && !$hasNumericRule && !is_array($this->getFieldValue())) {
266 + $this->rules[$fieldName] = 'string|' . $this->rules[$fieldName];
267 + }
252 268 }
253 269 }