presseportale/app/Enums/PressReleasePlaceholder.php
Kevin Adametz a000238ca8 User Panel: Phase-8-Abschluss, Titelbild/Lizenzen/Zeitzonen und KI-Pruef-Pipeline
Phase 8 (Rest) + Umbauten vom 10./11.06.:
- Ein Titelbild pro PM (Cover 1280x580), SVG-Platzhalter-Set + Picker,
  PressReleaseCoverImage-Resolver
- Lizenz-/Rechteformular nach "Lizenztyp Bildupload" (7 Lizenztypen,
  Personen-/Sachrechte-Status, bedingte Pflichtfelder, Risikohinweise)
- Veroeffentlichungs-Box vereinfacht (Embargo aus der Form-UI entfernt),
  geplante Termine in Europe/Berlin (Speicherung UTC, DISPLAY_TIMEZONE)
- Quota-Stub (users.press_release_quota) + monatlicher Reset-Command
- Einreichungs-Modal einheitlich in Show/Create/Edit; Ghost-Buttons auf
  filled; PM-Editor-Layout responsive entkoppelt (.pr-editor-layout)

KI-Pruef-Pipeline (Phasen 1-5 des Entwicklungsplans):
- API-Haertung: status nicht mehr per API setzbar, eigene Submit-Route
  durch denselben Funnel (Blacklist, Quota, Status-Log)
- Klassifikation Rot/Gelb/Gruen asynchron (Queue classification,
  OpenAI-Treiber + deterministischer Fallback), ki_audits-Audit-Log
- Routing: Rot -> rejected + Mail, Gelb -> Review-Queue, Gruen ->
  Auto-Publish; Scheduler publiziert nur gruene faellige PMs
- Content-Score 0-100 -> Stufe (Standard/Geprueft/Hochwertig) inkl.
  Editor-Panel und Badges; Re-Klassifikation/-Score bei Aenderung
- Admin: KI-Badge + Filter, On-Demand-Pruefung mit Anbieter-Override

Suite: 442 passed, 4 skipped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 08:30:13 +00:00

90 lines
2.6 KiB
PHP

<?php
namespace App\Enums;
/**
* Wiederverwendbares Set farbiger SVG-Titelbild-Platzhalter für
* Pressemitteilungen ohne eigenes Bild.
*
* Die Werte entsprechen den Dateinamen in
* `public/images/press-release-placeholders/<value>.svg`.
*/
enum PressReleasePlaceholder: string
{
case GridBlue = '01-grid-blue';
case GridGreen = '02-grid-green';
case GridAmber = '03-grid-amber';
case LinesBlue = '04-lines-blue';
case LinesGreen = '05-lines-green';
case LinesAmber = '06-lines-amber';
case DotsBlue = '07-dots-blue';
case DotsGreen = '08-dots-green';
case DotsAmber = '09-dots-amber';
case WavesBlue = '10-waves-blue';
case WavesGreen = '11-waves-green';
case WavesAmber = '12-waves-amber';
case EditorialBlue = '13-editorial-blue';
case EditorialGreen = '14-editorial-green';
case EditorialAmber = '15-editorial-amber';
case SignalBlue = '16-signal-blue';
case SignalGreen = '17-signal-green';
case SignalAmber = '18-signal-amber';
/**
* Default-Variante, wenn nichts gesetzt ist.
*/
public static function default(): self
{
return self::GridBlue;
}
/**
* Liefert die Variante zu einem Roh-Wert oder den Default-Fallback.
*/
public static function fromValueOrDefault(?string $value): self
{
return self::tryFrom((string) $value) ?? self::default();
}
/**
* Deterministische Variante aus einem Seed (z. B. PM-ID/Titel), damit
* dieselbe PM immer denselben Platzhalter bekommt.
*/
public static function fromSeed(int|string $seed): self
{
$cases = self::cases();
return $cases[abs(crc32((string) $seed)) % count($cases)];
}
/**
* Öffentlicher Asset-Pfad relativ zu `public/`.
*/
public function path(): string
{
return 'images/press-release-placeholders/'.$this->value.'.svg';
}
/**
* Lesbares Label für die UI (Picker-Tooltips etc.).
*/
public function label(): string
{
$pattern = match (true) {
str_contains($this->value, 'grid') => 'Raster',
str_contains($this->value, 'lines') => 'Linien',
str_contains($this->value, 'dots') => 'Punkte',
str_contains($this->value, 'waves') => 'Wellen',
str_contains($this->value, 'editorial') => 'Editorial',
default => 'Signal',
};
$color = match (true) {
str_contains($this->value, 'blue') => 'Blau',
str_contains($this->value, 'green') => 'Grün',
default => 'Bernstein',
};
return $pattern.' · '.$color;
}
}