Open ondrejmirtes opened 10 months ago
I've been doing sone work on this and based on the ticket description was pretty easy to get something working in two hours 🎉
@ondrejmirtes could you elaborate on what you mean with this:
Also override what ValidatedObjectType::isSuperTypeOf and acceptsWithReason answer.
Furthermore I'm wondering what should happen when assigning properties on a validated object. I guess that using the same narrowed type for PropertyReflection::getWritableType()
would disallow assigning any type which is actually assignable but might not pass validation? So IMO ideally assigning to any (validated) property should change the object type back (i.e. change the ValidatedObjectType
into an ObjectType
again).
Furthermore I have a technical question. Is there an easy method to parse the attributes arguments? For example NotBlank
has an allowNull
argument. So I need to parse the argument expressions on the attribute. Which results in some more complex code on it's own. And then, there are three methods to set this option, #[NotBlank(allowNull: true)]
, #[NotBlank(['allowNull' => true])]
and #[NotBlank(options: ['allowNull' => true])]
, which makes the code even worse. So if there is some method which you can give the Expr
of the argument which will resolve it into some PHP value already that would be nice. As now I have to resolve the ConstFetch
for true
/false
, walk over the Array_->items
, check every ArrayItem->key
whether it's a String_
, ....
I'd say that a validated object should stay validated, so it should only accept the narrowed type. I'd say it's a rare scenario anyway.
So if there is some method which you can give the Expr
When you ask for attributes with ClassReflection::getNativeReflection()->getProperty($name)->getAttributes()
, you're gonna end up with this object: https://apiref.phpstan.org/1.11.x/PHPStan.BetterReflection.Reflection.Adapter.ReflectionAttribute.html
You can see it has getArgumentsExpressions()
method.
You can use this class to turn expressions into Types: https://apiref.phpstan.org/1.11.x/PHPStan.Reflection.InitializerExprTypeResolver.html
There's a feature request for a nicer API: https://github.com/phpstan/phpstan/issues/10443
/cc @DaveLiddament
When an object is validated with Symfony Validator, we could narrow down its property types based on constraints.
My idea is:
class ValidatedObjectType extends ObjectType
ObjectType::getProperty()
, read the validator attributes, and narrow the property type in reflection returned from parent. We'd probably createnew ValidatedObjectPropertyReflection
, inject the original object, and only override the type getters.ValidatedObjectType::isSuperTypeOf
andacceptsWithReason
answer.symfony-validated<UserDTO>
and return ValidatedObjectType thanks to https://phpstan.org/developing-extensions/custom-phpdoc-types.The only missing part is to narrow the object type to a validated one after calling the validator:
This interface isn't really static analysis friendly. It'd be a job for a type-specifying extension to do that, but something like
$validator->isValid($author)
would be much easier to work with.