diff --git a/Changes.md b/Changes.md index bab3732..28e6c30 100644 --- a/Changes.md +++ b/Changes.md @@ -2,6 +2,12 @@ --- +## 2026-07-06 – Fix: Fehlermeldung beim Beleg-Löschen, falls Datei nicht löschbar ist (Issue #114) + +- **`src/Models/Beleg.php`:** `delete()` nutzte ein ungeschütztes `unlink()`; schlug dieses auf dem Server mit „Permission denied" fehl, wurde eine PHP-Warning ausgegeben, die den nachfolgenden Redirect-Header zerstörte („headers already sent"). Der Datensatz wurde dabei trotzdem gelöscht, was zu Verwirrung führte. Fehler beim Datei-Löschen wird jetzt abgefangen und nur noch geloggt (`error_log`), die Löschung des Datensatzes läuft unverändert durch. + +--- + ## 2026-07-02 – Feature: Zusätzliche CC-E-Mail-Adressen pro Kunde (Issue #111) - **`migrations/084_customer_cc_emails.sql`:** Neue Spalten `email_cc1`, `email_cc2` in `customers` diff --git a/src/Models/Beleg.php b/src/Models/Beleg.php index 56781c7..edaa37c 100644 --- a/src/Models/Beleg.php +++ b/src/Models/Beleg.php @@ -249,9 +249,11 @@ class Beleg $cnt = Database::fetchOne('SELECT COUNT(*) as cnt FROM bookings WHERE beleg_id=?', [$id]); if ($cnt && $cnt['cnt'] > 0) return false; - // Delete file + // Delete file (Datei-Löschung darf DB-Löschung nicht durch Warnings/Header-Fehler stören) $fullPath = dirname(__DIR__, 2) . '/public/' . $beleg['storage_path']; - if (file_exists($fullPath)) unlink($fullPath); + if (file_exists($fullPath) && !@unlink($fullPath)) { + error_log('Beleg::delete: Datei konnte nicht gelöscht werden: ' . $fullPath); + } Database::execute('DELETE FROM belege WHERE id=?', [$id]); return true; diff --git a/tests/49_BelegDeleteUnlinkFailTest.php b/tests/49_BelegDeleteUnlinkFailTest.php new file mode 100644 index 0000000..aff945a --- /dev/null +++ b/tests/49_BelegDeleteUnlinkFailTest.php @@ -0,0 +1,42 @@ + 'BLG-TEST-49', + 'filename' => 'original.pdf', + 'storage_path' => 'static/uploads/test_49_unlink_fail/original.pdf', + 'mime_type' => 'application/pdf', + 'file_hash' => 'testhash49', + 'beleg_datum' => '2026-01-01', + ]); + $this->assertGreaterThan(0, $id, 'Beleg angelegt'); + + $result = Beleg::delete($id); + $this->assert($result === true, 'delete() liefert true, obwohl unlink() fehlschlägt'); + $this->assert(Beleg::find($id) === false, 'Beleg-Datensatz wurde trotz Datei-Fehler aus der DB gelöscht'); + } finally { + chmod($dir, 0755); + if (file_exists($file)) unlink($file); + if (is_dir($dir)) rmdir($dir); + } + } +}