chore: complete update

This commit is contained in:
2025-07-17 16:24:20 +02:00
parent 899227b0a4
commit 64a7051137
1300 changed files with 85570 additions and 2756 deletions

View File

@@ -0,0 +1,30 @@
<?php
namespace App\Framework\StaticSite;
use App\Framework\Console\ConsoleCommand;
use App\Framework\Core\AppBootstrapper;
use App\Framework\Core\PathProvider;
use App\Framework\Http\Method;
use App\Framework\HttpClient\ClientRequest;
use App\Framework\HttpClient\CurlHttpClient;
use App\Framework\Performance\PerformanceMeter;
class GenerateStaticSites
{
private string $outputDirectory;
public function __construct(
private readonly PathProvider $pathProvider
)
{
$this->outputDirectory = $this->pathProvider->resolvePath('/public') . '/static';
}
#[ConsoleCommand('static:generate', 'Generiert statische Seiten')]
public function generate(): void
{
}
}

View File

@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace App\Framework\StaticSite;
use App\Framework\Router\HttpRouter;
use App\Framework\Router\Route;
use App\Framework\Router\RouteCollection;
class RouteCollector
{
private HttpRouter $router;
public function __construct(HttpRouter $router)
{
$this->router = $router;
}
/**
* Sammelt alle Routen aus dem Router
*
* @return array Liste aller Routen-Pfade
*/
public function collectRoutes(): array
{
$routes = [];
$routeCollection = $this->router->getRoutes();
if ($routeCollection instanceof RouteCollection) {
foreach ($routeCollection->getAll() as $route) {
if ($route instanceof Route) {
$path = $route->path;
// Nur GET-Routen für statische Seiten verwenden
if (in_array('GET', $route->methods)) {
$routes[] = $path;
}
}
}
}
return $routes;
}
/**
* Filtert die Routen nach bestimmten Kriterien
*
* @param array $routes Liste der Routen
* @param array $exclude Pfade, die ausgeschlossen werden sollen
* @return array Gefilterte Routen
*/
public function filterRoutes(array $routes, array $exclude = []): array
{
return array_filter($routes, function ($route) use ($exclude) {
// Prüfe, ob Route ausgeschlossen werden soll
foreach ($exclude as $pattern) {
if (preg_match($pattern, $route)) {
return false;
}
}
// Schließe Routen mit Platzhaltern aus (z.B. /users/{id})
if (strpos($route, '{') !== false && strpos($route, '}') !== false) {
return false;
}
return true;
});
}
}

View File

@@ -0,0 +1,106 @@
<?php
declare(strict_types=1);
namespace App\Framework\StaticSite;
use App\Framework\Attributes\StaticPage;
use App\Framework\Router\HttpRouter;
use App\Framework\Router\Route;
use App\Framework\Router\RouteCollection;
class StaticPageCollector
{
private HttpRouter $router;
public function __construct(HttpRouter $router)
{
$this->router = $router;
}
/**
* Sammelt alle Routen mit dem StaticPage-Attribut
*
* @return array Liste aller statischen Seitenrouten
*/
public function collectStaticPages(): array
{
$staticPages = [];
$routeCollection = $this->router->getRoutes();
if ($routeCollection instanceof RouteCollection) {
foreach ($routeCollection->getAll() as $route) {
if ($this->hasStaticPageAttribute($route->controller, $route->action)) {
$staticPages[] = $route->path;
}
}
}
return $staticPages;
}
/**
* Sammelt alle GET-Routen unabhängig vom StaticPage-Attribut
*
* @return array Liste aller GET-Routen
*/
public function collectAllGetRoutes(): array
{
$routes = [];
$routeCollection = $this->router->getRoutes();
if ($routeCollection instanceof RouteCollection) {
foreach ($routeCollection->getAll() as $route) {
if (in_array('GET', $route->methods)) {
$routes[] = $route->path;
}
}
}
return $routes;
}
/**
* Prüft, ob die Controller-Methode das StaticPage-Attribut hat
*/
private function hasStaticPageAttribute(string $controllerClass, string $methodName): bool
{
if (!class_exists($controllerClass) || !method_exists($controllerClass, $methodName)) {
return false;
}
try {
$reflectionMethod = new \ReflectionMethod($controllerClass, $methodName);
$attributes = $reflectionMethod->getAttributes(StaticPage::class);
return count($attributes) > 0;
} catch (\ReflectionException $e) {
return false;
}
}
/**
* Filtert die Routen nach bestimmten Kriterien
*
* @param array $routes Liste der Routen
* @param array $exclude Pfade, die ausgeschlossen werden sollen
* @return array Gefilterte Routen
*/
public function filterRoutes(array $routes, array $exclude = []): array
{
return array_filter($routes, function ($route) use ($exclude) {
// Prüfe, ob Route ausgeschlossen werden soll
foreach ($exclude as $pattern) {
if (preg_match($pattern, $route)) {
return false;
}
}
// Schließe Routen mit Platzhaltern aus (z.B. /users/{id})
if (strpos($route, '{') !== false && strpos($route, '}') !== false) {
return false;
}
return true;
});
}
}

