companies:merges --batch= zeigt je Vorgang Überlebenden, Newsroom-URLs auf beiden Portalen, aufgegangene Firmen und deren alte URLs (301). Der scharfe Lauf gibt die ersten 30 Vorgänge jetzt ebenfalls als Tabelle aus. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
115 lines
4.7 KiB
PHP
115 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Enums\CompanyMergeSubject;
|
|
use App\Enums\Portal;
|
|
use App\Models\Company;
|
|
use App\Models\CompanyMerge;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Support\Str;
|
|
|
|
/**
|
|
* Zeigt, was eine Zusammenführung (Roadmap 1a.3) getan hat — je Vorgang der
|
|
* Überlebende, die aufgegangenen Firmen und die URLs zum Nachprüfen: der
|
|
* Newsroom auf beiden Portalen, die alten Slugs, die per 301 weiterführen.
|
|
*/
|
|
class ListCompanyMerges extends Command
|
|
{
|
|
protected $signature = 'companies:merges
|
|
{--batch= : Nur diesen Lauf}
|
|
{--email= : Nur diese Adresse}
|
|
{--limit=100 : Höchstens so viele Vorgänge}
|
|
{--json : Ausgabe als JSON}';
|
|
|
|
protected $description = 'Listet Zusammenführungen mit Überlebendem, aufgegangenen Firmen und Prüf-URLs.';
|
|
|
|
public function handle(): int
|
|
{
|
|
$merges = CompanyMerge::query()
|
|
->when($this->option('batch'), fn (Builder $query, string $batch) => $query->where('batch', $batch))
|
|
->when($this->option('email'), fn (Builder $query, string $email) => $query->where('email', Company::emailKey($email)))
|
|
->with([
|
|
'survivor',
|
|
'moves' => fn ($query) => $query->where('subject', CompanyMergeSubject::Company->value),
|
|
])
|
|
->orderByDesc('id')
|
|
->limit(max(1, (int) $this->option('limit')))
|
|
->get();
|
|
|
|
if ($merges->isEmpty()) {
|
|
$this->warn('Keine Vorgänge gefunden.');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$losers = Company::withTrashed()
|
|
->withoutGlobalScopes()
|
|
->whereIn('id', $merges->flatMap(fn (CompanyMerge $merge) => $merge->moves->pluck('subject_id'))->all())
|
|
->get(['id', 'name', 'slug', 'portal'])
|
|
->keyBy('id');
|
|
|
|
$rows = $merges->map(function (CompanyMerge $merge) use ($losers): array {
|
|
$survivor = $merge->survivor;
|
|
$gone = $merge->moves->map(fn ($move) => $losers->get($move->subject_id))->filter();
|
|
|
|
return [
|
|
'id' => $merge->getKey(),
|
|
'batch' => $merge->batch,
|
|
'email' => $merge->email,
|
|
'rueckabgewickelt' => $merge->reverted_at?->toDateTimeString(),
|
|
'bleibt' => ['id' => $survivor->getKey(), 'name' => $survivor->name, 'slug' => $survivor->slug, 'portal' => $survivor->portal->value],
|
|
'newsroom' => $this->newsroomUrls($survivor->portal, $survivor->slug),
|
|
'aufgegangen' => $gone->map(fn (Company $loser): array => [
|
|
'id' => $loser->getKey(),
|
|
'name' => $loser->name,
|
|
'slug' => $loser->slug,
|
|
'portal' => $loser->portal->value,
|
|
// Nur bei abweichendem Slug gibt es eine Weiterleitung —
|
|
// bei gleichem findet die URL den Überlebenden direkt.
|
|
'alte_url' => $loser->slug !== $survivor->slug ? $this->newsroomUrls($loser->portal, $loser->slug) : [],
|
|
])->values()->all(),
|
|
'meldungen' => $merge->moved_press_releases_count,
|
|
];
|
|
});
|
|
|
|
if ($this->option('json')) {
|
|
$this->line((string) json_encode($rows->values()->all(), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$this->table(
|
|
['#', 'Adresse', 'bleibt', 'Newsroom', 'aufgegangen (alte URL → 301)', 'PM'],
|
|
$rows->map(fn (array $row): array => [
|
|
$row['id'].($row['rueckabgewickelt'] ? ' (zurück)' : ''),
|
|
$row['email'],
|
|
sprintf('#%d %s', $row['bleibt']['id'], Str::limit($row['bleibt']['name'], 32)),
|
|
implode("\n", $row['newsroom']),
|
|
implode("\n", array_map(
|
|
fn (array $loser): string => sprintf('#%d %s%s', $loser['id'], Str::limit($loser['name'], 28), $loser['alte_url'] ? "\n ".implode("\n ", $loser['alte_url']) : ' (gleicher Slug)'),
|
|
$row['aufgegangen'],
|
|
)),
|
|
$row['meldungen'],
|
|
])->all(),
|
|
);
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
/**
|
|
* Newsroom-URL je Portal, auf dem die Firma erreichbar ist.
|
|
*
|
|
* @return list<string>
|
|
*/
|
|
private function newsroomUrls(Portal $portal, string $slug): array
|
|
{
|
|
$portals = $portal === Portal::Both ? ['presseecho', 'businessportal24'] : [$portal->value];
|
|
|
|
return array_map(
|
|
fn (string $key): string => rtrim((string) config("domains.domains.{$key}.url"), '/').'/de/newsroom/'.$slug,
|
|
$portals,
|
|
);
|
|
}
|
|
}
|