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,40 @@
<?php
namespace App\Core\Commands;
/**
* Woles Command Factory
* Factory for creating command instances
*/
class CommandFactory
{
/**
* Create command instance
*/
public static function create(string $command): object
{
switch ($command) {
case 'make:module':
return new MakeModuleCommand();
case 'make:controller':
return new MakeControllerCommand();
case 'make:model':
return new MakeModelCommand();
case 'serve':
return new ServeCommand();
case 'migrate':
return new MigrateCommand();
case 'migrate:rollback':
return new MigrateCommand();
case 'migrate:status':
return new MigrateCommand();
case 'seed':
return new SeedCommand();
case 'key:generate':
return new KeyGenerateCommand();
case 'help':
default:
return new HelpCommand();
}
}
}

View File

@@ -0,0 +1,55 @@
<?php
namespace App\Core\Commands;
/**
* Woles Help Command
* CLI command to show help information
*/
class HelpCommand
{
private array $commands = [];
public function __construct()
{
$this->commands = [
'make:module' => 'Create a new module',
'make:controller' => 'Create a new controller',
'make:model' => 'Create a new model',
'serve' => 'Start development server',
'migrate' => 'Run database migrations',
'migrate:rollback' => 'Rollback last migration batch',
'migrate:status' => 'Show migration status',
'seed' => 'Run database seeders',
'key:generate' => 'Generate application key',
'key:generate-show' => 'Generate and show application key',
'help' => 'Show available commands'
];
}
/**
* Execute the command
*/
public function execute(): void
{
echo "Woles Framework Artisan CLI\n\n";
echo "Available commands:\n";
foreach ($this->commands as $command => $description) {
echo " " . str_pad($command, 20) . " {$description}\n";
}
echo "\nExamples:\n";
echo " php woles make:module Blog\n";
echo " php woles make:controller PostController Blog\n";
echo " php woles make:model Post Blog\n";
echo " php woles serve\n";
echo " php woles migrate\n";
echo " php woles migrate:rollback\n";
echo " php woles migrate:status\n";
echo " php woles seed\n";
echo " php woles seed UserSeeder\n";
echo " php woles key:generate\n";
echo " php woles key:generate-show\n";
}
}

View File

@@ -0,0 +1,52 @@
<?php
namespace App\Core\Commands;
/**
* KeyGenerateCommand
* Generate and set APP_KEY in .env
*/
class KeyGenerateCommand
{
/**
* Execute the command
*/
public function execute(bool $showOnly = false): void
{
$key = bin2hex(random_bytes(32)); // 64 hex chars
if ($showOnly) {
echo $key . "\n";
return;
}
$envPath = __DIR__ . '/../../../.env';
$examplePath = __DIR__ . '/../../../env.example';
// If .env doesn't exist, try to copy from example
if (!file_exists($envPath)) {
if (file_exists($examplePath)) {
copy($examplePath, $envPath);
} else {
// Create minimal .env
file_put_contents($envPath, "APP_NAME=NovaCore Framework\nAPP_ENV=production\nAPP_DEBUG=false\n");
}
}
$content = file_get_contents($envPath) ?: '';
// Replace or append APP_KEY
if (preg_match('/^APP_KEY=.*/m', $content)) {
$content = preg_replace('/^APP_KEY=.*/m', 'APP_KEY=' . $key, $content);
} else {
$content .= (str_ends_with($content, "\n") ? '' : "\n") . 'APP_KEY=' . $key . "\n";
}
// Backup and write
@copy($envPath, $envPath . '.bak');
file_put_contents($envPath, $content);
echo "Application key set successfully.\n";
echo "APP_KEY=" . $key . "\n";
}
}

View File