View File

@@ -0,0 +1,107 @@
<?php
declare(strict_types=1);
namespace App\Framework\StaticSite;
use App\Framework\Core\Application;
use App\Framework\Http\Method;
use App\Framework\Http\HttpRequest;
use App\Framework\Http\Request;
use App\Framework\Http\Response;
class StaticSiteGenerator
{
private Application $app;
private string $outputDir;
private array $routesToGenerate;
public function __construct(Application $app, array $routesToGenerate = [], ?string $outputDir = null)
{
$this->app = $app;
$this->routesToGenerate = $routesToGenerate;
$this->outputDir = $outputDir ?? dirname(__DIR__, 2) . '/public/static';
}
public function generate(): void
{
$this->prepareOutputDirectory();
foreach ($this->routesToGenerate as $route) {
$this->generateRoute($route);
}
}
private function prepareOutputDirectory(): void
{
if (!file_exists($this->outputDir)) {
mkdir($this->outputDir, 0755, true);
}
}
private function generateRoute(string $route): void
{
// Erstelle eine simulierte Anfrage
$request = new HttpRequest(Method::GET, $route, [], [], []);
try {
// Führe die Anfrage aus und erhalte die Antwort
$response = $this->app->handleRequest($request);
// Generiere den Pfad für die Datei
$filePath = $this->getFilePathForRoute($route);
// Stelle sicher, dass das Verzeichnis existiert
$directory = dirname($filePath);
if (!file_exists($directory)) {
mkdir($directory, 0755, true);
}
// Schreibe den Inhalt in die Datei
file_put_contents($filePath, $response->getBody());
echo "Statische Seite generiert: {$route} -> {$filePath}\n";
} catch (\Exception $e) {
echo "Fehler beim Generieren von {$route}: {$e->getMessage()}\n";
}
}
private function getFilePathForRoute(string $route): string
{
// Bereinige Route
$route = trim($route, '/');
// Bestimme den Dateinamen
if (empty($route)) {
$filePath = $this->outputDir . '/index.html';
} else {
// Für /about, /contact, etc.
if (strpos($route, '.') === false) {
// Keine Dateiendung vorhanden, erstelle Verzeichnis mit index.html
$filePath = $this->outputDir . '/' . $route . '/index.html';
} else {
// Dateiendung vorhanden (z.B. .json, .xml)
$filePath = $this->outputDir . '/' . $route;
}
}
return $filePath;
}
public function setRoutesToGenerate(array $routes): self
{
$this->routesToGenerate = $routes;
return $this;
}
public function addRoute(string $route): self
{
$this->routesToGenerate[] = $route;
return $this;
}
public function setOutputDirectory(string $directory): self
{
$this->outputDir = $directory;
return $this;
}
}

View File

@@ -0,0 +1,26 @@
<?php
namespace App\Framework\StaticSite;
use App\Framework\Attributes\Route;
use App\Framework\Attributes\StaticPage;
use App\Framework\Core\AttributeMapper;
final readonly class StaticSiteMapper implements AttributeMapper
{
public function getAttributeClass(): string
{
return StaticPage::class;
}
public function map(object $reflectionTarget, object $attributeInstance): ?array
{
$route = $reflectionTarget->getAttributes(Route::class);
return [
'route' => $route[0]->newInstance()->path,
];
}
}