jbboehr / phpstan-laravel-validation

GNU Affero General Public License v3.0
4 stars 1 forks source link

Wrapped or untyped response returned depending on context #6

Closed Firehed closed 1 year ago

Firehed commented 1 year ago

Hi there! I've run into a couple of type inconsistencies when using this plugin (at 26f81b6) under Laravel 9.x (9.48.0 specifically):

When using $controller->validate($request, [rules]) (as provided by Illuminate\Foundation\Validation\ValidatesRequests), the return type ends up as simply array rather than one with the type information provided:

// in a controller
$valid = $this->validate($request, [
    'amount' => 'required|integer',
]);
\PHPStan\dumpType($valid);

installed: Dumped type: array not installed Dumped type: array

Similarly, when using $request->validate([rules]) (as apparently provided by Illuminate/Foundation/Providers/FoundationServiceProvider calling Request::macro('validate', ...)), the actual validated array is returned, rather than Illuminate\Validation\Validator. While the validated type is correct if I unwrap it with ->validated(), this will cause a crash at runtime since the framework has already unwrapped the value!

// also in a controller
$valid = $request->validate([
    'amount' => 'required|integer',
]);
\PHPStan\dumpType($valid);

installed: Dumped type: Illuminate\Validate\Validator

\PHPStan\dumpType($valid->validated()) shows: Dumped type: array{amount: int|numeric-string} but doing this will crash at runtime!

not installed: Dumped type: mixed

In both cases, the actual value produced is:

['amount' => '1500']

In the former case, it looks like it should be handled by the FactoryMakeExtension (though the getClass() return value may not be picking up on the Contracts part of the namespace, but I tried changing it to no avail), so I'm totally lost.

In the latter case, I see the RequestValidateExtension returning the ValidatorType, so it appears to not be reflecting the fact that the framework calls validate() automatically.

Hopefully you find this feedback useful!

jbboehr commented 1 year ago

Haha, well there's a reason why I hadn't tagged a release yet :) Been meaning to take it for a spin on the codebase at work but got sidetracked with some other projects.

We also use rules() methods [0] a lot which the plugin can't really handle unfortunately as there isn't really any type inference for function return values in phpstan AFAICT:

public function rules()
{
    return [
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ];
}

Hopefully you find this feedback useful!

Absolutely! Hopefully my latest commits resolve your issue.