feat: Complete Woles Framework v1.0 with enterprise-grade UI
- Add comprehensive error handling system with custom error pages - Implement professional enterprise-style design with Tailwind CSS - Create modular HMVC architecture with clean separation of concerns - Add security features: CSRF protection, XSS filtering, Argon2ID hashing - Include CLI tools for development workflow - Add error reporting dashboard with system monitoring - Implement responsive design with consistent slate color scheme - Replace all emoji icons with professional SVG icons - Add comprehensive test suite with PHPUnit - Include database migrations and seeders - Add proper exception handling with fallback pages - Implement template engine with custom syntax support - Add helper functions and facades for clean code - Include proper logging and debugging capabilities
This commit is contained in:
14
app/Core/Exceptions/CsrfMismatchException.php
Normal file
14
app/Core/Exceptions/CsrfMismatchException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Core\Exceptions;
|
||||
|
||||
/**
|
||||
* 419 CSRF Token Mismatch Exception
|
||||
*/
|
||||
class CsrfMismatchException extends \Exception
|
||||
{
|
||||
public function __construct(string $message = "CSRF token mismatch", int $code = 419, ?\Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
14
app/Core/Exceptions/ForbiddenException.php
Normal file
14
app/Core/Exceptions/ForbiddenException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Core\Exceptions;
|
||||
|
||||
/**
|
||||
* 403 Forbidden Exception
|
||||
*/
|
||||
class ForbiddenException extends \Exception
|
||||
{
|
||||
public function __construct(string $message = "Access forbidden", int $code = 403, ?\Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
154
app/Core/Exceptions/Handler.php
Normal file
154
app/Core/Exceptions/Handler.php
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace App\Core\Exceptions;
|
||||
|
||||
use App\Modules\Error\Controller as ErrorController;
|
||||
|
||||
/**
|
||||
* NovaCore Exception Handler
|
||||
* Global exception handling with modern error pages
|
||||
*/
|
||||
class Handler
|
||||
{
|
||||
/**
|
||||
* Handle exception
|
||||
*/
|
||||
public function handle(\Throwable $e): void
|
||||
{
|
||||
// Log the exception
|
||||
$this->logException($e);
|
||||
|
||||
// Show error page
|
||||
$this->renderException($e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log exception
|
||||
*/
|
||||
private function logException(\Throwable $e): void
|
||||
{
|
||||
$logFile = storage_path('logs/error.log');
|
||||
$timestamp = date('Y-m-d H:i:s');
|
||||
|
||||
$message = "[{$timestamp}] " . get_class($e) . ": {$e->getMessage()}\n";
|
||||
$message .= "File: {$e->getFile()}:{$e->getLine()}\n";
|
||||
$message .= "Stack trace:\n{$e->getTraceAsString()}\n\n";
|
||||
|
||||
file_put_contents($logFile, $message, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render exception
|
||||
*/
|
||||
private function renderException(\Throwable $e): void
|
||||
{
|
||||
try {
|
||||
$errorController = new ErrorController();
|
||||
|
||||
// Determine error type and render appropriate page
|
||||
if ($e instanceof \App\Core\Exceptions\NotFoundException) {
|
||||
$errorController->notFound();
|
||||
} elseif ($e instanceof \App\Core\Exceptions\ForbiddenException) {
|
||||
$errorController->forbidden();
|
||||
} elseif ($e instanceof \App\Core\Exceptions\UnauthorizedException) {
|
||||
$errorController->unauthorized();
|
||||
} elseif ($e instanceof \App\Core\Exceptions\CsrfMismatchException) {
|
||||
$errorController->csrfMismatch();
|
||||
} else {
|
||||
$errorController->serverError($e);
|
||||
}
|
||||
} catch (\Throwable $renderException) {
|
||||
// Fallback to basic error page if error rendering fails
|
||||
$this->renderFallbackException($e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render fallback exception (when error page rendering fails)
|
||||
*/
|
||||
private function renderFallbackException(\Throwable $e): void
|
||||
{
|
||||
http_response_code(500);
|
||||
|
||||
if (is_development()) {
|
||||
$this->renderDevelopmentException($e);
|
||||
} else {
|
||||
$this->renderProductionException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render development exception
|
||||
*/
|
||||
private function renderDevelopmentException(\Throwable $e): void
|
||||
{
|
||||
http_response_code(500);
|
||||
|
||||
echo "<!DOCTYPE html>\n";
|
||||
echo "<html>\n<head>\n";
|
||||
echo "<title>Woles Framework Error</title>\n";
|
||||
echo "<script src=\"https://cdn.tailwindcss.com\"></script>\n";
|
||||
echo "<link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap\" rel=\"stylesheet\">\n";
|
||||
echo "</head>\n<body class=\"font-sans bg-slate-50 min-h-screen p-8\">\n";
|
||||
echo "<div class=\"max-w-4xl mx-auto\">\n";
|
||||
echo "<div class=\"bg-white rounded-xl shadow-sm border border-red-200 p-8\">\n";
|
||||
echo "<div class=\"flex items-center mb-6\">\n";
|
||||
echo "<div class=\"w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center mr-4\">\n";
|
||||
echo "<svg class=\"h-6 w-6 text-red-600\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n";
|
||||
echo "<path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z\"></path>\n";
|
||||
echo "</svg>\n";
|
||||
echo "</div>\n";
|
||||
echo "<h1 class=\"text-2xl font-bold text-slate-900\">" . get_class($e) . "</h1>\n";
|
||||
echo "</div>\n";
|
||||
echo "<div class=\"bg-red-50 border border-red-200 rounded-lg p-4 mb-6\">\n";
|
||||
echo "<p class=\"text-red-800 font-medium\">" . htmlspecialchars($e->getMessage()) . "</p>\n";
|
||||
echo "</div>\n";
|
||||
echo "<div class=\"bg-slate-50 border border-slate-200 rounded-lg p-4 mb-4\">\n";
|
||||
echo "<p class=\"text-sm text-slate-600\"><strong>File:</strong> " . htmlspecialchars($e->getFile()) . ":" . $e->getLine() . "</p>\n";
|
||||
echo "</div>\n";
|
||||
echo "<div class=\"bg-slate-900 text-green-400 p-4 rounded-lg font-mono text-xs overflow-x-auto\">\n";
|
||||
echo "<pre>" . htmlspecialchars($e->getTraceAsString()) . "</pre>\n";
|
||||
echo "</div>\n";
|
||||
echo "<div class=\"mt-6 text-center\">\n";
|
||||
echo "<a href=\"/\" class=\"bg-slate-900 hover:bg-slate-800 text-white px-6 py-3 rounded-md font-medium transition-colors\">Go Home</a>\n";
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
echo "</body>\n</html>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Render production exception
|
||||
*/
|
||||
private function renderProductionException(): void
|
||||
{
|
||||
http_response_code(500);
|
||||
|
||||
echo "<!DOCTYPE html>\n";
|
||||
echo "<html>\n<head>\n";
|
||||
echo "<title>Server Error - Woles Framework</title>\n";
|
||||
echo "<script src=\"https://cdn.tailwindcss.com\"></script>\n";
|
||||
echo "<link href=\"https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap\" rel=\"stylesheet\">\n";
|
||||
echo "</head>\n<body class=\"font-sans bg-slate-50 min-h-screen\">\n";
|
||||
echo "<div class=\"min-h-screen flex items-center justify-center px-4 sm:px-6 lg:px-8\">\n";
|
||||
echo "<div class=\"max-w-md w-full space-y-8\">\n";
|
||||
echo "<div class=\"text-center\">\n";
|
||||
echo "<div class=\"mx-auto h-24 w-24 bg-slate-100 rounded-full flex items-center justify-center mb-6\">\n";
|
||||
echo "<svg class=\"h-12 w-12 text-slate-400\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n";
|
||||
echo "<path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z\"></path>\n";
|
||||
echo "</svg>\n";
|
||||
echo "</div>\n";
|
||||
echo "<h1 class=\"text-6xl font-bold text-slate-900 mb-2\">500</h1>\n";
|
||||
echo "<h2 class=\"text-2xl font-semibold text-slate-900 mb-4\">Server Error</h2>\n";
|
||||
echo "<p class=\"text-slate-600 mb-8\">Something went wrong on our end.</p>\n";
|
||||
echo "<div class=\"space-y-4\">\n";
|
||||
echo "<a href=\"/\" class=\"w-full flex justify-center py-3 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-slate-900 hover:bg-slate-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-900\">Return to Home</a>\n";
|
||||
echo "<button onclick=\"location.reload()\" class=\"w-full flex justify-center py-3 px-4 border border-slate-300 rounded-md shadow-sm text-sm font-medium text-slate-700 bg-white hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-slate-500\">Try Again</button>\n";
|
||||
echo "</div>\n";
|
||||
echo "<div class=\"mt-8 text-sm text-slate-500\">We're working to fix this issue. Please try again later.</div>\n";
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
echo "</div>\n";
|
||||
echo "</body>\n</html>\n";
|
||||
}
|
||||
}
|
||||
14
app/Core/Exceptions/NotFoundException.php
Normal file
14
app/Core/Exceptions/NotFoundException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Core\Exceptions;
|
||||
|
||||
/**
|
||||
* 404 Not Found Exception
|
||||
*/
|
||||
class NotFoundException extends \Exception
|
||||
{
|
||||
public function __construct(string $message = "Page not found", int $code = 404, ?\Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
14
app/Core/Exceptions/UnauthorizedException.php
Normal file
14
app/Core/Exceptions/UnauthorizedException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace App\Core\Exceptions;
|
||||
|
||||
/**
|
||||
* 401 Unauthorized Exception
|
||||
*/
|
||||
class UnauthorizedException extends \Exception
|
||||
{
|
||||
public function __construct(string $message = "Unauthorized access", int $code = 401, ?\Throwable $previous = null)
|
||||
{
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user