fix: POST-Redirect-GET Pattern für Reload-Sicherheit (v4.3)

Problem:
- Nach Aktualisieren (F5) kam Browser-Warnung "Formular erneut senden"
- Filter (Kabel ausblenden) gingen nach Reload verloren

Lösung:
1. Kabel-Filter als GET-Parameter statt POST
   - Filter bleiben nach F5 erhalten
   - Keine Token-Validierung nötig für einfache Filter

2. Redirect nach POST-Actions:
   - createallfromdatanorm: Redirect zu ?id=X nach Verarbeitung
   - addmissingprices: Redirect zu ?id=X nach Verarbeitung
   - Verhindert "Form resubmit" Warnung

Jetzt:
- F5 = Einfaches Reload ohne Warnung
- Filter bleiben erhalten
- Keine doppelten Submissions möglich

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Eduard Wisch 2026-03-03 08:52:07 +01:00
parent 66cdff2104
commit bfcc5c66db

View file

@ -848,6 +848,11 @@ if ($action == 'addmissingprices' && $id > 0) {
if ($errorCount > 0) { if ($errorCount > 0) {
setEventMessages($addedCount.' hinzugefuegt, '.$errorCount.' Fehler', null, 'warnings'); setEventMessages($addedCount.' hinzugefuegt, '.$errorCount.' Fehler', null, 'warnings');
} }
// Redirect to avoid "Form resubmit" warning on page reload
$redirectUrl = $_SERVER['PHP_SELF'].'?id='.$id;
header('Location: '.$redirectUrl);
exit;
} else { } else {
setEventMessages('Keine Preise ausgewählt', null, 'warnings'); setEventMessages('Keine Preise ausgewählt', null, 'warnings');
} }
@ -1762,6 +1767,11 @@ if ($action == 'createallfromdatanorm' && $id > 0) {
$import->status = ZugferdImport::STATUS_IMPORTED; $import->status = ZugferdImport::STATUS_IMPORTED;
$import->update($user); $import->update($user);
} }
// Redirect to avoid "Form resubmit" warning on page reload
$redirectUrl = $_SERVER['PHP_SELF'].'?id='.$id;
header('Location: '.$redirectUrl);
exit;
} }
$action = 'edit'; $action = 'edit';
$import->fetch($id); $import->fetch($id);
@ -2950,12 +2960,11 @@ if ($action == 'edit' && $import->id > 0) {
print '<i class="fas fa-database paddingright"></i>'.$langs->trans('DatanormPreview'); print '<i class="fas fa-database paddingright"></i>'.$langs->trans('DatanormPreview');
print ' <span class="badge badge-info">'.count($datanormPreviewMatches).' '.$langs->trans('Matches').'</span>'; print ' <span class="badge badge-info">'.count($datanormPreviewMatches).' '.$langs->trans('Matches').'</span>';
// Filter: Kabel ausblenden (in eigenem Form für sofortiges Submit) // Filter: Kabel ausblenden (als GET-Parameter für Reload-Sicherheit)
$hideCables = GETPOST('hide_cables', 'int'); $hideCables = GETPOST('hide_cables', 'int');
$checked = $hideCables ? ' checked' : ''; $checked = $hideCables ? ' checked' : '';
print '<div style="float: right; margin-top: -5px;">'; print '<div style="float: right; margin-top: -5px;">';
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'" style="display: inline-block; margin: 0; padding: 5px 10px; background-color: #f8f8f8; border: 1px solid #ddd; border-radius: 4px;">'; print '<form method="GET" action="'.$_SERVER['PHP_SELF'].'" style="display: inline-block; margin: 0; padding: 5px 10px; background-color: #f8f8f8; border: 1px solid #ddd; border-radius: 4px;">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="previewdatanorm">'; print '<input type="hidden" name="action" value="previewdatanorm">';
print '<input type="hidden" name="id" value="'.$import->id.'">'; print '<input type="hidden" name="id" value="'.$import->id.'">';
print '<label style="font-weight: normal; cursor: pointer; margin: 0;">'; print '<label style="font-weight: normal; cursor: pointer; margin: 0;">';