Skip to content

Commit

Permalink
wip: proper router parameters to reflection parameters mapping
Browse files Browse the repository at this point in the history
  • Loading branch information
romalytvynenko committed Nov 25, 2024
1 parent 7ffd366 commit 2ca03e5
Showing 1 changed file with 41 additions and 2 deletions.
43 changes: 41 additions & 2 deletions src/Support/OperationExtensions/RequestEssentialsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,16 @@
use Illuminate\Http\Request;
use Illuminate\Routing\ImplicitRouteBinding;
use Illuminate\Routing\Route;
use Illuminate\Routing\Router;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Reflector;
use Illuminate\Support\Str;
use Laravel\SerializableClosure\Support\ReflectionClosure;
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocNode;
use ReflectionException;
use ReflectionFunction;
use ReflectionNamedType;
use ReflectionParameter;

Expand Down Expand Up @@ -172,14 +176,19 @@ private function getRoutePathParameters(RouteInfo $routeInfo)

$paramNames = $route->parameterNames();

$implicitlyBoundParams = collect()
$implicitlyBoundReflectionParams = collect()
->union($route->signatureParameters(UrlRoutable::class))
->union($route->signatureParameters(['backedEnum' => true]))
->filter(function (ReflectionParameter $p) use ($paramNames) {
return in_array($p->name, $paramNames)
|| in_array(Str::snake($p->name), $paramNames);
});

$explicitlyBoundParamsNames = collect($paramNames)
->map($this->getExplicitlyBoundParamType(...))
->dd()
->values();

$routeParams = collect($route->signatureParameters())
->filter(function (ReflectionParameter $p) {
if (! $type = $p->getType()) {
Expand All @@ -188,7 +197,8 @@ private function getRoutePathParameters(RouteInfo $routeInfo)

return !$type instanceof ReflectionNamedType || $type->isBuiltin();
})
->union($implicitlyBoundParams)
->union($implicitlyBoundReflectionParams)
->sortKeys()
->values();

$paramsWithRealNames = $routeParams
Expand Down Expand Up @@ -243,6 +253,35 @@ private function getRoutePathParameters(RouteInfo $routeInfo)
return [$params, $aliases];
}

private function getExplicitlyBoundParamType(string $name): string|null
{
if (! $binder = app(Router::class)->getBindingCallback($name)) {
return null;
}

try {
$reflection = new ReflectionFunction($binder);
} catch (ReflectionException) {
return null;
}

if ($returnType = $reflection->getReturnType()) {
return $returnType instanceof ReflectionNamedType && !$returnType->isBuiltin()
? $returnType->getName()
: null;
}

// in case this is a model binder
if (
($modelClass = $reflection->getClosureUsedVariables()['class'] ?? null)
&& is_string($modelClass)
) {
return $modelClass;
}

return null;
}

private function getParameterType(string $paramName, string $description, RouteInfo $routeInfo, Route $route, ?ParamTagValueNode $phpDocParam, ?ReflectionParameter $reflectionParam)
{
$type = new UnknownType;
Expand Down

0 comments on commit 2ca03e5

Please sign in to comment.