@@ -0,0 +1,41 @@
<?php
namespace App\Core\Commands;
class MakeControllerCommand
{
public function execute(string $name, string $module): void
{
if (!$name || !$module) {
echo "Error: Controller name and module are required\n";
echo "Usage: php artisan make:controller <ControllerName> <ModuleName>\n";
return;
}
$modulePath = __DIR__ . "/../../Modules/{$module}";
if (!is_dir($modulePath)) {
echo "Error: Module '{$module}' does not exist\n";
return;
}
$content = "<?php
namespace App\\Modules\\{$module};
use App\\Core\\Controller;
class {$name} extends Controller
{
public function index()
{
return \$this->view('{$module}.view.index', [
'title' => '{$module} - NovaCore Framework'
]);
}
}";
file_put_contents("{$modulePath}/{$name}.php", $content);
echo "Controller '{$name}' created in module '{$module}'!\n";
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace App\Core\Commands;
class MakeModelCommand
{
public function execute(string $name, string $module): void
{
if (!$name || !$module) {
echo "Error: Model name and module are required\n";
echo "Usage: php artisan make:model <ModelName> <ModuleName>\n";
return;
}
$modulePath = __DIR__ . "/../../Modules/{$module}";
if (!is_dir($modulePath)) {
echo "Error: Module '{$module}' does not exist\n";
return;
}
$content = "<?php
namespace App\\Modules\\{$module};
class {$name}
{
// Add your model methods here
}";
file_put_contents("{$modulePath}/{$name}.php", $content);
echo "Model '{$name}' created in module '{$module}'!\n";
}
}

View File

@@ -0,0 +1,164 @@
<?php
namespace App\Core\Commands;
/**
* NovaCore Make Module Command
* CLI command to create new modules
*/
class MakeModuleCommand
{
private string $modulesPath;
public function __construct()
{
$this->modulesPath = __DIR__ . '/../../Modules';
}
/**
* Execute the command
*/
public function execute(string $moduleName): void
{
if (!$moduleName) {
echo "Error: Module name is required\n";
echo "Usage: php artisan make:module <ModuleName>\n";
return;
}
$modulePath = $this->modulesPath . '/' . $moduleName;
$viewPath = "{$modulePath}/view";
// Create directories
if (!is_dir($modulePath)) {
mkdir($modulePath, 0755, true);
}
if (!is_dir($viewPath)) {
mkdir($viewPath, 0755, true);
}
// Create Controller
$this->createController($moduleName, $modulePath);
// Create Model
$this->createModel($moduleName, $modulePath);
// Create Routes
$this->createRoutes($moduleName, $modulePath);
// Create View
$this->createView($moduleName, $viewPath);
echo "Module '{$moduleName}' created successfully!\n";
echo "Controller: {$modulePath}/Controller.php\n";
echo "Model: {$modulePath}/Model.php\n";
echo "Routes: {$modulePath}/routes.php\n";
echo "View: {$viewPath}/index.php\n";
}
/**
* Create controller file
*/
private function createController(string $moduleName, string $modulePath): void
{
$controllerContent = "<?php
namespace App\\Modules\\{$moduleName};
use App\\Core\\Controller;
/**
* {$moduleName} Controller
*/
class Controller extends Controller
{
public function index()
{
return \$this->view('{$moduleName}.view.index', [
'title' => '{$moduleName} - NovaCore Framework'
]);
}
}";
file_put_contents("{$modulePath}/Controller.php", $controllerContent);
}
/**
* Create model file
*/
private function createModel(string $moduleName, string $modulePath): void
{
$modelContent = "<?php
namespace App\\Modules\\{$moduleName};
/**
* {$moduleName} Model
*/
class Model
{
// Add your model methods here
}";
file_put_contents("{$modulePath}/Model.php", $modelContent);
}
/**
* Create routes file
*/
private function createRoutes(string $moduleName, string $modulePath): void
{
$routesContent = "<?php
/**
* {$moduleName} Module Routes
*/
\$router->get('/{$moduleName}', '{$moduleName}\\Controller@index');";
file_put_contents("{$modulePath}/routes.php", $routesContent);
}
/**
* Create view file
*/
private function createView(string $moduleName, string $viewPath): void
{
$viewContent = "<!DOCTYPE html>
<html lang=\"en\">
<head>
<meta charset=\"UTF-8\">
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">
<title>{{ \$title }}</title>
<style>
body {
font-family: 'Outfit', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: #f8f9fa;
margin: 0;
padding: 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
background: white;
padding: 2rem;
border-radius: 10px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h1 {
color: #667eea;
margin-bottom: 1rem;
}
</style>
</head>
<body>
<div class=\"container\">
<h1>{{ \$title }}</h1>
<p>Welcome to the {$moduleName} module!</p>
</div>
</body>
</html>";
file_put_contents("{$viewPath}/index.php", $viewContent);
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace App\Core\Commands;
use App\Core\Database\Migrator;
/**
* NovaCore Migrate Command
* CLI command to run database migrations
*/
class MigrateCommand
{
private Migrator $migrator;
public function __construct()
{
$this->migrator = new Migrator();
}
/**
* Execute the command
*/
public function execute(): void
{
echo "Running database migrations...\n";
$this->migrator->run();
}
/**
* Rollback migrations
*/
public function rollback(): void
{
echo "Rolling back migrations...\n";
$this->migrator->rollback();
}
/**
* Show migration status
*/
public function status(): void
{
$this->migrator->status();
}
}

View File

@@ -0,0 +1,91 @@
<?php
namespace App\Core\Commands;
use App\Core\Database\Seeder;
/**
* NovaCore Seed Command
* CLI command to run database seeders
*/
class SeedCommand
{
private string $seedersPath;
public function __construct()
{
$this->seedersPath = __DIR__ . '/../../database/seeders';
}
/**
* Execute the command
*/
public function execute(string $seeder = null): void
{
if ($seeder) {
$this->runSeeder($seeder);
} else {
$this->runAllSeeders();
}
}
/**
* Run all seeders
*/
private function runAllSeeders(): void
{
echo "Running database seeders...\n";
$seederFiles = glob($this->seedersPath . '/*.php');
foreach ($seederFiles as $file) {
$filename = basename($file);
$className = $this->getSeederClassName($filename);
require_once $file;
if (class_exists($className)) {
$seeder = new $className();
$seeder->run();
}
}
echo "Seeding completed successfully!\n";
}
/**
* Run specific seeder
*/
private function runSeeder(string $seederName): void
{
$file = $this->seedersPath . '/' . $seederName . '.php';
if (!file_exists($file)) {
echo "Error: Seeder '{$seederName}' not found\n";
return;
}
$className = $this->getSeederClassName($seederName . '.php');
require_once $file;
if (!class_exists($className)) {
echo "Error: Seeder class '{$className}' not found\n";
return;
}
echo "Running seeder: {$seederName}\n";
$seeder = new $className();
$seeder->run();
echo "Seeder completed successfully!\n";
}
/**
* Get seeder class name
*/
private function getSeederClassName(string $filename): string
{
$name = pathinfo($filename, PATHINFO_FILENAME);
return "Database\\Seeders\\{$name}";
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace App\Core\Commands;
/**
* NovaCore Serve Command
* CLI command to start development server
*/
class ServeCommand
{
/**
* Execute the command
*/
public function execute(): void
{
$port = getenv('APP_PORT') ?: '8000';
$host = getenv('APP_HOST') ?: 'localhost';
echo "NovaCore Framework development server starting...\n";
echo "Server running at http://{$host}:{$port}\n";
echo "Press Ctrl+C to stop the server\n\n";
exec("php -S {$host}:{$port} -t public");
}
}