diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index 7e4a55db55cf..ed370a2f5c08 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -168,7 +168,7 @@ public function run(?array $data = null, ?string $group = null, ?string $dbGroup if (strpos($field, '*') !== false) { // Process multiple fields foreach ($values as $dotField => $value) { - $this->processRules($dotField, $setup['label'] ?? $field, $value, $rules, $data); + $this->processRules($dotField, $setup['label'] ?? $field, $value, $rules, $data, $field); } } else { // Process single field @@ -201,10 +201,17 @@ public function check($value, string $rule, array $errors = []): bool * * @param array|string $value * @param array|null $rules - * @param array $data + * @param array $data The array of data to validate, with `DBGroup`. + * @param string|null $originalField The original asterisk field name like "foo.*.bar". */ - protected function processRules(string $field, ?string $label, $value, $rules = null, ?array $data = null): bool - { + protected function processRules( + string $field, + ?string $label, + $value, + $rules = null, + ?array $data = null, + ?string $originalField = null + ): bool { if ($data === null) { throw new InvalidArgumentException('You must supply the parameter: data.'); } @@ -333,7 +340,8 @@ protected function processRules(string $field, ?string $label, $value, $rules = $field, $label, $param, - (string) $value + (string) $value, + $originalField ); return false; @@ -706,13 +714,21 @@ public function setError(string $field, string $error): ValidationInterface * * @param string|null $value The value that caused the validation to fail. */ - protected function getErrorMessage(string $rule, string $field, ?string $label = null, ?string $param = null, ?string $value = null): string - { + protected function getErrorMessage( + string $rule, + string $field, + ?string $label = null, + ?string $param = null, + ?string $value = null, + ?string $originalField = null + ): string { $param ??= ''; // Check if custom message has been defined by user if (isset($this->customErrors[$field][$rule])) { $message = lang($this->customErrors[$field][$rule]); + } elseif (null !== $originalField && isset($this->customErrors[$originalField][$rule])) { + $message = lang($this->customErrors[$originalField][$rule]); } else { // Try to grab a localized version of the message... // lang() will return the rule name back if not found, diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index c6339139044d..5a48615b6c05 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -463,6 +463,28 @@ public function testRunGroupWithCustomErrorMessage(): void ], $this->validation->getErrors()); } + /** + * @see https://github.com/codeigniter4/CodeIgniter4/issues/6245 + */ + public function testRunWithCustomErrorsAndAsteriskField(): void + { + $data = [ + 'foo' => [ + ['bar' => null], + ['bar' => null], + ], + ]; + $this->validation->setRules( + ['foo.*.bar' => ['label' => 'foo bar', 'rules' => 'required']], + ['foo.*.bar' => ['required' => 'Required']] + ); + $this->validation->run($data); + $this->assertSame([ + 'foo.0.bar' => 'Required', + 'foo.1.bar' => 'Required', + ], $this->validation->getErrors()); + } + /** * @dataProvider rulesSetupProvider * diff --git a/user_guide_src/source/changelogs/v4.2.5.rst b/user_guide_src/source/changelogs/v4.2.5.rst index a670705e4153..eb9c8f7ec643 100644 --- a/user_guide_src/source/changelogs/v4.2.5.rst +++ b/user_guide_src/source/changelogs/v4.2.5.rst @@ -14,6 +14,7 @@ BREAKING - The method signature of ``BaseConnection::tableExists()`` has been changed. A second optional parameter ``$cached`` was added. This directs whether to use cache data or not. Default is ``true``, use cache data. - The abstract method signature of ``BaseBuilder::_listTables()`` has been changed. A second optional parameter ``$tableName`` was added. Providing a table name will generate SQL listing only that table. +- The method signature of ``Validation::processRules()`` and ``Validation::getErrorMessage()`` have been changed. Both of these methods add new ``$originalField`` parameter. Enhancements ************