diff --git a/README.md b/README.md index 336021e..33cd30b 100644 --- a/README.md +++ b/README.md @@ -42,15 +42,18 @@ use Yiisoft\Validator\Rule\Required; final class LoginForm extends FormModel { + #[Label('Your login')] #[Required] #[Length(min: 4, max: 40, skipOnEmpty: true)] #[Email(skipOnEmpty: true)] private ?string $login = null; + #[Label('Your password')] #[Required] #[Length(min: 8, skipOnEmpty: true)] private ?string $password = null; + #[Label('Remember me for 1 week')] #[Safe] private bool $rememberMe = false; } diff --git a/src/FormModel.php b/src/FormModel.php index b79801a..afcf827 100644 --- a/src/FormModel.php +++ b/src/FormModel.php @@ -5,6 +5,7 @@ namespace Yiisoft\FormModel; use LogicException; +use ReflectionAttribute; use ReflectionClass; use ReflectionException; use Yiisoft\FormModel\Exception\PropertyNotSupportNestedValuesException; @@ -15,6 +16,7 @@ use Yiisoft\Hydrator\Attribute\SkipHydration; use Yiisoft\Strings\Inflector; use Yiisoft\Strings\StringHelper; +use Yiisoft\Validator\Label; use Yiisoft\Validator\Result; use function array_key_exists; @@ -237,6 +239,18 @@ private function readPropertyMetaValue(int $metaKey, string $path): ?string return null; } + /** + * Try to get label from {@see Label} PHP attribute. + */ + if ($metaKey === self::META_LABEL) { + $attributes = $property->getAttributes(Label::class, ReflectionAttribute::IS_INSTANCEOF); + foreach ($attributes as $attribute) { + /** @var Label $instance */ + $instance = $attribute->newInstance(); + return $instance->getLabel(); + } + } + $value = $property->getValue($value); if (!is_object($value)) { return null; diff --git a/tests/FormModelTest.php b/tests/FormModelTest.php index aed3786..5e6009c 100644 --- a/tests/FormModelTest.php +++ b/tests/FormModelTest.php @@ -21,6 +21,7 @@ use Yiisoft\FormModel\Tests\Support\Form\DefaultFormNameForm; use Yiisoft\FormModel\Tests\Support\Form\FormWithNestedProperty; use Yiisoft\FormModel\Tests\Support\Form\FormWithNestedStructures; +use Yiisoft\FormModel\Tests\Support\Form\LabelForm; use Yiisoft\FormModel\Tests\Support\Form\LoginForm; use Yiisoft\FormModel\Tests\Support\Form\NestedForm; use Yiisoft\FormModel\Tests\Support\Form\NestedMixedForm\NestedMixedForm; @@ -682,4 +683,20 @@ public function testAddErrorWithoutValidation(): void $this->expectExceptionMessage('Validation result is not set.'); $form->addError('Test message.'); } + + public static function dataLabel(): iterable + { + yield ['AgeFromAttribute', 'age']; + yield ['NameFromGetter', 'name']; + } + + #[DataProvider('dataLabel')] + public function testLabel(string $expected, string $property): void + { + $form = new LabelForm(); + + $label = $form->getPropertyLabel($property); + + $this->assertSame($expected, $label); + } } diff --git a/tests/Support/Form/LabelForm.php b/tests/Support/Form/LabelForm.php new file mode 100644 index 0000000..4abf176 --- /dev/null +++ b/tests/Support/Form/LabelForm.php @@ -0,0 +1,24 @@ + 'NameFromGetter', + ]; + } +}