diff --git a/system/Validation/Validation.php b/system/Validation/Validation.php index 5eae6b52c9a5..cd81352eb8c2 100644 --- a/system/Validation/Validation.php +++ b/system/Validation/Validation.php @@ -918,26 +918,24 @@ protected function getErrorMessage( ): string { $param ??= ''; + $args = [ + 'field' => ($label === null || $label === '') ? $field : lang($label), + 'param' => (! isset($this->rules[$param]['label'])) ? $param : lang($this->rules[$param]['label']), + 'value' => $value ?? '', + ]; + // 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, - // so there will always be a string being returned. - $message = lang('Validation.' . $rule); + return lang($this->customErrors[$field][$rule], $args); + } + if (null !== $originalField && isset($this->customErrors[$originalField][$rule])) { + return lang($this->customErrors[$originalField][$rule], $args); } - $message = str_replace('{field}', ($label === null || $label === '') ? $field : lang($label), $message); - $message = str_replace( - '{param}', - (! isset($this->rules[$param]['label'])) ? $param : lang($this->rules[$param]['label']), - $message - ); - - return str_replace('{value}', $value ?? '', $message); + // Try to grab a localized version of the message... + // lang() will return the rule name back if not found, + // so there will always be a string being returned. + return lang('Validation.' . $rule, $args); } /** diff --git a/tests/system/Validation/ValidationTest.php b/tests/system/Validation/ValidationTest.php index 234d4d00be53..5906e2ac5465 100644 --- a/tests/system/Validation/ValidationTest.php +++ b/tests/system/Validation/ValidationTest.php @@ -1351,6 +1351,30 @@ public function testTranslatedLabelWithCustomErrorMessage(): void $this->assertSame('The Foo Bar Translated field is very short.', $this->validation->getError('foo')); } + public function testTranslatedLabelWithCustomErrorMessageAndComplexLanguageString(): void + { + // Lithuanian language used as an example + $rules = [ + 'foo' => [ + 'label' => 'Lauko pavadinimas', + 'rules' => 'min_length[5]', + 'errors' => [ + 'min_length' => '{param, plural, + =0 {Lauke „{field}" negali būti mažiau nei nulis ženklų} + =1 {Lauke „{field}" negali būti mažiau nei vienas ženklas} + one {Lauke „{field}" negali būti mažiau nei # ženklas} + few {Lauke „{field}" negali būti mažiau nei # ženklai} + other {Lauke „{field}" negali būti mažiau nei # ženklų} + }', + ], + ], + ]; + + $this->validation->setRules($rules, []); + $this->validation->run(['foo' => 'abc']); + $this->assertSame('Lauke „Lauko pavadinimas" negali būti mažiau nei 5 ženklų', $this->validation->getError('foo')); + } + public function testTranslatedLabelTagReplacement(): void { $data = ['Username' => 'Pizza']; diff --git a/user_guide_src/source/changelogs/v4.5.6.rst b/user_guide_src/source/changelogs/v4.5.6.rst index 8a486ae9de3f..a835382a5724 100644 --- a/user_guide_src/source/changelogs/v4.5.6.rst +++ b/user_guide_src/source/changelogs/v4.5.6.rst @@ -41,6 +41,8 @@ Bugs Fixed - **Routing:** Fixed a TypeError in `str_replace()` when `Routing::$translateURIDashes` is set to `true` and a route is defined using a closure. +- **Validation:** Fixed a bug where complex language strings were not properly handled. + See the repo's `CHANGELOG.md `_ for a complete list of bugs fixed.