Files
Adminator 1e51ef7def Nachtrag: alle bisher untracked Ordner + hängende Änderungen mit-committen
- Konzept/, didaktik_geografie/, didaktik_simulation/, v2-modules/, v2-platform/
- 12 code-workspace-Files
- STATUS-*.md
- viele M/D/R-Änderungen an bereits getrackten Files
- .gitignore verstärkt: **/.humaninput/, **/secret_keys.txt

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-07-08 02:27:02 +02:00

69 lines
2.7 KiB
PHP

<?php
declare(strict_types=1);
/**
* Prüft CSS auf hardcodierte Hex-Farben.
* Erlaubt: var(--ggs-*) und var(--<slug>-*).
* Hex-Werte direkt im Code verboten (Kommentare werden ignoriert).
*
* Wir scannen .css- und .html-Files (für Inline-CSS).
*/
function check_css(string $dir, string $slug, Report $r): void {
$publicDir = "$dir/public";
if (!is_dir($publicDir)) {
$r->warn("public/ fehlt — CSS-Check übersprungen");
return;
}
$files = [];
$rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($publicDir, FilesystemIterator::SKIP_DOTS));
foreach ($rii as $file) {
if (!$file->isFile()) continue;
$ext = strtolower($file->getExtension());
if (in_array($ext, ['css', 'html'], true)) {
$files[] = $file->getPathname();
}
}
$totalHex = 0;
$violations = [];
foreach ($files as $f) {
$content = file_get_contents($f);
// Multi-Line-Kommentare /* ... */ entfernen (auch über Zeilen hinweg)
$content = preg_replace('/\/\*.*?\*\//s', '', $content);
$rel = str_replace($dir . DIRECTORY_SEPARATOR, '', $f);
$lines = preg_split('/\R/', $content);
foreach ($lines as $ln => $line) {
$trimmed = trim($line);
// Kommentar-Zeilen überspringen
if (str_starts_with($trimmed, '//') || str_starts_with($trimmed, '*')
|| str_starts_with($trimmed, '/*') || str_starts_with($trimmed, '<!--')) {
continue;
}
// Token-DEFINITIONEN erlauben: --xxx: #abc; (auch mehrere pro Zeile)
// Wir ersetzen die Token-Definitionen weg und prüfen den Rest.
$rest = preg_replace('/--[a-zA-Z0-9_-]+\s*:\s*#[0-9a-fA-F]{3,8}/', '', $line);
// Hex-Pattern auf dem Rest (= echte Verwendung, nicht Definition)
if (preg_match_all('/(?<![a-zA-Z0-9])#([0-9a-fA-F]{8}|[0-9a-fA-F]{6}|[0-9a-fA-F]{4}|[0-9a-fA-F]{3})\b/', $rest, $hits)) {
foreach ($hits[0] as $h) {
$totalHex++;
$violations[] = "$rel:" . ($ln + 1) . ": $h";
if (count($violations) >= 30) break 3;
}
}
}
}
if ($totalHex === 0) {
$r->ok("Keine hardcodierten Hex-Farben in public/ gefunden");
} else {
$r->fail("$totalHex hardcodierte Hex-Farben in public/ gefunden — bitte var(--ggs-*) oder var(--$slug-*) nutzen",
array_slice($violations, 0, 30));
if ($totalHex > 30) {
$r->note("... weitere " . ($totalHex - 30) . " weggekürzt");
}
$r->note("Falls Spezialfarben nötig (Wettersymbole, Heatmap): definiere --$slug-* CSS-Variablen lokal und beantrage Whitelist bei Atlas.");
}
}