From 7dce1aa7d58b7b34cf81ad51c82644a4ca9f89bb Mon Sep 17 00:00:00 2001 From: Andrey Pyzhikov <5071@mail.ru> Date: Mon, 24 Jan 2022 02:29:15 +0800 Subject: [PATCH] Fix: Validation. Error key for field with asterisk Signed-off-by: Andrey Pyzhikov <5071@mail.ru> --- system/Validation/Validation.php | 13 ++++++++---- tests/system/Validation/ValidationTest.php | 18 +++++++++++++---- .../source/libraries/validation.rst | 20 +++++++++++++++++++ 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index 2ebe361fa5c8..d8b8358c55c7 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -139,7 +139,12 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup $rules = $this->splitRules($rules); } - $values = dot_array_search($field, $data); + $values = strpos($field, '*') !== false + ? array_filter(array_flatten_with_dots($data), static fn ($key) => preg_match( + '/^' . str_replace('\.\*', '\..+', preg_quote($field, '/')) . '$/', + $key + ), ARRAY_FILTER_USE_KEY) + : dot_array_search($field, $data); if ($values === []) { // We'll process the values right away if an empty array @@ -148,10 +153,10 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup continue; } - if (strpos($field, '*') !== false && is_array($values)) { + if (strpos($field, '*') !== false) { // Process multiple fields - foreach ($values as $value) { - $this->processRules($field, $setup['label'] ?? $field, $value, $rules, $data); + foreach ($values as $dotField => $value) { + $this->processRules($dotField, $setup['label'] ?? $field, $value, $rules, $data); } } else { // Process single field diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index fa5e769411b0..448ba7bc3f2e 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -825,21 +825,31 @@ public function testRulesForSingleRuleWithAsteriskWillReturnError(): void ], 'name_user' => [ 123, + 'alpha', 'xyz098', ], + 'contacts' => [ + 'friends' => [ + ['name' => ''], + ['name' => 'John'], + ], + ], ]; $request = new IncomingRequest($config, new URI(), 'php://input', new UserAgent()); $this->validation->setRules([ - 'id_user.*' => 'numeric', - 'name_user.*' => 'alpha', + 'id_user.*' => 'numeric', + 'name_user.*' => 'alpha', + 'contacts.*.name' => 'required', ]); $this->validation->withRequest($request->withMethod('post'))->run(); $this->assertSame([ - 'id_user.*' => 'The id_user.* field must contain only numbers.', - 'name_user.*' => 'The name_user.* field may only contain alphabetical characters.', + 'id_user.0' => 'The id_user.* field must contain only numbers.', + 'name_user.0' => 'The name_user.* field may only contain alphabetical characters.', + 'name_user.2' => 'The name_user.* field may only contain alphabetical characters.', + 'contacts.friends.0.name' => 'The contacts.*.name field is required.', ], $this->validation->getErrors()); } diff --git a/user_guide_src/source/libraries/validation.rst b/user_guide_src/source/libraries/validation.rst index 9029b6edb169..ca1b435f76e0 100644 --- a/user_guide_src/source/libraries/validation.rst +++ b/user_guide_src/source/libraries/validation.rst @@ -618,6 +618,26 @@ If you need to retrieve all error messages for failed fields, you can use the `` If no errors exist, an empty array will be returned. +When using a wildcard, the error will point to a specific field, replacing the asterisk with the appropriate key/keys.:: + + // for data + 'contacts' => [ + 'friends' => [ + [ + 'name' => 'Fred Flinstone', + ], + [ + 'name' => '', + ], + ] + ] + + //rule + contacts.*.name => 'required' + + // error will be + 'contacts.friends.1.name' => 'The contacts.*.name field is required.', + Getting a Single Error ======================