Fix #114: Beleg-Löschung nicht mehr durch Datei-Permission-Fehler unterbrochen

This commit is contained in:
fds2610-bot 2026-07-06 23:57:37 +02:00
parent 0fad25907c
commit 2012f228c4
3 changed files with 52 additions and 2 deletions

View file

@ -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) ## 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` - **`migrations/084_customer_cc_emails.sql`:** Neue Spalten `email_cc1`, `email_cc2` in `customers`

View file

@ -249,9 +249,11 @@ class Beleg
$cnt = Database::fetchOne('SELECT COUNT(*) as cnt FROM bookings WHERE beleg_id=?', [$id]); $cnt = Database::fetchOne('SELECT COUNT(*) as cnt FROM bookings WHERE beleg_id=?', [$id]);
if ($cnt && $cnt['cnt'] > 0) return false; 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']; $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]); Database::execute('DELETE FROM belege WHERE id=?', [$id]);
return true; return true;

View file

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
use Steuerkram\Models\Beleg;
class BelegDeleteUnlinkFailTest extends TestCase
{
protected string $testName = 'Test 49: Beleg-Löschung trotz Datei-Permission-Fehler';
public function run(): void
{
$dir = dirname(__DIR__) . '/public/static/uploads/test_49_unlink_fail';
$file = $dir . '/original.pdf';
mkdir($dir, 0755, true);
file_put_contents($file, 'dummy');
// Schreibschutz auf das Verzeichnis: unlink() der Datei schlägt fehl (Permission denied),
// genau wie im gemeldeten Fehler auf dem Produktiv-Server.
chmod($dir, 0500);
try {
$id = Beleg::create([
'beleg_nr' => '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);
}
}
}