diff --git a/customer-qr-upload.php b/customer-qr-upload.php
new file mode 100644
index 0000000..d24673b
--- /dev/null
+++ b/customer-qr-upload.php
@@ -0,0 +1,311 @@
+
QR-Code UploadQR-Code Upload
Dieses Formular ist derzeit nicht aktiviert.
';
+ exit;
+}
+
+bratonien_tools_customer_qr_ensure_storage();
+
+if ((string)($_GET['action'] ?? '') === 'check')
+{
+ header('Content-Type: application/json; charset=utf-8');
+ header('Cache-Control: no-store, max-age=0');
+
+ try
+ {
+ $year = bratonien_tools_customer_qr_year($_GET['year'] ?? '');
+ $number = bratonien_tools_customer_qr_number($_GET['number'] ?? '');
+ $exists = bratonien_tools_customer_qr_exists($year, $number);
+ echo json_encode(array(
+ 'ok' => true,
+ 'available' => !$exists,
+ 'year' => $year,
+ 'number' => $number,
+ 'message' => $exists
+ ? 'Diese QR-Code-Nummer ist für '.$year.' bereits vorhanden.'
+ : 'Nummer ist für '.$year.' frei.',
+ ), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+ }
+ catch (Throwable $e)
+ {
+ http_response_code(400);
+ echo json_encode(array('ok' => false, 'message' => $e->getMessage()), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+ }
+ exit;
+}
+
+if ($_SERVER['REQUEST_METHOD'] === 'POST')
+{
+ $results = array();
+ $year = bratonien_tools_customer_qr_default_year();
+
+ try
+ {
+ if (function_exists('check_pwg_token'))
+ {
+ check_pwg_token();
+ }
+
+ $year = bratonien_tools_customer_qr_year($_POST['upload_year'] ?? '');
+
+ if (
+ empty($_FILES['qr_files'])
+ && empty($_POST)
+ && !empty($_SERVER['CONTENT_LENGTH'])
+ )
+ {
+ throw new RuntimeException('Der Upload überschreitet das PHP-Limit post_max_size ('.ini_get('post_max_size').').');
+ }
+
+ if (empty($_FILES['qr_files']))
+ {
+ throw new RuntimeException('Es wurden keine QR-Code-Dateien ausgewählt.');
+ }
+
+ $numbers = isset($_POST['qr_numbers']) && is_array($_POST['qr_numbers'])
+ ? array_values($_POST['qr_numbers'])
+ : array();
+
+ $results = bratonien_tools_customer_qr_process_uploads($year, $_FILES['qr_files'], $numbers);
+ }
+ catch (Throwable $e)
+ {
+ $results[] = array(
+ 'status' => 'error',
+ 'file' => '',
+ 'year' => $year,
+ 'number' => '',
+ 'message' => $e->getMessage(),
+ );
+ }
+
+ $_SESSION['bratonien_customer_qr_flash'] = array(
+ 'year' => $year,
+ 'results' => $results,
+ );
+
+ $target = strtok($_SERVER['REQUEST_URI'], '?');
+ header('Location: '.$target, true, 303);
+ exit;
+}
+
+$flash = array();
+if (!empty($_SESSION['bratonien_customer_qr_flash']) && is_array($_SESSION['bratonien_customer_qr_flash']))
+{
+ $flash = $_SESSION['bratonien_customer_qr_flash'];
+ unset($_SESSION['bratonien_customer_qr_flash']);
+}
+
+$selected_year = isset($flash['year']) ? (int)$flash['year'] : bratonien_tools_customer_qr_default_year();
+$results = isset($flash['results']) && is_array($flash['results']) ? $flash['results'] : array();
+$token = function_exists('get_pwg_token') ? get_pwg_token() : '';
+$max_files = max(1, (int)ini_get('max_file_uploads'));
+$endpoint = htmlspecialchars(strtok($_SERVER['REQUEST_URI'], '?'), ENT_QUOTES, 'UTF-8');
+
+header('Content-Type: text/html; charset=utf-8');
+header('Cache-Control: no-store, max-age=0');
+?>
+
+
+
+
+
+ QR-Code Upload
+
+
+
+
+
+
+
+
+ Ergebnis
+
+
+
+
+
+
Jahr · QR-Code #
+
+
+
+
+
+
+
+
+
+
+
+