diff --git a/.github/workflows/rector.yml b/.github/workflows/rector.yml index adacd735a..bd79331da 100644 --- a/.github/workflows/rector.yml +++ b/.github/workflows/rector.yml @@ -14,8 +14,10 @@ name: rector jobs: rector: uses: yiisoft/actions/.github/workflows/rector.yml@master + secrets: + token: ${{ secrets.YIISOFT_GITHUB_TOKEN }} with: os: >- ['ubuntu-latest'] php: >- - ['8.0'] + ['8.2'] diff --git a/CHANGELOG.md b/CHANGELOG.md index 446ebd6c0..09ec86a77 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ - Chg #624: Fix meaning of error message in `OneOf` rule (@arogachev) - Chg #625: Improve meaning and use pluralization in error message for `OneOf` and `AtLeast` rules (@arogachev) - Chg #626: Disallow `$min` greater than amount of `$attributes` in `AtLeast` configuration (@arogachev) +- Bug #632: Fix property name usage in error messages of rules in `Nested` rule (@vjik) ## 1.1.0 April 06, 2023 diff --git a/psalm.xml b/psalm.xml index f4cecedef..d091d59c2 100644 --- a/psalm.xml +++ b/psalm.xml @@ -9,5 +9,11 @@ > + + + + + + diff --git a/src/Rule/EmailHandler.php b/src/Rule/EmailHandler.php index d0c3daa84..b1b88f34e 100644 --- a/src/Rule/EmailHandler.php +++ b/src/Rule/EmailHandler.php @@ -44,7 +44,7 @@ public function validate(mixed $value, object $rule, ValidationContext $context) if ($rule->isIdnEnabled()) { $matches['local'] = idn_to_ascii($matches['local']); $matches['domain'] = idn_to_ascii($matches['domain']); - $value = implode([ + $value = implode('', [ $matches['name'], $matches['open'], $matches['local'], diff --git a/src/Rule/NestedHandler.php b/src/Rule/NestedHandler.php index cbb33fc46..2a2e263f2 100644 --- a/src/Rule/NestedHandler.php +++ b/src/Rule/NestedHandler.php @@ -63,12 +63,9 @@ public function validate(mixed $value, object $rule, ValidationContext $context) foreach ($rule->getRules() as $valuePath => $rules) { if ($rule->isPropertyPathRequired() && !ArrayHelper::pathExists($data, $valuePath)) { - if (is_int($valuePath)) { - $valuePathList = [$valuePath]; - } else { - /** @var list $valuePathList */ - $valuePathList = StringHelper::parsePath($valuePath); - } + $valuePathList = is_int($valuePath) + ? [$valuePath] + : StringHelper::parsePath($valuePath); $compoundResult->addError( $rule->getNoPropertyPathMessage(), @@ -82,25 +79,24 @@ public function validate(mixed $value, object $rule, ValidationContext $context) continue; } - /** @var mixed $validatedValue */ $validatedValue = ArrayHelper::getValueByPath($data, $valuePath); - $itemResult = $context->validate($validatedValue, $rules); + if (is_int($valuePath)) { + $itemResult = $context->validate($validatedValue, $rules); + } else { + $valuePathList = StringHelper::parsePath($valuePath); + $attribute = (string) end($valuePathList); + $itemResult = $context->validate([$attribute => $validatedValue], [$attribute => $rules]); + } + if ($itemResult->isValid()) { continue; } foreach ($itemResult->getErrors() as $error) { - if (is_int($valuePath)) { - $valuePathList = [$valuePath]; - } else { - /** @var list $valuePathList */ - $valuePathList = StringHelper::parsePath($valuePath); - } - - if (!empty($valuePathList)) { - array_push($valuePathList, ...$error->getValuePath()); - } + $valuePathList = is_int($valuePath) + ? [$valuePath, ...$error->getValuePath()] + : [...StringHelper::parsePath($valuePath), ...array_slice($error->getValuePath(), 1)]; $compoundResult->addError($error->getMessage(), $error->getParameters(), $valuePathList); } diff --git a/tests/Rule/NestedTest.php b/tests/Rule/NestedTest.php index 86c10aed7..5d80aa154 100644 --- a/tests/Rule/NestedTest.php +++ b/tests/Rule/NestedTest.php @@ -1263,6 +1263,21 @@ public function hasAttribute(string $attribute): bool 'level1.level2.level3.name' => ['This value must contain at least 5 characters.'], ], ], + 'error messages with attributes in nested structure' => [ + [ + 'user' => [ + 'name' => '', + ], + ], + new Nested([ + 'user' => [ + 'name' => new Required(message: '{attribute} is required.'), + ], + ]), + [ + 'user.name' => ['name is required.'], + ], + ], ]; }