json($data, $statusCode); } protected function redirect(string $url, ?string $flashSuccess = null, ?string $flashError = null): Response { if ($flashSuccess) { View::setFlash('success', $flashSuccess); } if ($flashError) { View::setFlash('error', $flashError); } $response = new Response(); return $response->redirect($url); } protected function validateCsrf(Request $request): bool { if (session_status() === PHP_SESSION_NONE) { session_start(); } $token = $request->post('_csrf') ?: $request->getHeader('X-CSRF-Token'); $sessionToken = $_SESSION['csrf_token'] ?? null; return $token && $sessionToken && hash_equals($sessionToken, $token); } }