php bin/console cms:admin:path <neu> legt die Verwaltung auf eine andere Adresse. Geprueft wird, dass der Name frei ist und keine Seite verdeckt; der Wert steht in .env.local und fuellt einen Parameter, der als Praefix in jeder Verwaltungsroute steht, in der Firewall, in den Schutzkopfzeilen und in der Statistik. Die robots.txt nennt einen geaenderten Namen nicht - sie ist oeffentlich und waere sonst ein Wegweiser. Beim Standardnamen bleibt die Zeile, weil diese Adresse ohnehin jeder kennt. Die Auffangroute fuer Seiten steht jetzt zuletzt: sie kann einen frei gewaehlten Namen nicht per Regex ausschliessen, und die Reihenfolge ist ohnehin die richtige. Der Befehl raeumt den Zwischenspeicher auf, aber nicht den, in dem er selbst laeuft. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
97 lines
3.5 KiB
PHP
97 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Controller;
|
|
|
|
use App\Content\FontLibrary;
|
|
use App\Content\Theme;
|
|
use App\Domain\InvalidPage;
|
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
|
use Symfony\Component\HttpFoundation\Request;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
use Symfony\Component\Routing\Attribute\Route;
|
|
|
|
final class ThemeController extends AbstractController
|
|
{
|
|
public function __construct(private Theme $theme, private FontLibrary $fonts)
|
|
{
|
|
}
|
|
|
|
#[Route('/%kant.admin_path%/theme', name: 'admin_theme', methods: ['GET'])]
|
|
public function index(): Response
|
|
{
|
|
$theme = $this->theme->load();
|
|
|
|
return $this->render('admin/theme.html.twig', [
|
|
'theme' => $theme,
|
|
'fallbacks' => Theme::FALLBACKS,
|
|
'weights' => Theme::WEIGHTS,
|
|
'fontsLocal' => $this->fonts->hasLocal($theme),
|
|
'fontsMissing' => $this->fonts->missing($theme),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Holt die gewaehlten Google-Schriften auf den eigenen Server.
|
|
*
|
|
* Auf Zuruf, nicht bei einem Seitenaufruf: das dauert Sekunden und braucht eine Verbindung
|
|
* nach aussen, die ein Besucher nie abwarten soll.
|
|
*/
|
|
#[Route('/%kant.admin_path%/theme/fonts', name: 'admin_theme_fonts', methods: ['POST'])]
|
|
public function fonts(Request $request): Response
|
|
{
|
|
$this->denyAccessUnlessGranted('ROLE_EDITOR');
|
|
if (!$this->isCsrfTokenValid('theme', $request->request->getString('_csrf_token'))) {
|
|
$this->addFlash('error', 'Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.');
|
|
|
|
return $this->redirectToRoute('admin_theme');
|
|
}
|
|
try {
|
|
$result = $this->fonts->fetch($this->theme->load());
|
|
$this->addFlash('success', sprintf(
|
|
'%d Schriftdatei(en) geladen, %s insgesamt: %s. Die Website lädt jetzt nichts mehr von Google.',
|
|
$result['files'],
|
|
$this->bytes($result['bytes']),
|
|
implode(', ', $result['families']),
|
|
));
|
|
} catch (\RuntimeException $error) {
|
|
$this->addFlash('error', $error->getMessage());
|
|
}
|
|
|
|
return $this->redirectToRoute('admin_theme');
|
|
}
|
|
|
|
private function bytes(int $bytes): string
|
|
{
|
|
return $bytes < 1024 * 1024 ? round($bytes / 1024).' KB' : round($bytes / 1024 / 1024, 1).' MB';
|
|
}
|
|
|
|
#[Route('/%kant.admin_path%/theme/save', name: 'admin_theme_save', methods: ['POST'])]
|
|
public function save(Request $request): Response
|
|
{
|
|
$this->denyAccessUnlessGranted('ROLE_EDITOR');
|
|
if (!$this->isCsrfTokenValid('theme', $request->request->getString('_csrf_token'))) {
|
|
$this->addFlash('error', 'Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.');
|
|
|
|
return $this->redirectToRoute('admin_theme');
|
|
}
|
|
$fonts = [];
|
|
foreach ($request->request->all('fonts') as $row) {
|
|
if (!is_array($row)) {
|
|
continue;
|
|
}
|
|
$row['weights'] = array_map('intval', (array) ($row['weights'] ?? []));
|
|
$fonts[] = $row;
|
|
}
|
|
try {
|
|
$this->theme->save($request->request->all('colors'), $fonts, $request->request->all('base'));
|
|
} catch (InvalidPage $e) {
|
|
$this->addFlash('error', $e->getMessage());
|
|
|
|
return $this->redirectToRoute('admin_theme');
|
|
}
|
|
$this->addFlash('success', 'Das Design wurde gespeichert. Es gilt sofort auf allen Seiten.');
|
|
|
|
return $this->redirectToRoute('admin_theme');
|
|
}
|
|
}
|