Files
MVC/init.php
T
2026-05-22 12:24:06 +02:00

1172 lines
30 KiB
PHP

<?php
/**
* Ultimate MVC Project Bootstrapper (Fixed Version with Header)
* Erstellt ein voll funktionsfähiges Projekt inkl. Dev-Server, Header, DarkMode & freiem Zugriff.
*/
if (php_sapi_name() !== 'cli') {
die("Dieses Script muss über die CLI ausgeführt werden.\n");
}
$projectName = $argv[1] ?? null;
if (!$projectName) {
echo "Bitte gib einen Projektnamen an: ";
$handle = fopen("php://stdin", "r");
$projectName = trim(fgets($handle));
fclose($handle);
}
if (!$projectName) die("Fehler: Kein Name angegeben.\n");
$baseDir = getcwd() . DIRECTORY_SEPARATOR . $projectName;
// 1. Verzeichnisstruktur erstellen
$dirs = [
'',
'WEBROOT',
'WEBROOT/api',
'WEBROOT/api/v1',
'WEBROOT/commands',
'WEBROOT/static',
'WEBROOT/src',
'WEBROOT/src/config',
'WEBROOT/src/database',
'WEBROOT/src/utils',
'WEBROOT/src/MVC',
'WEBROOT/src/MVC/Core',
'WEBROOT/src/MVC/Classes',
'WEBROOT/src/MVC/Controller',
'WEBROOT/src/MVC/Model',
'WEBROOT/src/MVC/View',
'WEBROOT/src/MVC/Layout',
'WEBROOT/src/MVC/Layout/Templates',
];
foreach ($dirs as $dir) {
$path = $baseDir . ($dir ? DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $dir) : '');
if (!is_dir($path)) {
mkdir($path, 0755, true);
echo "📁 Ordner erstellt: $dir\n";
}
}
$files = [];
// --- DEV SERVER: server.php ---
$files['server.php'] = <<<'PHP'
<?php
$port = 8000;
$host = 'localhost';
$root = __DIR__ . '/WEBROOT';
echo "\n🚀 Starte MVC Dev-Server auf http://$host:$port\n";
echo "Drücke STRG+C zum Beenden.\n\n";
passthru("php -S $host:$port -t \"$root\"");
PHP;
$files['.htaccess'] = <<<'HTACCESS'
RewriteEngine On
RewriteRule ^(Commands|config_backups|controller|modules)($|/.*) - [F,L,NC]
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
# -----------------------------------
# .php entfernen
# -----------------------------------
# browser requestet datei.php -> redirect zu /datei
RewriteCond %{THE_REQUEST} \s/+(.+?)\.php[\s?] [NC]
RewriteRule ^ /%1 [R=301,L]
# /datei -> datei.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+)$ $1.php [L]
HTACCESS;
$files[$projectName . '.code-workspace'] = <<<VSCODE
{
"folders": [
{
"path": "."
}
],
"settings": {
"workbench.colorTheme": "Default Dark Modern",
"workbench.colorCustomizations": {
"activityBar.background": "#ff000075",
"activityBar.foreground": "#000000",
"breadcrumb.foreground": "#FFFFFF",
},
"files.exclude": {
"*.git*": true,
"WEBROOT/config_backups": true,
"WEBROOT/static": true,
"WEBROOT/templates": true,
},
"editor.renderWhitespace": "all",
"editor.smoothScrolling": true,
"editor.fontSize": 14,
"editor.formatOnSave": true,
"editor.minimap.enabled": true,
"editor.minimap.scale": 2,
"editor.minimap.side": "right",
"editor.minimap.maxColumn": 100,
"editor.minimap.renderCharacters": true,
"editor.minimap.showSlider": "always",
"files.autoSave": "off",
"files.autoSaveDelay": 3000,
"window.title": "BACKEND",
"workbench.editor.wrapTabs": true,
},
"extensions": {
"recommendations": [
"oderwat.indent-rainbow",
"pranaygp.vscode-css-peek",
"wayou.vscode-todo-highlight",
"mrmlnc.vscode-mustache",
"fabiospampinato.vscode-highlight",
"junstyle.php-cs-fixer",
"mtea.gettext-editor",
"neilbrayfield.php-docblocker",
"bmewburn.vscode-intelephense-client",
"mohamed-ali.html-css-class-completion",
"rifi2k.format-html-in-php",
"mrorz.language-gettext",
"voldemortensen.rainbow-tags",
]
}
}
VSCODE;
$files['WEBROOT/src/utils/databaseMethods.php'] = <<<'PHP'
<?php
function DatabaseCreateTable($table, $columnsDefinition) {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$sql = "CREATE TABLE IF NOT EXISTS `$table` ($columnsDefinition)";
$stmt = $conn->prepare($sql);
if (!$stmt) {
die("Fehler beim Prepare: " . $conn->error);
}
if (!$stmt->execute()) {
die("Fehler beim Execute: " . $stmt->error);
}
return true;
}
function DatabaseShowTables() {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$tablesResult = $conn->query("SHOW TABLES");
if (!$tablesResult) {
die("Fehler beim Laden der Tabellen: " . $conn->error);
}
$tables = [];
while ($tableRow = $tablesResult->fetch_array()) {
$tables[] = $tableRow[0];
}
return $tables;
}
function DatabaseShowTableStructure($table) {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$stmt = $conn->prepare("SHOW COLUMNS FROM `$table`");
if (!$stmt) {
die("Fehler beim Prepare: " . $conn->error);
}
if (!$stmt->execute()) {
die("Fehler beim Execute: " . $stmt->error);
}
$result = $stmt->get_result();
$columns = [];
while ($column = $result->fetch_assoc()) {
$columns[] = [
"Field" => $column["Field"],
"Type" => $column["Type"],
"Null" => $column["Null"],
"Key" => $column["Key"],
"Default" => $column["Default"],
"Extra" => $column["Extra"]
];
}
return $columns;
}
function DatabaseShow($table, $columns = "*", $where = "", ...$values) {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$sql = "SELECT $columns FROM `$table`";
if (!empty($where)) {
$sql .= " WHERE $where";
}
$stmt = $conn->prepare($sql);
if (!$stmt) {
die("Fehler beim Prepare: " . $conn->error);
}
if (!$stmt->execute($values)) {
die("Fehler beim Execute: " . $stmt->error);
}
$result = $stmt->get_result();
return $result->fetch_all(MYSQLI_ASSOC);
}
function DatabaseInsert($table, $columns, ...$values) {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$placeholders = rtrim(str_repeat("?,", count($values)), ",");
$sql = "INSERT INTO `$table` ($columns) VALUES ($placeholders)";
$stmt = $conn->prepare($sql);
if (!$stmt) {
die("Fehler beim Prepare: " . $conn->error);
}
if (!$stmt->execute($values)) {
die("Fehler beim Execute: " . $stmt->error);
}
return true;
}
function DatabaseDelete($table, $where, ...$values) {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$sql = "DELETE FROM `$table` WHERE $where";
$stmt = $conn->prepare($sql);
if (!$stmt) {
die("Fehler beim Prepare: " . $conn->error);
}
if (!$stmt->execute($values)) {
die("Fehler beim Execute: " . $stmt->error);
}
return true;
}
function DatabaseUpdate($table, $set, $where, ...$values) {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$sql = "UPDATE `$table` SET $set WHERE $where";
$stmt = $conn->prepare($sql);
if (!$stmt) {
die("Fehler beim Prepare: " . $conn->error);
}
if (!$stmt->execute($values)) {
die("Fehler beim Execute: " . $stmt->error);
}
return true;
}
function getFKValue($conn, $table, $key, $value, $id, &$cache) {
if ($id === null) return null;
$cacheKey = $table . "_" . $id;
if (isset($cache[$cacheKey])) {
return $cache[$cacheKey];
}
$stmt = $conn->prepare("SELECT `$value` FROM `$table` WHERE `$key` = ? LIMIT 1");
if (!$stmt) {
die("FK Prepare Fehler: " . $conn->error);
}
$stmt->bind_param("i", $id);
$stmt->execute();
$result = $stmt->get_result()->fetch_assoc();
$valueResult = $result[$value] ?? null;
$cache[$cacheKey] = $valueResult;
return $valueResult;
}
function DatabaseShowWithFK($table, $fkMap = [], $columns = "*", $where = "", ...$values) {
include_once(__DIR__ . '/../database/databaseConnect.php');
$conn = db_connect();
$cache = [];
$select = is_array($columns) ? implode(", ", $columns) : $columns;
$sql = "SELECT $select FROM `$table`";
if (!empty($where)) {
$sql .= " WHERE $where";
}
$stmt = $conn->prepare($sql);
if (!$stmt) die("Fehler beim Prepare: " . $conn->error);
if (!empty($values)) {
$stmt->execute($values);
} else {
$stmt->execute();
}
$result = $stmt->get_result();
if (!$result) die("Fehler beim get_result: " . $conn->error);
$rows = $result->fetch_all(MYSQLI_ASSOC);
foreach ($rows as &$row) {
foreach ($fkMap as $fkColumn => $fkInfo) {
if (!isset($row[$fkColumn]) || $row[$fkColumn] === null) {
continue;
}
$row[$fkColumn] = getFKValue(
$conn,
$fkInfo['table'],
$fkInfo['key'],
$fkInfo['value'],
$row[$fkColumn],
$cache
);
}
}
return [
"rows" => $rows
];
}
PHP;
// --- CONFIG: env.ini ---
$files['WEBROOT/src/config/env.ini'] = <<<INI
[database]
APP_ENV = "dev"
DB_DEV_HOST = "localhost"
DB_DEV_USERNAME = "root"
DB_DEV_PASSWORD = ""
DB_DEV_DATABASE = "mein_projekt"
INI;
// --- DB: databaseConnect.php ---
$files['WEBROOT/src/database/databaseConnect.php'] = <<<'PHP'
<?php
function db_connect() {
$config = parse_ini_file(__DIR__ . '/../config/env.ini');
$env = strtoupper($config['APP_ENV']);
try {
$conn = new mysqli(
$config["DB_{$env}_HOST"],
$config["DB_{$env}_USERNAME"],
$config["DB_{$env}_PASSWORD"],
$config["DB_{$env}_DATABASE"]
);
$conn->set_charset("utf8mb4");
return $conn;
} catch (Exception $e) {
return null;
}
}
PHP;
// -- CLASSES --
$files['WEBROOT/src/MVC/Classes/Api.php'] = <<<'PHP'
<?php
namespace MVC\Classes;
class Api {
public static function jsonResponse($data, int $statusCode = 200) {
header('Content-Type: application/json');
http_response_code($statusCode);
echo json_encode(
[
'status' => $statusCode === 200 ? 'success' : 'error',
'data' => $data,
], JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE
);
exit;
}
}
PHP;
$files['WEBROOT/src/MVC/Classes/Client.php'] = <<<'PHP'
<?php
namespace MVC\Classes;
class Client {
public static function ip() {
if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$ipList = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
return trim($ipList[0]);
} else if (!empty($_SERVER['REMOTE_ADDR'])) {
return $_SERVER['REMOTE_ADDR'];
} else {
return 'UNKNOWN';
}
}
public static function port() {
return $_SERVER['REMOTE_PORT'] ?? 'UNKNOWN';
}
public static function country() {
$response = file_get_contents('http://ip-api.com/json/{' . self::ip() . '}?fields=country,countryCode');
$data = json_decode($response);
return $data->country ?? 'UNKNOWN';
}
public static function userAgent() {
return $_SERVER['HTTP_USER_AGENT'] ?? 'UNKNOWN';
}
}
PHP;
$files['WEBROOT/src/MVC/Classes/Cookie.php'] = <<<'PHP'
<?php
namespace MVC\Classes;
class Cookie {
public function set(string $CookieName, int $CookieValue, int $CookieTime) {
setcookie($CookieName, $CookieValue, time()+($CookieTime*60));
}
public function read(string $CookieName) {
if (isset($_COOKIE[$CookieName])) {
return $_COOKIE[$CookieName];
}
return 'Cookie not set';
}
public function Delete(string $CookieName) {
setcookie($CookieName, "", time()-(3600*24));
}
}
PHP;
$files['WEBROOT/src/MVC/Classes/Request.php'] = <<<'PHP'
<?php
namespace MVC\Classes;
class Request {
public static function method() {
return $_SERVER['REQUEST_METHOD'] ?? 'UNKNOWN';
}
public static function uri() {
return $_SERVER['REQUEST_URI'] ?? 'UNKNOWN';
}
public static function headers() {
return getallheaders();
}
public static function body() {
return file_get_contents('php://input');
}
public static function queryParams() {
return $_GET;
}
public static function time() {
return $_SERVER['REQUEST_TIME'] ?? 'UNKNOWN';
}
public static function referrer() {
return $_SERVER['HTTP_REFERER'] ?? 'UNKNOWN';
}
}
PHP;
$files['WEBROOT/src/MVC/Classes/Server.php'] = <<<'PHP'
<?php
namespace MVC\Classes;
class Server {
public static function documentRoot() {
return $_SERVER['DOCUMENT_ROOT'] ?? 'UNKNOWN';
}
public static function currentDir() {
return __DIR__;
}
public static function currentScript() {
return $_SERVER['SCRIPT_NAME'] ?? 'UNKNOWN';
}
public static function name() {
return $_SERVER['SERVER_NAME'] ?? 'UNKNOWN';
}
public static function port() {
return $_SERVER['SERVER_PORT'] ?? 'UNKNOWN';
}
}
PHP;
// --- CORE ---
$files['WEBROOT/src/MVC/Core/Controller.php'] = <<<'PHP'
<?php
namespace MVC\Core;
class Controller {
protected $view;
public function __construct() {
$this->view = new View(__DIR__ . '/../View');
}
protected function render($template, $data = []) {
foreach ($data as $key => $value) {
$this->view->assign($key, $value);
}
return $this->view->render($template);
}
protected function json($data, $status = 200) {
header('Content-Type: application/json');
http_response_code($status);
echo json_encode($data);
exit;
}
}
PHP;
$files['WEBROOT/src/MVC/Core/Model.php'] = <<<'PHP'
<?php
namespace MVC\Core;
require_once __DIR__ . '/../../database/databaseConnect.php';
require_once __DIR__ . '/../../utils/databaseMethods.php';
abstract class Model {
protected static $table;
protected static $conn;
protected static function getConnection() {
if (!self::$conn) {
self::$conn = \db_connect();
}
return self::$conn;
}
public static function all() {
return \DatabaseShow(static::$table, "*");
}
public static function find($id, $column = 'ID') {
$result = \DatabaseShow(static::$table, "*", "$column = ?", $id);
return $result[0] ?? null;
}
public static function where($where, ...$params) {
return \DatabaseShow(static::$table, "*", $where, ...$params);
}
public static function insert($data) {
$columns = implode(", ", array_keys($data));
$values = array_values($data);
return \DatabaseInsert(static::$table, $columns, ...$values);
}
public static function update($data, $where, ...$whereParams) {
$sets = [];
$values = [];
foreach ($data as $column => $value) {
$sets[] = "$column = ?";
$values[] = $value;
}
$setString = implode(", ", $sets);
return \DatabaseUpdate(static::$table, $setString, $where, ...array_merge($values, $whereParams));
}
public static function delete($where, ...$params) {
return \DatabaseDelete(static::$table, $where, ...$params);
}
public static function query($sql, ...$params) {
$conn = self::getConnection();
if (empty($params)) {
return $conn->query($sql);
}
$stmt = $conn->prepare($sql);
$types = str_repeat('s', count($params));
$stmt->bind_param($types, ...$params);
$stmt->execute();
return $stmt->get_result();
}
}
PHP;
$files['WEBROOT/src/MVC/Core/View.php'] = <<<'PHP'
<?php
namespace MVC\Core;
class View {
protected $data = [];
protected $viewPath;
public function __construct($viewPath) {
$this->viewPath = $viewPath;
}
public function assign($key, $value) {
$this->data[$key] = $value;
}
public function render($template) {
extract($this->data);
$file = $this->viewPath . '/' . $template . '.php';
if (file_exists($file)) {
ob_start();
include $file;
return ob_get_clean();
}
return "View $template not found at $file";
}
}
PHP;
$files['WEBROOT/src/MVC/Core/Router.php'] = <<<'PHP'
<?php
namespace MVC\Core;
class Router {
protected $routes = [];
protected $middlewares = [];
public function add($service, $controller, $method, $middlewares = []) {
$this->routes[$service] = [
'controller' => $controller,
'method' => $method,
'middlewares' => $middlewares
];
}
public function dispatch($service) {
if (!isset($this->routes[$service])) {
throw new \Exception("Service '$service' not found.");
}
$route = $this->routes[$service];
// Run Middlewares
foreach ($route['middlewares'] as $middleware) {
$this->runMiddleware($middleware);
}
$controllerClass = $route['controller'];
$method = $route['method'];
if (!class_exists($controllerClass)) {
throw new \Exception("Controller class '$controllerClass' not found.");
}
$controller = new $controllerClass();
if (!method_exists($controller, $method)) {
throw new \Exception("Method '$method' not found in controller '$controllerClass'.");
}
return $controller->$method();
}
protected function runMiddleware($middleware) {
if ($middleware === 'admin') {
if (!isset($_SESSION['is_admin']) || $_SESSION['is_admin'] !== true) {
die("Access Denied: Admin rights required.");
}
}
if ($middleware === 'auth') {
if (empty($_SESSION['user_logged_in'])) {
header('Location: login.php');
exit;
}
}
}
}
PHP;
$files['WEBROOT/src/MVC/Layout/Layout.php'] = <<<'PHP'
<?php
namespace MVC\Layout;
class Layout {
protected $blocks = [];
protected $template;
public function __construct($template = 'main') {
$this->template = $template;
}
public function setBlock($name, $content) {
$this->blocks[$name] = $content;
}
public function getBlock($name) {
return $this->blocks[$name] ?? '';
}
public function render() {
$layoutFile = __DIR__ . '/Templates/' . $this->template . '.php';
if (file_exists($layoutFile)) {
ob_start();
include $layoutFile;
return ob_get_clean();
}
return "Layout template nicht gefunden.";
}
}
PHP;
$files['WEBROOT/src/MVC/autoloader.php'] = <<<'PHP'
<?php
spl_autoload_register(function ($class) {
$prefix = 'MVC\\';
$base_dir = __DIR__ . '/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php';
if (file_exists($file)) {
require $file;
}
});
PHP;
// --- LAYOUT TEMPLATE ---
$files['WEBROOT/src/MVC/Layout/Templates/main.php'] = <<<'HTML'
<!DOCTYPE html>
<html lang="de" class="<?= ($_SESSION['theme'] ?? 'light') === 'dark' ? 'dark-mode' : '' ?>">
<head>
<meta charset="UTF-8">
<title><?= $this->getBlock('title') ?></title>
<style>
:root { --bg: #ffffff; --text: #333; --sidebar: #f4f4f4; --header: #007bff; --accent: #007bff; --border: #ddd; }
.dark-mode { --bg: #1a1a1a; --text: #f4f4f4; --sidebar: #252525; --header: #111; --accent: #3498db; --border: #333; }
body { font-family: 'Segoe UI', sans-serif; margin: 0; background: var(--bg); color: var(--text); transition: 0.3s; height: 100vh; overflow: hidden; display: flex; flex-direction: column; }
.main-header { height: 60px; background: var(--header); color: white; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); z-index: 10; }
.main-container { flex: 1; display: flex; overflow: hidden; }
.sidebar { width: 260px; background: var(--sidebar); padding: 20px; border-right: 1px solid var(--border); overflow-y: auto; }
.content { flex: 1; padding: 40px; overflow-y: auto; }
.btn-toggle { padding: 8px 15px; border: 1px solid rgba(255,255,255,0.3); border-radius: 5px; cursor: pointer; background: transparent; color: white; font-size: 0.9rem; }
.btn-toggle:hover { background: rgba(255,255,255,0.1); }
nav a { display: block; padding: 12px; text-decoration: none; color: inherit; border-radius: 5px; margin-bottom: 5px; }
nav a:hover { background: rgba(0,0,0,0.05); }
nav a.active { background: rgba(0,0,0,0.05); }
.logo { font-size: 1.4rem; font-weight: bold; }
</style>
</head>
<body>
<header class="main-header">
<div class="logo"><?= $this->getBlock('header_title') ?></div>
<div class="header-actions">
<?= $this->getBlock('header_actions') ?>
</div>
</header>
<div class="main-container">
<div class="sidebar">
<?= $this->getBlock('sidebar') ?>
</div>
<div class="content">
<?= $this->getBlock('content') ?>
</div>
</div>
<script>
function toggleTheme() { fetch('?service=toggle_theme').then(() => location.reload()); }
</script>
</body>
</html>
HTML;
// --- CONTROLLERS ---
$files['WEBROOT/src/MVC/Controller/ApiController.php'] = <<<'PHP'
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Classes\Api;
class ApiController extends Controller {
public static function get(){
return Api::jsonResponse([
'data' => 'DummyData',
]);
}
}
PHP;
$files['WEBROOT/src/MVC/Controller/HomeController.php'] = <<<'PHP'
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Classes\Client;
use MVC\Classes\Cookie;
use MVC\Classes\Request;
use MVC\Classes\Server;
class HomeController extends Controller {
public function index() {
return $this->render('home');
}
public function toggle_theme() {
$_SESSION['theme'] = ($_SESSION['theme'] ?? 'light') === 'dark' ? 'light' : 'dark';
return $this->json(
[
'success' => true
]
);
}
}
PHP;
$files['WEBROOT/src/MVC/Controller/TestController.php'] = <<<'PHP'
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Classes\Client;
use MVC\Classes\Cookie;
use MVC\Classes\Request;
use MVC\Classes\Server;
class TestController extends Controller {
public function service1() {
return $this->render(
'test1',
[
'msg' => 'Service 1 ist bereit!'
]
);
}
public function service2() {
return $this->render(
'test2',
[
'data' =>
[
'Layout' => 'Header + Sidebar',
'Theme' => 'Auto-Toggle'
]
]
);
}
}
PHP;
// --- API ---
$files['WEBROOT/api/v1/get.php'] = <<<'PHP'
<?php
header('Content-Type: application/json');
require_once __DIR__ . '/../../src/MVC/autoloader.php';
use MVC\Controller\ApiController;
$api = (new ApiController());
try {
echo ($api->get());
} catch (\Exception $e) {
echo ($e->getMessage());
}
PHP;
// --- VIEWS ---
$files['WEBROOT/src/MVC/View/home.php'] = "<h1>Dashboard</h1><p>Willkommen in deinem neuen MVC-System mit integriertem Header.</p>";
$files['WEBROOT/src/MVC/View/test1.php'] = "<h1>Service 1</h1><p><?= \$msg ?></p>";
$files['WEBROOT/src/MVC/View/test2.php'] = "<h1>System Check</h1><ul><?php foreach(\$data as \$k => \$v): ?><li><b><?= \$k ?>:</b> <?= \$v ?></li><?php endforeach; ?></ul>";
// --- ENTRY POINT ---
$files['WEBROOT/index.php'] = <<<'PHP'
<?php
session_start();
require_once __DIR__ . '/src/MVC/autoloader.php';
$service = $_GET['service'] ?? 'home';
try {
$router = new \MVC\Core\Router();
$router->add('home', \MVC\Controller\HomeController::class, 'index');
$router->add('toggle_theme', \MVC\Controller\HomeController::class, 'toggle_theme');
$router->add('test1', \MVC\Controller\TestController::class, 'service1');
$router->add('test2', \MVC\Controller\TestController::class, 'service2');
$layout = new \MVC\Layout\Layout('main');
$layout->setBlock('title', 'MVC Starter');
$layout->setBlock('header_title', '🚀 MVC Dashboard');
$layout->setBlock('header_actions', '<button class="btn-toggle" onclick="toggleTheme()">🌓 Theme umschalten</button>');
// Sidebar Block
ob_start();
$navItems = [
'home' => '🏠 Home',
'test1' => '🛠️Test 1',
'test2' => '📊 Test 2',
];
?>
<nav>
<?php foreach ($navItems as $navKey => $navLabel): ?>
<a href="?service=<?= $navKey ?>" class="<?= $service === $navKey ? 'active' : '' ?>"><?= $navLabel ?></a>
<?php endforeach; ?>
</nav>
<?php
$layout->setBlock('sidebar', ob_get_clean());
$layout->setBlock('content', $router->dispatch($service));
echo $layout->render();
} catch (\Exception $e) {
http_response_code(404); echo "<h1>404</h1><p>" . $e->getMessage() . "</p>";
}
PHP;
// --- GENERATOR: create_model.php ---
$files['create_model.php'] = <<<'PHP'
<?php
/**
* MVC Model Generator
* Nutzung: php create_model.php <TabellenName> <Spalte1,Spalte2,...>
*/
if (php_sapi_name() !== 'cli') {
die("Dieses Script muss über die CLI ausgeführt werden.\n");
}
$tableName = $argv[1] ?? null;
$columnsInput = $argv[2] ?? null;
// Interaktive Abfrage, falls Argumente fehlen
if (!$tableName) {
echo "Tabellenname eingeben (z.B. Benutzer): ";
$handle = fopen("php://stdin", "r");
$tableName = trim(fgets($handle));
fclose($handle);
}
if (!$columnsInput) {
echo "Spalten kommagetrennt eingeben (z.B. NAME,EMAIL,ROLLE): ";
$handle = fopen("php://stdin", "r");
$columnsInput = trim(fgets($handle));
fclose($handle);
}
if (!$tableName) die("Fehler: Kein Tabellenname angegeben.\n");
// Namen formatieren
$className = str_replace(' ', '', ucwords(str_replace('_', ' ', strtolower($tableName))));
$modelFile = __DIR__ . "/WEBROOT/src/MVC/Model/{$className}.php";
// Spalten aufbereiten
$columns = array_map('trim', explode(',', $columnsInput));
$columnList = implode("', '", $columns);
// Model-Inhalt generieren
$content = <<<PHPMODEL
<?php
namespace MVC\Model;
use MVC\Core\Model;
/**
* Model für die Tabelle '{$tableName}'
* Verfügbare Spalten: '{$columnList}'
*/
class {$className} extends Model {
protected static \$table = "{$tableName}";
// Hier kannst du spezifische Methoden für dieses Model hinzufügen
/**
* Beispiel: Suche nach einer spezifischen Spalte
*/
public static function getByFirstColumn(\$value) {
return self::where("{$columns[0]} = ?", \$value);
}
}
PHPMODEL;
// Datei schreiben
if (!is_dir(dirname($modelFile))) {
mkdir(dirname($modelFile), 0755, true);
}
if (!file_exists($modelFile)) {
file_put_contents($modelFile, $content);
echo "✅ Model erstellt: WEBROOT/src/MVC/Model/{$className}.php\n";
echo "--- INFO ---\n";
echo "Tabelle: {$tableName}\n";
echo "Klasse: MVC\\Model\\{$className}\n";
echo "Spalten: " . implode(', ', $columns) . "\n";
} else {
echo "⚠️ Model {$className}.php existiert bereits.\n";
}
PHP;
// --- GENERATOR: create_module.php ---
$files['create_module.php'] = <<<'PHP'
<?php
/**
* MVC Module Generator for Gemini CLI Project
* Nutzung: php create_module.php <name>
*/
if (php_sapi_name() !== 'cli') {
die("Dieses Script kann nur über die Kommandozeile ausgeführt werden.\n");
}
$name = $argv[1] ?? null;
if (!$name) {
echo "Bitte gib einen Namen für das Modul an (z.B. mein_projekt): ";
$handle = fopen("php://stdin", "r");
$name = trim(fgets($handle));
fclose($handle);
}
if (!$name) {
die("Fehler: Kein Name angegeben.\n");
}
// Namen formatieren
$key = strtolower(str_replace(' ', '_', $name));
$className = str_replace(' ', '', ucwords(str_replace('_', ' ', $key)));
$controllerFile = __DIR__ . "/WEBROOT/src/MVC/Controller/{$className}Controller.php";
$viewFile = __DIR__ . "/WEBROOT/src/MVC/View/{$key}.php";
// 1. Controller erstellen
$controllerContent = <<<PHPCTRL
<?php
namespace MVC\Controller;
use MVC\Core\Controller;
use MVC\Classes\Client;
use MVC\Classes\Cookie;
use MVC\Classes\Request;
use MVC\Classes\Server;
// use MVC\Model\YourModel; // Importiere dein Model
class {$className}Controller extends Controller {
public function {$key}() {
// Nutze Models für den Datenbankzugriff
// \$data = YourModel::all();
return \$this->render('{$key}', [
'title' => '{$className} Modul',
'message' => 'Willkommen in deinem neuen Modul {$className}!'
]);
}
}
PHPCTRL;
if (!file_exists($controllerFile)) {
file_put_contents($controllerFile, $controllerContent);
echo "✅ Controller erstellt: WEBROOT/src/MVC/Controller/{$className}Controller.php\n";
} else {
echo "⚠️ Controller existiert bereits.\n";
}
// 2. View erstellen
$viewContent = <<<HTML
<h2><?= htmlspecialchars(\$title) ?></h2>
<div class="card">
<p><?= htmlspecialchars(\$message) ?></p>
<p>Hier kannst du nun dein Projekt aufbauen.</p>
</div>
<style>
.card {
background: var(--card-bg);
padding: 20px;
border-radius: 8px;
border: 1px solid var(--card-border);
}
</style>
HTML;
if (!file_exists($viewFile)) {
file_put_contents($viewFile, $viewContent);
echo "✅ View erstellt: WEBROOT/src/MVC/View/{$key}.php\n";
} else {
echo "⚠️ View existiert bereits.\n";
}
// 3. Anleitung ausgeben
echo "\n--- NÄCHSTE SCHRITTE ---\n";
echo "1. Registriere das Modul in WEBROOT/index.php beim Router:\n";
echo " \$router->add('{$key}', \\MVC\\Controller\\{$className}Controller::class, '{$key}', ['auth']);\n\n";
echo "2. Füge den Service in der Seitenverwaltung (Admin) oder in config.php hinzu:\n";
echo " ID: {$key}\n";
echo " Name: " . ucfirst($name) . "\n";
echo "------------------------\n";
PHP;
// 3. Dateien schreiben
foreach ($files as $file => $content) {
$path = $baseDir . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $file);
file_put_contents($path, $content);
echo "📄 Datei erstellt: $file\n";
}
echo "\n✨ Projekt '$projectName' wurde mit HEADER initialisiert!\n";
echo "1. Starten: php server.php\n";
echo "2. Öffnen: http://localhost:8000\n";