- B-01/B-02: Startseiten-Feed, Card-Helfer und Nachweis-PDF nur mit isPubliclyDeliverable() - B-03: Livewire-Temp-Upload 16 MiB - N09: Snapshot je Bytes- und Metadaten-Hash inkl. OG-Variante, put() geprüft, alle Fassungen ins Archiv - O03: published_ever_at in der Freigabetransaktion (markPublishedIfNowPublic) — Kundenbestätigung, Vorab-Sichtung, Korrektur - B-04/B-14: Bestätigung an Bild-ID und SHA gebunden, unter Sperre - B-05/B-06: Entfernen unter Sperre mit frischem Stand und Archivauftrag; Korrektur archiviert über den Auftrag, Nacharbeiten abgesichert - B-07: precheck_withheld_at getrennt von withheld_at (Migration + Übernahme) - B-08, B-09, B-11, B-12: published_ever_at nur bei Status published, Admin-Eigentümer mit Kundenregel, Sweep verwaister Originale, Verarbeitungsfehler als Formularmeldung - K-02-Teil: nach Kundenbestätigung erneut routen - OPT-3 bis OPT-5: pingImage für JPEG, Hash durchgereicht, erstes Frame Admin-PM-Detailseite enthält zusätzlich K-06 (Autorisierung) und A-08 (Nachweis per POST), weil die Datei ungeteilt committet ist. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
55 lines
2.1 KiB
PHP
55 lines
2.1 KiB
PHP
<?php
|
||
|
||
namespace App\Console\Commands;
|
||
|
||
use App\Services\Archive\EvidenceArchive;
|
||
use App\Services\PressRelease\Images\PressReleaseImageRemover;
|
||
use Illuminate\Console\Command;
|
||
|
||
/**
|
||
* Umsetzungsaudit 29.09.2026, B-11: Beweisoriginale ohne Bildzeile (harter
|
||
* Abbruch nach dem Schreiben des Originals, z. B. memory_limit bei
|
||
* 8000 × 8000 px) nach einer Karenzzeit entfernen.
|
||
*
|
||
* Standard ist ein Trockenlauf. Dateien, auf die eine Bildzeile zeigt —
|
||
* auch weich gelöschte (Beweisarchiv ausstehend) —, bleiben immer liegen.
|
||
* Nach einem Datenbank-Restore fehlen Zeilen, deren Originale noch Beweis
|
||
* sind: Solange der Archiv-Sweep ausgesetzt ist (`archive:sweep-orphans
|
||
* --pause`, setzt auch `archive:reconcile-after-restore`), löscht auch dieser
|
||
* Befehl nichts.
|
||
*/
|
||
class SweepOrphanPressReleaseOriginals extends Command
|
||
{
|
||
protected $signature = 'press-release-images:sweep-orphan-originals
|
||
{--execute : Wirklich löschen (Standard ist ein Trockenlauf)}
|
||
{--hours=48 : Nur Dateien, die älter als X Stunden sind}';
|
||
|
||
protected $description = 'Entfernt Beweisoriginale ohne zugehörige Bildzeile (B-11)';
|
||
|
||
public function handle(PressReleaseImageRemover $remover, EvidenceArchive $archive): int
|
||
{
|
||
$execute = (bool) $this->option('execute');
|
||
|
||
if ($execute && $archive->isSweepPaused()) {
|
||
$this->warn('Orphan-Sweep ausgesetzt (Restore-Abgleich) — nichts gelöscht. Fortsetzen mit archive:sweep-orphans --resume.');
|
||
|
||
return self::SUCCESS;
|
||
}
|
||
|
||
$result = $remover->sweepOrphanOriginals(
|
||
$execute,
|
||
(int) $this->option('hours'),
|
||
fn (string $file) => $this->line(' verwaist: '.$file),
|
||
);
|
||
|
||
$this->info(sprintf(
|
||
'%s: %d Dateien geprüft, %d verwaist, %d entfernt.',
|
||
$execute ? 'Bereinigung' : 'Trockenlauf',
|
||
$result['scanned'],
|
||
$result['orphans'],
|
||
$result['removed'],
|
||
));
|
||
|
||
return $execute && $result['removed'] < $result['orphans'] ? self::FAILURE : self::SUCCESS;
|
||
}
|
||
}
|