b2in/database/seeders/UnusedCmsContentCleanupSeeder.php
Kevin Adametz fcb10be120 Interior-Feinschliff: Hero-Slideshow, Lektorat, Rechtstexte, Aufräumen und Korrekturen 08.10.
Startseite und Heroes
- Hero-Slideshow (11 Motive inkl. Febrü) mit Infokarte, Laufzeit-Linie, größeren Klickflächen,
  Goldrahmen und mobiler Karte unter dem Bild; Zeile über der Überschrift, neue Vertrauenspunkte
- Hero-Stil auf Marken, Über uns und Kontakt übertragen, Breadcrumb entfernt
- Gründer-Leiste, Vision-Box auf Ocker, Showroom-Display in Box mit „Größer ansehen“/Vollbild
- Akzentfarbe #a8741f, größere Serif-Überschriften in der Interior-Welt
- Marken: Bildpause mit Zitat; Vereine aktualisiert und verlinkt

Inhalte
- Lektorat aller angezeigten Texte, /about-Korrekturen, Rechtstexte (DDG, TDDDG, Hosting Hetzner)
- Ablauf Maßanfertigung überall einheitlich, Magazin-Beitrag neu, alte Beiträge offline,
  deutsches Datum/Lesezeit, FAQ Projektausstattung, Otterpohl
- Referenzen-Seite per CMS-Schalter ausblendbar

CMS und Technik
- Tote Sektionen, Felder, Seiten und Komponenten entfernt und archiviert (dev/2026-08-28/archiv-*)
- Entwurf /entwurf, Farb-Schalter und /welcome entfernt; Test-Routen nur noch lokal
- Seitenbaum-Beschreibungen geprüft, fehlende CMS-Felder ergänzt, Markenliste aus „Kernmarken“
- Admin-Bildvorschauen repariert, verwendete Bilder in die Mediathek übernommen
- Seeder für das Deployment siehe dev/2026-08-28/entwicklungsplan.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-08 14:00:15 +00:00

