chore: complete update
This commit is contained in:
@@ -4,70 +4,99 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Router;
|
||||
|
||||
use App\Framework\Core\PathProvider;
|
||||
use App\Framework\DI\DefaultContainer;
|
||||
use App\Framework\Http\Headers;
|
||||
use App\Framework\Http\HttpResponse;
|
||||
use App\Framework\Http\Response;
|
||||
use App\Framework\View\Engine;
|
||||
use App\Framework\Http\Responses\SseResponse;
|
||||
use App\Framework\Http\Responses\WebSocketResponse;
|
||||
use App\Framework\Router\Result\FileResult;
|
||||
use App\Framework\Router\Result\JsonResult;
|
||||
use App\Framework\Router\Result\Redirect;
|
||||
use App\Framework\Router\Result\SseResult;
|
||||
use App\Framework\Router\Result\ViewResult;
|
||||
use App\Framework\Router\Result\WebSocketResult;
|
||||
use App\Framework\View\RenderContext;
|
||||
use App\Framework\View\Template;
|
||||
use App\Framework\View\TemplateRenderer;
|
||||
use App\Framework\View\TemplateRendererInitializer;
|
||||
|
||||
readonly class RouteResponder
|
||||
final readonly class RouteResponder
|
||||
{
|
||||
public function __construct(
|
||||
private TemplateRenderer $templateRenderer = new Engine()
|
||||
) {
|
||||
}
|
||||
private PathProvider $pathProvider,
|
||||
private DefaultContainer $container,
|
||||
private TemplateRenderer $templateRenderer,
|
||||
) {}
|
||||
|
||||
public function respond(ActionResult $result): Response
|
||||
public function respond(Response|ActionResult $result): Response
|
||||
{
|
||||
$contentType = "text/html";
|
||||
|
||||
switch ($result->resultType) {
|
||||
case ResultType::Html:
|
||||
$body = $this->renderTemplate(
|
||||
$result->template,
|
||||
$result->data,
|
||||
$result->layout ?? null,
|
||||
$result->slots ?? [],
|
||||
$result->controllerClass
|
||||
);
|
||||
|
||||
$contentType = "text/html";
|
||||
|
||||
break;
|
||||
case ResultType::Json:
|
||||
$body = json_encode(
|
||||
$result->data,
|
||||
JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE
|
||||
);
|
||||
$contentType = "application/json";
|
||||
|
||||
break;
|
||||
case ResultType::Plain:
|
||||
$body = $result->data['text'] ?? '';
|
||||
$contentType = "text/plain";
|
||||
break;
|
||||
default:
|
||||
throw new \RuntimeException("Unknown result type: {$result->resultType}");
|
||||
if($result instanceof Response) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
return new HttpResponse(
|
||||
status: $result->status,
|
||||
headers: new Headers()->with('Content-Type', $contentType), //['Content-Type' => $contentType],
|
||||
body: $body
|
||||
);
|
||||
return match(true) {
|
||||
$result instanceof ViewResult => new HttpResponse(
|
||||
status: $result->status,
|
||||
body: $this->renderTemplate(
|
||||
new RenderContext(
|
||||
template: $result->model ? $this->resolveTemplate($result->model) : $result->template,
|
||||
metaData: $result->metaData,
|
||||
data: $result->model ? get_object_vars($result->model) + $result->data : $result->data,
|
||||
layout: '',
|
||||
slots: $result->slots
|
||||
)
|
||||
)
|
||||
),
|
||||
$result instanceof JsonResult => new HttpResponse(
|
||||
status : $result->status,
|
||||
headers: new Headers()->with('Content-Type', 'application/json'),
|
||||
body : json_encode($result->data),
|
||||
),
|
||||
$result instanceof Redirect => new HttpResponse(
|
||||
status: $result->status,
|
||||
headers: new Headers()->with('Location', $result->target)
|
||||
),
|
||||
$result instanceof SseResult => new SseResponse($result, $result->callback),
|
||||
$result instanceof WebSocketResult => $this->createWebSocketResponse($result),
|
||||
$result instanceof FileResult => new HttpResponse(
|
||||
#headers: new Headers()->with('Content-Type', $result->mimeType),
|
||||
body: $result->filePath
|
||||
),
|
||||
|
||||
default => throw new \RuntimeException('Unbekanntes Ergebnisobjekt: ' . get_class($result)),
|
||||
};
|
||||
}
|
||||
|
||||
private function renderTemplate(string $template, array $data, ?string $layout, array $slots = [], ?string $controllerName = null): string
|
||||
private function createWebSocketResponse(WebSocketResult $result): WebSocketResponse
|
||||
{
|
||||
$context = new RenderContext(
|
||||
template: $template,
|
||||
data: $data,
|
||||
layout: $layout,
|
||||
slots: $slots,
|
||||
controllerClass: $controllerName
|
||||
);
|
||||
// WebSocket-Key aus Request-Headers abrufen
|
||||
$websocketKey = $_SERVER['HTTP_SEC_WEBSOCKET_KEY'] ?? '';
|
||||
|
||||
return new WebSocketResponse($result, $websocketKey);
|
||||
}
|
||||
|
||||
private function renderTemplate(RenderContext $context): string
|
||||
{
|
||||
return $this->templateRenderer->render($context);
|
||||
}
|
||||
|
||||
private function resolveTemplate(?object $model):string
|
||||
{
|
||||
if($model === null) {
|
||||
return 'test';
|
||||
}
|
||||
|
||||
$ref = new \ReflectionClass($model);
|
||||
$attrs = $ref->getAttributes(Template::class);
|
||||
if ($attrs === []) {
|
||||
return 'test';
|
||||
#throw new \RuntimeException("Fehlendes #[Template] Attribut in {$ref->getName()}");
|
||||
}
|
||||
|
||||
/** @var Template $attr */
|
||||
$attr = $attrs[0]->newInstance();
|
||||
return $attr->path;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user