candidates(); $count = (clone $query)->count(); if ($count === 0) { $this->info('Keine Linkspam-Firmen gefunden.'); return self::SUCCESS; } $this->table( ['ID', 'Name', 'Angelegt', 'Adresse (Anfang)'], (clone $query)->limit(10)->get()->map(fn (Company $company): array => [ $company->id, mb_strimwidth((string) $company->name, 0, 50, '…'), $company->created_at?->format('d.m.Y'), mb_strimwidth(str_replace(["\r", "\n"], ' ', (string) $company->address), 0, 60, '…'), ])->all(), ); if ($this->option('dry-run')) { $this->info(sprintf('[Dry-Run] %d Firmen würden deaktiviert (10 Beispiele oben).', $count)); return self::SUCCESS; } $ids = (clone $query)->pluck('id'); $file = sprintf('companies-link-spam-%s.txt', now()->format('Y-m-d-His')); Storage::disk('local')->put($file, $ids->implode("\n")); $retired = 0; foreach ($ids->chunk(500) as $chunk) { $retired += Company::query() ->withoutGlobalScope(PortalScope::class) ->whereIn('id', $chunk->all()) ->update(['is_active' => false]); } $activityLog->record( ActivityType::Correction, sprintf('%d Legacy-Firmen mit Linkspam in den Stammdaten deaktiviert (IDs in storage/app/%s).', $retired, $file), null, null, ['count' => $retired, 'file' => $file], 'system', ); $this->info(sprintf('%d Firmen deaktiviert. IDs: storage/app/%s', $retired, $file)); return self::SUCCESS; } /** * @return Builder */ private function candidates(): Builder { return Company::query() ->withoutGlobalScope(PortalScope::class) ->where('is_active', true) ->whereNull('gone_at') ->where(function (Builder $query): void { foreach (['address', 'boilerplate', 'name'] as $column) { foreach (self::MARKERS as $marker) { $query->orWhere($column, 'like', '%'.$marker.'%'); } } }) ->whereDoesntHave('pressReleases', fn (Builder $q) => $q->withoutGlobalScope(PortalScope::class)->published()) ->orderBy('id'); } }