179 lines
6.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace Database\Seeders;
use FluxCms\Core\Models\CmsContent;
use FluxCms\Core\Services\CmsContentService;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Storage;
/**
* Räumt das CMS auf (Nachtrag 22, 06.10.2026): Sektionen, die keine erreichbare Seite mehr
* anzeigt, werden gelöscht – die alten Seiten Netzwerk, Partner, Ecosystem und Interior
* (leiten auf /marken um), die frühere Immobilien-Seite, die Startseiten-Blöcke vor dem
* Interior-Relaunch und das Führungsteam. Seit 07.10.2026 auch der Hero des alten Entwurfs
* (`home.hero_slider`, Seite /entwurf).
*
* Vor dem Löschen schreibt der Seeder die betroffenen Einträge vollständig (beide Sprachen)
* nach storage/app/private/cms-archiv/cms-content-geloescht-{Zeitstempel}.json (Disk „local“). Außerdem:
* - „Abschluss auf Über uns“ zieht von netzwerk/partner_cta nach about/partner_cta – die
* Gruppe „netzwerk“ gibt es danach nicht mehr.
* - Felder, die keine Vorlage ausgibt, fallen aus den betroffenen Sektionen heraus
* ({@see self::UNUSED_FIELDS}) – etwa die Kennzahlen im Abschluss der Über-uns-Seite.
*
* Mehrfaches Ausführen ist unbedenklich.
*
* php artisan db:seed --class=UnusedCmsContentCleanupSeeder
*/
class UnusedCmsContentCleanupSeeder extends Seeder
{
/** @var list<string> Gruppe.Schlüssel der toten Sektionen */
public const UNUSED = [
'about.leadership_team',
'home.brand_worlds', 'home.ecosystem_core', 'home.hero_slider', 'home.integriertes_modell_b2in', 'home.synergie_section',
'immobilien.bruecke', 'immobilien.hero', 'immobilien.hero_v2', 'immobilien.image_break', 'immobilien.kaufprozess',
'immobilien.mindset', 'immobilien.moebel_vorteil', 'immobilien.portfolio', 'immobilien.projects_meta',
'immobilien.trust', 'immobilien.warum_dubai',
'global.cta_section_portfolio',
'netzwerk.broker_section', 'netzwerk.cabinet_partner', 'netzwerk.commitment_section', 'netzwerk.cta',
'netzwerk.dark_stats_section', 'netzwerk.digital_core', 'netzwerk.ecosystem_hero', 'netzwerk.ecosystem_hub',
'netzwerk.ecosystem_result', 'netzwerk.ecosystem_start', 'netzwerk.ecosystem_stats', 'netzwerk.end_customer_section',
'netzwerk.final_commitment', 'netzwerk.hero', 'netzwerk.image_break', 'netzwerk.immobilien_hint',
'netzwerk.interior_brands', 'netzwerk.interior_concept', 'netzwerk.interior_hero', 'netzwerk.interior_process',
'netzwerk.interior_trust', 'netzwerk.interior_zielgruppen', 'netzwerk.partner_benefits',
'netzwerk.partner_benefits_broker', 'netzwerk.partner_benefits_developer', 'netzwerk.partner_benefits_retailer',
'netzwerk.partner_benefits_supplier', 'netzwerk.partner_card_section', 'netzwerk.partner_hero',
'netzwerk.partner_process', 'netzwerk.supplier_section', 'netzwerk.supply_chain_intro', 'netzwerk.teasers',
];
/** @var array<string, list<string>> Gruppe.Schlüssel → Felder, die keine Vorlage ausgibt */
public const UNUSED_FIELDS = [
'about.partner_cta' => ['stats'],
'contact.contact_form' => ['social_media'],
'magazin.list' => ['load_more'],
'immobilien.magazin_list' => ['load_more'],
'magazin.detail' => ['share_article'],
// Kacheln kommen aus der Markenverwaltung; die Liste war im CMS ohne Wirkung (07.10.2026).
'home.core_brands' => ['brands'],
];
public function run(): void
{
$moved = $this->movePartnerCta();
$stripped = $this->stripUnusedFields();
if ($stripped > 0) {
$this->command?->info("CMS-Aufräumen: ungenutzte Felder aus {$stripped} Sektion(en) entfernt.");
}
$rows = $this->unusedRows();
if ($rows === []) {
$this->command?->info('CMS-Aufräumen: keine toten Sektionen (mehr) vorhanden'.($moved ? ', partner_cta verschoben.' : '.'));
return;
}
$path = 'cms-archiv/cms-content-geloescht-'.now()->format('Y-m-d_His').'.json';
Storage::disk('local')->put($path, json_encode(
array_map(fn (CmsContent $row) => [
'group' => $row->group,
'key' => $row->key,
'type' => $row->type,
'order' => $row->order,
'value' => $row->getTranslations('value'),
], $rows),
JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES,
));
$groups = [];
foreach ($rows as $row) {
$groups[$row->group] = true;
$row->delete();
}
foreach (array_keys($groups) as $group) {
app(CmsContentService::class)->clearCache($group);
}
$this->command?->info(sprintf(
'CMS-Aufräumen: %d tote Sektionen gelöscht, Sicherung unter %s%s',
count($rows),
Storage::disk('local')->path($path),
$moved ? ', partner_cta nach „about“ verschoben.' : '.',
));
}
/**
* @return list<CmsContent>
*/
private function unusedRows(): array
{
return CmsContent::query()->get()
->filter(fn (CmsContent $row) => in_array($row->group.'.'.$row->key, self::UNUSED, true))
->values()
->all();
}
/**
* Zieht den Abschluss der Über-uns-Seite in die Gruppe „about“.
*/
private function movePartnerCta(): bool
{
$old = CmsContent::query()->where('group', 'netzwerk')->where('key', 'partner_cta')->first();
$current = CmsContent::query()->where('group', 'about')->where('key', 'partner_cta')->first();
$changed = false;
if ($old && ! $current) {
$old->group = 'about';
$old->save();
$current = $old;
$changed = true;
} elseif ($old) {
$old->delete();
$changed = true;
}
if ($changed) {
app(CmsContentService::class)->clearCache('netzwerk');
app(CmsContentService::class)->clearCache('about');
}
return $changed;
}
/**
* Entfernt die Felder aus {@see self::UNUSED_FIELDS} in allen Sprachen.
*/
private function stripUnusedFields(): int
{
$count = 0;
foreach (self::UNUSED_FIELDS as $section => $fields) {
[$group, $key] = explode('.', $section, 2);
$row = CmsContent::query()->where('group', $group)->where('key', $key)->first();
if (! $row) {
continue;
}
$value = $row->getTranslations('value');
$stripped = array_map(
fn ($content) => is_array($content) ? array_diff_key($content, array_flip($fields)) : $content,
$value,
);
if ($stripped === $value) {
continue;
}
$row->value = $stripped;
$row->save();
app(CmsContentService::class)->clearCache($group);
$count++;
}
return $count;
}
}