Sicherheits-/Korrektheits-Fixes und neue Funktionen
Bugfixes aus dem Code-Review: - XSS: unescaptes $_SERVER['PHP_SELF'] in csvupload.php und letzteneintraege.php durch feste Seitennamen ersetzt. - Stripe-Webhook: Event-Deduplizierung (neue Tabelle stripe_webhook_events) gegen doppelte Verarbeitung/Dolibarr-Rechnungen bei Retry-Zustellung. - Stripe-Webhook: Tarifwechsel aus dem Kundenportal wird lokal nachgezogen (plan_code aus dem Preis-lookup_key bei subscription.updated). - Post-Redirect-Get fuer jahresauswertung, mailversenden und die Selbst-Stricheintragung - verhindert Doppelbuchung/Doppelversand per Browser-Refresh. - Jahresbonus: Mails erst nach erfolgreichem Commit; Restcent-Ausgleich beim letzten Empfaenger, damit die Summe exakt stimmt. - Verschachtelte HTML-Dokumente in csvupload/einzahlung/stricheintragen entfernt (Layout kommt aus header.php). - Rate-Limit fuer den Versand von E-Mail-Verifizierungslinks. Neue Funktionen: - Mitglieder koennen ihren zuletzt selbst eingetragenen Strich wieder stornieren (nur eigene Web-Eintraege, Kassenwart-Eintraege bleiben). - Monatsuebersicht des eigenen Verbrauchs im Mitglieder-Dashboard. - Automatische Zahlungserinnerung: opt-in pro Mandant ab der Warnschwelle, mit Intervall; Cron-Skript scripts/send-payment-reminders.php. - CSV-Import fuer Mitgliederlisten inkl. herunterladbarer Vorlage (mitglieder-vorlage.php), Semikolon-/Komma- und BOM-Erkennung. - Logo als PDF-Wasserzeichen pro Mandant (Upload in den Mandant- Einstellungen, geschuetzt unter var/tenant_logos/, ersetzt den Text-Wasserzeichen im Ausdruck). Robusterer Teilnehmer-Lookup im Dashboard ueber user_id (Fallback E-Mail).
This commit is contained in:
@@ -263,3 +263,51 @@ function imports_commit_batch(PDO $pdo, int $tenantId, int $batchId): array
|
||||
|
||||
return ['imported' => $imported];
|
||||
}
|
||||
|
||||
/**
|
||||
* Parst eine Mitglieder-CSV (Vorlage: Name, E-Mail, PayPal-Name, Aktiv). Erste
|
||||
* Zeile ist die Kopfzeile und wird uebersprungen. Trennzeichen wird anhand der
|
||||
* Kopfzeile automatisch erkannt (Komma oder Semikolon - Excel im deutschen
|
||||
* Gebietsschema exportiert Semikolon).
|
||||
*
|
||||
* @return list<array{row_number:int, name:string, email:string, paypal_name:string, active:bool}>
|
||||
*/
|
||||
function imports_parse_member_csv(string $filePath): array
|
||||
{
|
||||
$handle = fopen($filePath, 'r');
|
||||
if ($handle === false) {
|
||||
throw new RuntimeException('Die CSV-Datei konnte nicht gelesen werden.');
|
||||
}
|
||||
|
||||
$firstLine = fgets($handle);
|
||||
if ($firstLine === false) {
|
||||
fclose($handle);
|
||||
return [];
|
||||
}
|
||||
// BOM entfernen, Trennzeichen erkennen.
|
||||
$firstLine = preg_replace('/^\xEF\xBB\xBF/', '', $firstLine);
|
||||
$delimiter = (substr_count($firstLine, ';') > substr_count($firstLine, ',')) ? ';' : ',';
|
||||
|
||||
$rows = [];
|
||||
$rowNumber = 0;
|
||||
while (($data = fgetcsv($handle, 2000, $delimiter)) !== false) {
|
||||
// Komplett leere Zeilen ueberspringen.
|
||||
if ($data === [null] || (count($data) === 1 && trim((string)$data[0]) === '')) {
|
||||
continue;
|
||||
}
|
||||
$rowNumber++;
|
||||
$aktivRaw = strtolower(trim((string)($data[3] ?? 'ja')));
|
||||
$active = !in_array($aktivRaw, ['nein', 'no', '0', 'false', 'inaktiv'], true);
|
||||
$rows[] = [
|
||||
'row_number' => $rowNumber,
|
||||
'name' => trim((string)($data[0] ?? '')),
|
||||
'email' => trim((string)($data[1] ?? '')),
|
||||
'paypal_name' => trim((string)($data[2] ?? '')),
|
||||
'active' => $active,
|
||||
];
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
|
||||
return $rows;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user