Umsetzung von AP0-AP6 aus dev/2026-08-28/entwicklungsplan.md sowie der vorab gefundenen Befunde T1 und B1-B13. Befunde - CmsContentSeeder überschrieb bei jedem Lauf alle redaktionellen Inhalte; jetzt Redaktionsschutz plus gezielter Relaunch-Seeder (B1) - Magazin-CMS war nicht ans Frontend angebunden, Artikel jetzt über Slugs mit 301 von den alten numerischen URLs (B2) - Vier veröffentlichte Display-Playlists zeigten auf b2in.test und wären live nicht ladbar gewesen (B13) - Info-Tablet speicherte geleerte Öffnungszeiten nicht (T1) - /service und /portfolio lieferten seit Februar 500 (B12) Website - Startseite neu strukturiert und umgetextet, eigene Seite /marken mit Detailseite je Kernmarke, /netzwerk und Altrouten leiten dorthin - Galerie je Marke, getrennt nach realisierten Projekten und Visualisierungen; ohne gesetzte Kategorie gilt ein Bild als Entwurf - Seite /referenzen, gespeist aus den Markengalerien - Showroom-Display im 9:16-Rahmen über eine schreibgeschützte Embed-Route ohne Preview-Token - Terminanfrage-Widget auf allen Seiten, Markenauswahl aus dem CMS, WhatsApp per Klick-zum-Chat-Link mit vorbereitetem Text - FAQ, Über-uns, Kontakt und Magazin inhaltlich auf Interior umgestellt Sonstiges - Vorschau-Instanzen liefern noindex und verlinken sich bei unbekanntem Host auf sich selbst statt auf eine fremde Domain - Seeder-Zugangsdaten aus dem Code in die Konfiguration (B8) - Ablauf für die Vorschau: dev/2026-08-28/preview-deployment.md 833 Tests grün (3084 Assertions), Pint sauber. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
77 lines
2.5 KiB
PHP
77 lines
2.5 KiB
PHP
<?php
|
||
|
||
namespace Database\Seeders;
|
||
|
||
use App\Models\DisplayVersion;
|
||
use App\Models\DisplayVersionItem;
|
||
use Illuminate\Database\Seeder;
|
||
|
||
/**
|
||
* Macht die im Display-CMS gespeicherten Medien-URLs host-unabhängig.
|
||
*
|
||
* Problem: Bilder, Videos und QR-Codes lagen als absolute URLs mit fest verdrahtetem Host in
|
||
* den Moduleinstellungen und Item-Inhalten – teils `b2in.test` (lokale Entwicklungsdomain),
|
||
* teils `b2in.eu`. Der Player gibt absolute URLs unverändert zurück, deshalb lädt ein auf
|
||
* `b2in.test` verweisendes Medium auf dem Live-Display nicht (und umgekehrt).
|
||
*
|
||
* Relative Pfade löst der Player über `resolveDisplayUrl()` gegen die Portal-Basis auf und
|
||
* funktionieren damit auf beiden Systemen. Umgeschrieben wird deshalb Host + Schema zu einem
|
||
* reinen Pfad.
|
||
*
|
||
* Bewusst **nicht** angefasst: Ziel-Links wie Footer-URL oder QR-Ziel (z. B.
|
||
* `cabinet-bielefeld.de`) – die müssen absolut bleiben. Der Filter greift nur bei einem
|
||
* B2in-Host **und** einem Pfad unterhalb von /storage/.
|
||
*
|
||
* php artisan db:seed --class=DisplayMediaUrlNormalizerSeeder
|
||
*/
|
||
class DisplayMediaUrlNormalizerSeeder extends Seeder
|
||
{
|
||
private const ASSET_URL_PATTERN = '#^https?://(?:[a-z0-9-]+\.)*b2in\.(?:test|eu|de)(/storage/[^\s"]*)$#i';
|
||
|
||
private int $rewritten = 0;
|
||
|
||
public function run(): void
|
||
{
|
||
foreach (DisplayVersion::all() as $module) {
|
||
$settings = $this->normalize($module->settings ?? []);
|
||
|
||
if ($settings !== ($module->settings ?? [])) {
|
||
$module->settings = $settings;
|
||
$module->save();
|
||
}
|
||
}
|
||
|
||
foreach (DisplayVersionItem::all() as $item) {
|
||
$content = $this->normalize($item->content ?? []);
|
||
|
||
if ($content !== ($item->content ?? [])) {
|
||
$item->content = $content;
|
||
$item->save();
|
||
}
|
||
}
|
||
|
||
$this->command?->info("Display-Medien-URLs host-unabhängig gemacht: {$this->rewritten} Verweise.");
|
||
}
|
||
|
||
/**
|
||
* @param array<mixed> $value
|
||
* @return array<mixed>
|
||
*/
|
||
private function normalize(array $value): array
|
||
{
|
||
foreach ($value as $key => $entry) {
|
||
if (is_array($entry)) {
|
||
$value[$key] = $this->normalize($entry);
|
||
|
||
continue;
|
||
}
|
||
|
||
if (is_string($entry) && preg_match(self::ASSET_URL_PATTERN, $entry, $matches) === 1) {
|
||
$value[$key] = $matches[1];
|
||
$this->rewritten++;
|
||
}
|
||
}
|
||
|
||
return $value;
|
||
}
|
||
}
|