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>
179 lines
6.9 KiB
PHP
179 lines
6.9 KiB
PHP
<?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;
|
||
}
|
||
}
|