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:
mwpn
2025-10-11 07:08:23 +07:00
commit 0b42271bfe
90 changed files with 8315 additions and 0 deletions

View 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);
}
}

View 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);
}
}

View 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";
}
}

View 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);
}
}

View 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);
}
}