presseportale/app/Console/Commands/SeedCategoryDescriptions.php
Kevin Adametz 84ea617107 web: Jahresarchiv je Branche, Kategoriebeschreibungen, Portalname im Titel (Roadmap 2.3)
- /de/category/{slug}/archiv/{jahr} (CategoryArchivePageData,
  CategoryArchiveController, View kategorie-archiv): 30 Meldungen je
  Seite, neueste zuerst, Jahresleiste mit Zahlen; ohne Jahr das juengste
  Jahr mit Meldungen. Canonical mit ?page=N auf Folgeseiten, hreflang
  nur auf Seite 1, CollectionPage + BreadcrumbList. Gecacht bis Seite 3.
  Leere Jahre, unbekannte Kategorien, leere Folgeseiten: 404.
- Branchenseite: Jahresleiste unter dem Feed (archiveYears, eine
  gruppierte Query); Sitemap listet alle Jahresarchive.
- categories:seed-descriptions {--dry-run} {--force}: fuellt leere DE/EN
  Beschreibungen aus database/seeders/data/category-descriptions.php
  (14 Kategorien, sachlich, ohne Werbeaussagen), leert den Seiten-Cache.
- Branchenseite: Titel trug config('app.name') ("– pressekonto") statt
  des Portalnamens — jetzt presseecho/businessportal24.
- Protokoll Teil 5 (2.3 mit Befund: 0 von 14 Beschreibungen, Sonstiges =
  28 % des Bestands), Roadmap 2.3 abgehakt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-17 10:25:29 +00:00

83 lines
2.8 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Category;
use App\Models\CategoryTranslation;
use App\Support\WebPageCache;
use Illuminate\Console\Command;
/**
* Beschreibungen der Branchenseiten einspielen (Roadmap 2.3). Ohne eigene
* Beschreibung zeigen alle Branchenseiten denselben Standardsatz — für
* Suchmaschinen 14 gleich aussehende Seiten. Texte liegen in
* database/seeders/data/category-descriptions.php, Schlüssel ist der
* DE-Slug. Nur leere Felder werden gefüllt; --force überschreibt.
*/
class SeedCategoryDescriptions extends Command
{
protected $signature = 'categories:seed-descriptions
{--dry-run : Nur zeigen, was geschrieben würde}
{--force : Auch vorhandene Beschreibungen überschreiben}';
protected $description = 'Füllt leere Kategoriebeschreibungen (DE/EN) aus database/seeders/data/category-descriptions.php.';
public function handle(): int
{
/** @var array<string, array<string, string>> $texts */
$texts = require database_path('seeders/data/category-descriptions.php');
$rows = [];
$written = 0;
foreach ($texts as $slug => $byLocale) {
$category = Category::query()
->whereHas('translations', fn ($query) => $query->where('locale', 'de')->where('slug', $slug))
->with('translations')
->first();
if (! $category) {
$rows[] = [$slug, '—', 'Kategorie nicht gefunden'];
continue;
}
foreach ($byLocale as $locale => $text) {
/** @var CategoryTranslation|null $translation */
$translation = $category->translations->firstWhere('locale', $locale);
if (! $translation) {
$rows[] = [$slug, $locale, 'keine Übersetzung'];
continue;
}
if (filled($translation->description) && ! $this->option('force')) {
$rows[] = [$slug, $locale, 'bereits vorhanden, übersprungen'];
continue;
}
$rows[] = [$slug, $locale, mb_strimwidth($text, 0, 60, '…')];
if (! $this->option('dry-run')) {
$translation->forceFill(['description' => $text])->save();
$written++;
}
}
}
$this->table(['Kategorie', 'Sprache', 'Ergebnis'], $rows);
if ($this->option('dry-run')) {
$this->info('[Dry-Run] Nichts geschrieben.');
return self::SUCCESS;
}
WebPageCache::flush();
$this->info(sprintf('%d Beschreibungen geschrieben, Seiten-Cache geleert.', $written));
return self::SUCCESS;
}
}