chore: complete update
This commit is contained in:
27
src/Framework/Sitemap/SitemapEntry.php
Normal file
27
src/Framework/Sitemap/SitemapEntry.php
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Sitemap;
|
||||
|
||||
use DateTimeImmutable;
|
||||
|
||||
final readonly class SitemapEntry
|
||||
{
|
||||
public function __construct(
|
||||
public string $url,
|
||||
public DateTimeImmutable $lastmod,
|
||||
public string $changefreq = 'monthly',
|
||||
public float $priority = 0.5
|
||||
) {}
|
||||
|
||||
public function toXml(): string
|
||||
{
|
||||
return sprintf(
|
||||
'<url><loc>%s</loc><lastmod>%s</lastmod><changefreq>%s</changefreq><priority>%.1f</priority></url>',
|
||||
htmlspecialchars($this->url),
|
||||
$this->lastmod->format('Y-m-d'),
|
||||
$this->changefreq,
|
||||
$this->priority
|
||||
);
|
||||
}
|
||||
}
|
||||
100
src/Framework/Sitemap/SitemapGenerator.php
Normal file
100
src/Framework/Sitemap/SitemapGenerator.php
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Framework\Sitemap;
|
||||
|
||||
use App\Framework\Attributes\Singleton;
|
||||
use App\Framework\Core\Route;
|
||||
use App\Framework\Http\Method;
|
||||
use App\Framework\Router\RouteCollection;
|
||||
use App\Framework\Router\UrlGenerator;
|
||||
use Generator;
|
||||
|
||||
#[Singleton]
|
||||
final readonly class SitemapGenerator
|
||||
{
|
||||
public function __construct(
|
||||
private RouteCollection $routes,
|
||||
private UrlGenerator $urlGenerator
|
||||
) {}
|
||||
|
||||
/**
|
||||
* Generiert Sitemap-URLs aus allen verfügbaren Named Routes
|
||||
*
|
||||
* @return Generator<SitemapEntry>
|
||||
*/
|
||||
public function generateFromRoutes(): Generator
|
||||
{
|
||||
foreach ($this->getPublicRoutes() as $route) {
|
||||
if ($this->isStaticRoute($route)) {
|
||||
yield new SitemapEntry(
|
||||
url: $this->urlGenerator->absoluteRoute($route->name),
|
||||
lastmod: new \DateTimeImmutable(),
|
||||
changefreq: $this->determineChangeFreq($route),
|
||||
priority: $this->determinePriority($route)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Holt alle öffentlichen Named Routes
|
||||
*/
|
||||
private function getPublicRoutes(): Generator
|
||||
{
|
||||
// Hier müssen Sie eine Methode in RouteCollection hinzufügen
|
||||
foreach ($this->routes->getAllNamedRoutes() as $name => $route) {
|
||||
|
||||
// Nur GET-Routen für Sitemap: Named Routes sind aktuell immer nur Routes mit GET Methode
|
||||
if (/*$this->supportsMethod($route, Method::GET) &&*/
|
||||
!$this->isExcludedFromSitemap($route)) {
|
||||
yield $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function isStaticRoute(Route $route): bool
|
||||
{
|
||||
// Prüft ob Route keine Parameter benötigt
|
||||
return !str_contains($route->path, '{');
|
||||
}
|
||||
|
||||
private function supportsMethod(Route $route, Method $method): bool
|
||||
{
|
||||
return in_array($method->value, $route->method->value ?? [], true);
|
||||
}
|
||||
|
||||
private function isExcludedFromSitemap(Route $route): bool
|
||||
{
|
||||
// Admin/API-Routen ausschließen
|
||||
$excludePatterns = ['/admin', '/api', '/auth'];
|
||||
|
||||
foreach ($excludePatterns as $pattern) {
|
||||
if (str_starts_with($route->path, $pattern)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private function determineChangeFreq(Route $route): string
|
||||
{
|
||||
// Basierend auf Route-Name oder Pfad
|
||||
return match (true) {
|
||||
str_contains($route->path, '/blog') => 'weekly',
|
||||
str_contains($route->path, '/news') => 'daily',
|
||||
$route->name === 'home' => 'weekly',
|
||||
default => 'monthly'
|
||||
};
|
||||
}
|
||||
|
||||
private function determinePriority(Route $route): float
|
||||
{
|
||||
return match ($route->name) {
|
||||
'home' => 1.0,
|
||||
'about', 'contact' => 0.8,
|
||||
default => 0.5
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user