false`; ein stilles * `false` darf nirgends als Erfolg durchgehen, wo danach ein Tombstone * gesetzt oder eine Zeile hart gelöscht wird. */ class FileDeletion { /** * Löscht und bestätigt, dass die Datei danach nicht mehr existiert. * Eine bereits fehlende Datei gilt als gelöscht. */ public static function delete(Filesystem $disk, string $path): bool { // Eine fehlende Datei meldet der lokale Treiber als gelöscht (true); // ein stilles false (throw => false) heißt: Datei ist noch da. return $disk->delete($path) && self::isGone($disk, $path); } private static function isGone(Filesystem $disk, string $path): bool { return ! $disk->exists($path); } /** * Wie delete(), wirft aber bei Misserfolg — für Pfade, auf denen die * Löschung Voraussetzung für den nächsten Schritt ist. */ public static function deleteOrThrow(Filesystem $disk, string $path, string $context): void { if (! self::delete($disk, $path)) { throw new RuntimeException($context.': Datei konnte nicht gelöscht werden ('.$path.').'); } } /** * Löscht mehrere Pfade, protokolliert Fehlschläge und liefert die * verbliebenen Pfade — für Pfade, deren Verbleib nur Datenminimierung * betrifft. * * @param list $paths * @return list */ public static function deleteOrLog(Filesystem $disk, array $paths, string $context): array { $remaining = []; foreach ($paths as $path) { if (! self::delete($disk, $path)) { $remaining[] = $path; } } if ($remaining !== []) { Log::error($context.': Datei(en) konnten nicht gelöscht werden.', ['paths' => $remaining]); } return $remaining; } }