- publish()/changeStatusFromAdmin(): kein Bild aus Formular v2 ohne gültige Bestätigung (ImageRightsConfirmationRequiredException, Admin-Seite meldet es); published_ever_at an PM und Bildern; PublishedImageSnapshot (Cover + JSON mit Nachweis/Kennzeichnung) - deleteFromAdmin() und press-releases:purge-drafts löschen Bilder nie veröffentlichter Meldungen samt Original und Bestätigung sofort (E4, O1) - press-releases:backfill-published-ever (Status-Log), press-release-images:purge-inactive-legacy (E-B11, Trockenlauf Standard) - Admin-Route für Beweisoriginal und veröffentlichte Fassung nur mit Zweck, ActivityType EvidenceAccess; Architekturtest: original_path nur in vier Dateien - ImageCorrectionService + image_declaration_corrections (insert-only), withheld_at blendet das Bild öffentlich aus (publiclyVisible-Scope), Korrekturpanel auf der Admin-Seite - Systemstatus: fehlgeschlagene Herkunftsprüfungen der letzten 7 Tage Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
60 lines
2 KiB
PHP
60 lines
2 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use App\Enums\PressReleaseStatus;
|
||
use App\Models\PressRelease;
|
||
use App\Services\PressRelease\Images\PressReleaseImageRemover;
|
||
use Illuminate\Console\Command;
|
||
|
||
/**
|
||
* Archiviert Entwürfe, die seit mehr als X Tagen nicht bearbeitet wurden.
|
||
* Schützt vor "Zombie-Drafts" in der DB – optional, konfigurierbar.
|
||
*/
|
||
class PurgeExpiredPressReleaseDrafts extends Command
|
||
{
|
||
protected $signature = 'press-releases:purge-drafts
|
||
{--days=180 : Entwürfe älter als X Tage archivieren}
|
||
{--dry-run : Nur zählen, nichts ändern}';
|
||
|
||
protected $description = 'Archiviert inaktive PM-Entwürfe (älter als X Tage).';
|
||
|
||
public function handle(): int
|
||
{
|
||
$days = (int) $this->option('days');
|
||
$isDryRun = $this->option('dry-run');
|
||
$cutoff = now()->subDays($days);
|
||
|
||
$query = PressRelease::withoutGlobalScopes()
|
||
->where('status', PressReleaseStatus::Draft->value)
|
||
->where('updated_at', '<', $cutoff);
|
||
|
||
$count = $query->count();
|
||
|
||
if ($isDryRun) {
|
||
$this->warn("[DRY-RUN] {$count} Entwürfe würden archiviert. Kein tatsächlicher Vorgang.");
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
|
||
// Bilder nie veröffentlichter Entwürfe werden mit dem Purge sofort
|
||
// und vollständig gelöscht (Bildkennzeichnung E.3, Decision-Update E4).
|
||
$remover = app(PressReleaseImageRemover::class);
|
||
$imagesRemoved = 0;
|
||
|
||
(clone $query)->whereNull('published_ever_at')->with('images')->chunkById(200, function ($drafts) use ($remover, &$imagesRemoved): void {
|
||
foreach ($drafts as $draft) {
|
||
foreach ($draft->images as $image) {
|
||
$remover->remove($image);
|
||
$imagesRemoved++;
|
||
}
|
||
}
|
||
});
|
||
|
||
$query->update(['status' => PressReleaseStatus::Archived->value]);
|
||
|
||
$this->info("PM-Entwürfe archiviert: {$count} Einträge, Bilder gelöscht: {$imagesRemoved}.");
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
}
|