Files
michaelschiemer/src/Framework/Router/ParameterProcessor.php

77 lines
2.5 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Router;
use App\Framework\DI\DefaultContainer;
use App\Framework\Http\ControllerRequest;
use App\Framework\Http\Request;
use App\Framework\Logging\DefaultLogger;
use App\Framework\Router\Exceptions\ParameterResolutionException;
use ReflectionClass;
use ReflectionException;
final readonly class ParameterProcessor
{
public function __construct(
private DefaultContainer $container,
private ControllerRequestFactory $controllerRequestFactory,
private DefaultLogger $logger
) {}
public function prepareParameters(array $params, array $queryParams): array
{
$parameters = [];
foreach ($params as $param) {
try {
if(in_array($param['name'], array_keys($queryParams))) {
$parameters[] = $queryParams[$param['name']];
continue;
}
if ($param['isBuiltin'] === true) {
$parameters[] = $param['default'] ?? null;
continue;
}
$reflectionClass = new ReflectionClass($param['type']);
if ($reflectionClass->implementsInterface(ControllerRequest::class)) {
$request = $this->container->get(Request::class);
$parsedBody = $request->parsedBody;
$controllerRequest = $this->controllerRequestFactory
->createAndValidate($reflectionClass, $parsedBody);
$this->container->bind($param['type'], $controllerRequest);
$parameters[] = $controllerRequest;
continue;
}
$parameters[] = $this->container->get($param['type']);
} catch (ReflectionException $e) {
$this->logger?->error("Parameter reflection failed", [
'type' => $param['type'],
'error' => $e->getMessage()
]);
throw new ParameterResolutionException(
"Cannot resolve parameter of type '{$param['type']}'",
0,
$e
);
} catch (\Throwable $e) {
$this->logger?->error("Parameter preparation failed", [
'param' => $param,
'error' => $e->getMessage()
]);
throw $e;
}
}
return $parameters;
}
}