Skip to content

Commit 50da213

Browse files
committed
fix!: Validation rule with * gets incorrect values as dot array syntax
1 parent 0872a21 commit 50da213

2 files changed

Lines changed: 40 additions & 17 deletions

File tree

system/Validation/Validation.php

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -168,12 +168,21 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup
168168
}
169169

170170
if (strpos($field, '*') !== false) {
171-
$values = array_filter(array_flatten_with_dots($data), static fn ($key) => preg_match(
172-
'/^'
173-
. str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/'))
174-
. '$/',
175-
$key
176-
), ARRAY_FILTER_USE_KEY);
171+
$flattenedArray = array_flatten_with_dots($data);
172+
173+
$pattern = '/\A'
174+
. str_replace(
175+
['\.\*', '\*\.'],
176+
['\.[^.]+', '[^.]+\.'],
177+
preg_quote($field, '/')
178+
)
179+
. '\z/';
180+
$values = array_filter(
181+
$flattenedArray,
182+
static fn ($key) => preg_match($pattern, $key),
183+
ARRAY_FILTER_USE_KEY
184+
);
185+
177186
// if keys not found
178187
$values = $values ?: [$field => null];
179188
} else {
@@ -814,7 +823,13 @@ private function retrievePlaceholders(string $rule, array $data): array
814823
*/
815824
public function hasError(string $field): bool
816825
{
817-
$pattern = '/^' . str_replace('\.\*', '\..+', preg_quote($field, '/')) . '$/';
826+
$pattern = '/\A'
827+
. str_replace(
828+
['\.\*', '\*\.'],
829+
['\.[^.]+', '[^.]+\.'],
830+
preg_quote($field, '/')
831+
)
832+
. '\z/';
818833

819834
return (bool) preg_grep($pattern, array_keys($this->getErrors()));
820835
}
@@ -829,10 +844,18 @@ public function getError(?string $field = null): string
829844
$field = array_key_first($this->rules);
830845
}
831846

832-
$errors = array_filter($this->getErrors(), static fn ($key) => preg_match(
833-
'/^' . str_replace(['\.\*', '\*\.'], ['\..+', '.+\.'], preg_quote($field, '/')) . '$/',
834-
$key
835-
), ARRAY_FILTER_USE_KEY);
847+
$pattern = '/\A'
848+
. str_replace(
849+
['\.\*', '\*\.'],
850+
['\.[^.]+', '[^.]+\.'],
851+
preg_quote($field, '/')
852+
)
853+
. '\z/';
854+
$errors = array_filter(
855+
$this->getErrors(),
856+
static fn ($key) => preg_match($pattern, $key),
857+
ARRAY_FILTER_USE_KEY
858+
);
836859

837860
return $errors === [] ? '' : implode("\n", $errors);
838861
}

tests/system/Validation/ValidationTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1111,17 +1111,17 @@ public function testRulesForSingleRuleWithAsteriskWillReturnError(): void
11111111
$request = new IncomingRequest($config, new URI(), 'php://input', new UserAgent());
11121112

11131113
$this->validation->setRules([
1114-
'id_user.*' => 'numeric',
1115-
'name_user.*' => 'alpha',
1116-
'contacts.*.name' => 'required',
1114+
'id_user.*' => 'numeric',
1115+
'name_user.*' => 'alpha',
1116+
'contacts.friends.*.name' => 'required',
11171117
]);
11181118

11191119
$this->validation->withRequest($request->withMethod('post'))->run();
11201120
$this->assertSame([
11211121
'id_user.0' => 'The id_user.* field must contain only numbers.',
11221122
'name_user.0' => 'The name_user.* field may only contain alphabetical characters.',
11231123
'name_user.2' => 'The name_user.* field may only contain alphabetical characters.',
1124-
'contacts.friends.0.name' => 'The contacts.*.name field is required.',
1124+
'contacts.friends.0.name' => 'The contacts.friends.*.name field is required.',
11251125
], $this->validation->getErrors());
11261126

11271127
$this->assertSame(
@@ -1130,8 +1130,8 @@ public function testRulesForSingleRuleWithAsteriskWillReturnError(): void
11301130
$this->validation->getError('name_user.*')
11311131
);
11321132
$this->assertSame(
1133-
'The contacts.*.name field is required.',
1134-
$this->validation->getError('contacts.*.name')
1133+
'The contacts.friends.*.name field is required.',
1134+
$this->validation->getError('contacts.friends.*.name')
11351135
);
11361136
}
11371137

0 commit comments

Comments
 (0)