First version, for githup; UNSTABLE, DO NOT USE!
This commit is contained in:
94
www/intern/scripts/abt_handler.php
Normal file
94
www/intern/scripts/abt_handler.php
Normal file
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
|
||||
$domain = $_SERVER['HTTP_HOST'];
|
||||
|
||||
$url = $protocol . $domain;
|
||||
|
||||
if ((isset($_POST['prev_abt'])) && !empty($_POST['prev_abt_submit'])) {
|
||||
$value = get_option('wk_panel_current_abt', 1);
|
||||
if ($value > 1){
|
||||
$value -= 1;
|
||||
update_option('wk_panel_current_abt', $value);
|
||||
}
|
||||
|
||||
header("Location: ".$url."/intern/kampfrichter".$_SERVER['REQUEST_URI']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ((isset($_POST['next_abt'])) && !empty($_POST['next_abt_submit'])) {
|
||||
$value = get_option('wk_panel_current_abt', 1);
|
||||
$maxvalue = $wpdb->get_var( "SELECT abteilung FROM $table_name ORDER BY abteilung DESC LIMIT 1" );
|
||||
|
||||
if ($value < $maxvalue){
|
||||
$value += 1;
|
||||
update_option('wk_panel_current_abt', $value);
|
||||
}
|
||||
header("Location: ".$url."/intern/kampfrichter".$_SERVER['REQUEST_URI']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (!isset($_SESSION['currentsubabt'])){
|
||||
$_SESSION['currentsubabt'] = 0;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['last_abt'])){
|
||||
$_SESSION['last_abt'] = get_option('wk_panel_current_abt', 1);
|
||||
}
|
||||
|
||||
if ($_SESSION['last_abt'] !== get_option('wk_panel_current_abt', 1)){
|
||||
$_SESSION['currentsubabt'] = 0;
|
||||
$_SESSION['last_abt'] = get_option('wk_panel_current_abt', 1);
|
||||
}
|
||||
|
||||
if ((isset($_POST['prev_subabt'])) && !empty($_POST['prev_subabt_submit'])) {
|
||||
$value = $_SESSION['currentsubabt'];
|
||||
if ($value > 0){
|
||||
$_SESSION['currentsubabt']--;
|
||||
$_SESSION['last_abt'] = get_option('wk_panel_current_abt', 1);
|
||||
}
|
||||
header("Location: ".$url."/intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
if ((isset($_POST['next_subabt'])) && !empty($_POST['next_subabt_submit'])) {
|
||||
|
||||
$value = $_SESSION['currentsubabt'];
|
||||
|
||||
if ($value < 4){
|
||||
$_SESSION['currentsubabt']++;
|
||||
$_SESSION['last_abt'] = get_option('wk_panel_current_abt', 1);
|
||||
}
|
||||
header("Location: ".$url."/intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (
|
||||
isset($_POST['togle_advanced_mode']) &&
|
||||
!empty($_POST['togle_advanced_mode_submit']) &&
|
||||
check_admin_referer('toggle_advanced_mode_action', 'toggle_advanced_mode_nonce')
|
||||
) {
|
||||
$current_value = get_option('option_advanced_mode', false);
|
||||
$new_value = !$current_value;
|
||||
update_option('option_advanced_mode', $new_value);
|
||||
|
||||
hheader("Location: ".$url."/intern/kampfrichter".$_SERVER['REQUEST_URI']);
|
||||
exit;
|
||||
}
|
||||
if (
|
||||
isset($_POST['togle_advanced_mode_admin']) &&
|
||||
!empty($_POST['togle_advanced_mode_admin_submit']) &&
|
||||
check_admin_referer('toggle_advanced_mode_admin_action', 'toggle_advanced_mode_admin_nonce')
|
||||
) {
|
||||
$current_value = get_option('option_advanced_mode_admin', false);
|
||||
$new_value = !$current_value;
|
||||
update_option('option_advanced_mode_admin', $new_value);
|
||||
|
||||
header("Location: ".$url."/intern/kampfrichter".$_SERVER['REQUEST_URI']);
|
||||
exit;
|
||||
}
|
||||
28
www/intern/scripts/ajax-create-ws-token.php
Normal file
28
www/intern/scripts/ajax-create-ws-token.php
Normal file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (
|
||||
!((isset($_SESSION['access_granted_wk_leitung']) && $_SESSION['access_granted_wk_leitung'] === true) ||
|
||||
(isset($_SESSION['access_granted_kampfrichter']) && $_SESSION['access_granted_kampfrichter'] === true))
|
||||
) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_POST['access'])) {
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$access = preg_replace("/[\W]/", "", trim($_POST['access']));
|
||||
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require $baseDir . "/../scripts/websocket/ws-create-token.php";
|
||||
|
||||
$token = generateWSToken($access);
|
||||
|
||||
$responseBool = $token != null;
|
||||
|
||||
echo json_encode(['success' => $responseBool, 'token' => $token]);
|
||||
4
www/intern/scripts/audiofiles-uploads/.user.ini
Normal file
4
www/intern/scripts/audiofiles-uploads/.user.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
upload_max_filesize = 50M
|
||||
post_max_size = 55M
|
||||
max_execution_time = 120
|
||||
max_input_time = 120
|
||||
142
www/intern/scripts/audiofiles-uploads/ajax_audiofile_upload.php
Normal file
142
www/intern/scripts/audiofiles-uploads/ajax_audiofile_upload.php
Normal file
@@ -0,0 +1,142 @@
|
||||
<?php
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
$isTrainer =
|
||||
isset($_SESSION['access_granted_trainer'], $_SESSION['passcodetrainer_id']) &&
|
||||
$_SESSION['access_granted_trainer'] === true &&
|
||||
(int)$_SESSION['passcodetrainer_id'] > 0;
|
||||
|
||||
$isWkLeitung =
|
||||
isset($_SESSION['access_granted_wk_leitung'], $_SESSION['passcodewk_leitung_id']) &&
|
||||
$_SESSION['access_granted_wk_leitung'] === true &&
|
||||
(int)$_SESSION['passcodewk_leitung_id'] > 0;
|
||||
|
||||
if (!$isTrainer && !$isWkLeitung) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Allow large uploads and enough memory for GD processing
|
||||
ini_set('memory_limit', '256M');
|
||||
ini_set('max_execution_time', '120');
|
||||
|
||||
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
|
||||
if (!isset($_FILES['music_file']) || $_FILES['music_file']['error'] !== UPLOAD_ERR_OK) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Keine Musik' . $_FILES['music_file']['error'] ?? 'NO ERROR KNOWN'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$type = ($isTrainer) ? 'tr' : 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
|
||||
$saveDir = '/files/music/';
|
||||
|
||||
$normalDir = $saveDir;
|
||||
|
||||
$uploadDir = $baseDir . $saveDir;
|
||||
|
||||
$maxLengthMusic = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['maxLengthMusic']);
|
||||
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
|
||||
$tmpPath = $_FILES['music_file']['tmp_name'];
|
||||
$originalName = $_FILES['music_file']['name'];
|
||||
$extension = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
|
||||
|
||||
$allowedExt = ['mp3', 'wav', 'ogg'];
|
||||
if (!in_array($extension, $allowedExt, true)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Falsches Format (Endung)']);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mimeType = $finfo->file($tmpPath);
|
||||
$allowedMime = ['audio/mpeg', 'audio/wav', 'audio/x-wav', 'audio/ogg', 'application/ogg'];
|
||||
|
||||
if (!in_array($mimeType, $allowedMime, true)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Dateiinhalt ist kein gültiges Audio']);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$filename = uniqid('userupload_', true) . '.' . $extension;
|
||||
$destination = $uploadDir . $filename;
|
||||
$normalPath = $normalDir . $filename;
|
||||
|
||||
|
||||
if (!move_uploaded_file($tmpPath, $destination)) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($isTrainer && $maxLengthMusic !== null && intval($maxLengthMusic) !== 0) {
|
||||
require $baseDir . '/../composer/vendor/autoload.php';
|
||||
|
||||
$getID3 = new getID3;
|
||||
$fileInfo = $getID3->analyze($destination);
|
||||
|
||||
if (empty($fileInfo['playtime_seconds'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Fehler beim Bestimmen der Musiklänge'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$duration = (float) $fileInfo['playtime_seconds'];
|
||||
|
||||
if ($duration > intval($maxLengthMusic)) {
|
||||
unlink($destination);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Musik zu lange (über ' . intval($maxLengthMusic) . ' Sekunden)'
|
||||
]);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$sql = "INSERT INTO $tableAudiofiles (`file_name`,`file_path`) VALUES (?, ?)";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("ss", $originalName, $normalPath);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = $mysqli->insert_id;
|
||||
|
||||
$stmt->close();
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'id' => $id,
|
||||
'filename' => $originalName,
|
||||
'filepath' => $normalPath
|
||||
]);
|
||||
10
www/intern/scripts/db/migrations/multi_run_support.sql
Normal file
10
www/intern/scripts/db/migrations/multi_run_support.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
-- 1. Update the Noten table to include run_number
|
||||
-- NOTE: We also update the PRIMARY KEY to include this new column
|
||||
ALTER TABLE `a4b9577448d6_noten`
|
||||
ADD COLUMN `run_number` TINYINT(3) UNSIGNED NOT NULL DEFAULT 1 AFTER `jahr`,
|
||||
DROP PRIMARY KEY,
|
||||
ADD PRIMARY KEY (`person_id`, `note_bezeichnung_id`, `geraet_id`, `jahr`, `run_number`);
|
||||
|
||||
-- 2. Update the configuration table to support program-specific run counts
|
||||
ALTER TABLE `a4b9577448d6_noten_bezeichnungen`
|
||||
ADD COLUMN `anzahl_laeufe_json` TEXT NULL DEFAULT NULL AFTER `pro_geraet`;
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
// ---------- Get and sanitize input ----------
|
||||
$type = isset($_GET['type']) ? preg_replace('/[^a-zA-Z0-9 _-]/', '', $_GET['type']) : '';
|
||||
|
||||
$allowed_types = ['logo','scoring','ctext'];
|
||||
if (!in_array($type, $allowed_types)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid type']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($type === 'ctext'){
|
||||
$ctext = isset($_GET['ctext']) ? $_GET['ctext'] : '';
|
||||
}
|
||||
|
||||
$folder = realpath($baseDir.'/displays/json');
|
||||
if ($folder === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Could not find displays folder.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = 'config.json';
|
||||
$filepath = $folder . '/' . $filename;
|
||||
|
||||
if (!is_writable($folder)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Folder not writable: ' . $folder]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$jsonString = file_get_contents($filepath);
|
||||
|
||||
// decode JSON, fallback to empty array if invalid
|
||||
$oldjson = json_decode($jsonString, true) ?? [];
|
||||
|
||||
$oldjson["type"] = $type;
|
||||
|
||||
if ($type === 'ctext'){
|
||||
$oldjson["ctext"] = $ctext;
|
||||
}
|
||||
|
||||
$jsonData = json_encode($oldjson);
|
||||
|
||||
|
||||
|
||||
// Write file
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Failed to write JSON file: ' . $filepath
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'JSON type updated',
|
||||
'disable_start_button' => true
|
||||
]);
|
||||
exit;
|
||||
89
www/intern/scripts/einstellungen/ajax-change-value.php
Normal file
89
www/intern/scripts/einstellungen/ajax-change-value.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$allowedTypes = [
|
||||
'wkName',
|
||||
'displayColourLogo',
|
||||
'displayTextColourLogo',
|
||||
'displayColorScoringBg',
|
||||
'displayColorScoringBgSoft',
|
||||
'displayColorScoringPanel',
|
||||
'displayColorScoringPanelSoft',
|
||||
'displayColorScoringPanelText',
|
||||
'displayColorScoringPanelTextSoft',
|
||||
'displayColorScoringPanelTextNoteL',
|
||||
'displayColorScoringPanelTextNoteR',
|
||||
'displayIdNoteL',
|
||||
'displayIdNoteR',
|
||||
'rechnungenName',
|
||||
'rechnungenVorname',
|
||||
'rechnungenStrasse',
|
||||
'rechnungenHausnummer',
|
||||
'rechnungenPostleitzahl',
|
||||
'rechnungenOrt',
|
||||
'rechnungenIBAN',
|
||||
'maxLengthMusic',
|
||||
'linkWebseite',
|
||||
'rangNote',
|
||||
'orderBestRang'
|
||||
];
|
||||
$type = $_POST['type'] ? trim($_POST['type']) : '';
|
||||
|
||||
if (!in_array($type, $allowedTypes)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid input']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$value = $_POST['value'] ? trim($_POST['value']) : null;
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableVar (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
|
||||
if (!$stmt) {
|
||||
echo json_encode(['success' => false, 'message' => 'Critical db error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param("ss", $type, $value);
|
||||
$success = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if (!$success) {
|
||||
echo json_encode(['success' => false, 'message' => 'Insert failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Return JSON
|
||||
echo json_encode([
|
||||
'success' => true
|
||||
]);
|
||||
exit;
|
||||
84
www/intern/scripts/einstellungen/ajax-gereate-management.php
Normal file
84
www/intern/scripts/einstellungen/ajax-gereate-management.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
$type = 'wkl';
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add') {
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$start_index = intval($_POST['start_index'] ?? 0);
|
||||
$color = trim($_POST['color'] ?? '#424242');
|
||||
|
||||
if (!$name) {
|
||||
echo json_encode(['success' => false, 'message' => 'Name ist erforderlich.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableGeraete (name, start_index, color_kampfrichter) VALUES (?, ?, ?)");
|
||||
$stmt->bind_param("sis", $name, $start_index, $color);
|
||||
$success = $stmt->execute();
|
||||
$new_id = $mysqli->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
if ($success) {
|
||||
echo json_encode(['success' => true, 'id' => $new_id]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler beim Hinzufügen.']);
|
||||
}
|
||||
|
||||
} elseif ($action === 'update') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
$field = $_POST['field'] ?? '';
|
||||
$value = $_POST['value'] ?? '';
|
||||
|
||||
$allowedFields = ['name', 'start_index', 'color_kampfrichter'];
|
||||
if ($id > 0 && in_array($field, $allowedFields)) {
|
||||
if ($field === 'start_index') {
|
||||
$value = intval($value);
|
||||
}
|
||||
|
||||
$updated = db_update($mysqli, $tableGeraete, [$field => $value], ['id' => $id]);
|
||||
if ($updated !== false) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'DB Update failed.']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid parameters.']);
|
||||
}
|
||||
|
||||
} elseif ($action === 'delete') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
|
||||
if ($id > 0) {
|
||||
db_delete($mysqli, $tableGeraete, ['id' => $id]);
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID.']);
|
||||
}
|
||||
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Action not found.']);
|
||||
}
|
||||
261
www/intern/scripts/einstellungen/ajax-noten-management.php
Normal file
261
www/intern/scripts/einstellungen/ajax-noten-management.php
Normal file
@@ -0,0 +1,261 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set("display_errors", 1);
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
$type = 'wkl';
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$recalculateJSONs = false;
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add') {
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$type_val = $_POST['type_val'] ?? 'input';
|
||||
$berechnung = trim($_POST['berechnung'] ?? '');
|
||||
$pro_geraet = intval($_POST['pro_geraet'] ?? 0);
|
||||
$default_value = (isset($_POST['default_value'])) ? floatval($_POST['default_value']) : null;
|
||||
$min_value = (isset($_POST['min_value'])) ? floatval($_POST['min_value']) : null;
|
||||
$max_value = (isset($_POST['max_value'])) ? floatval($_POST['max_value']) : null;
|
||||
|
||||
$id = (isset($_POST['id'])) ? floatval($_POST['id']) : 1;
|
||||
|
||||
if (!$id) {
|
||||
echo json_encode(['success' => false, 'message' => 'Id ist erforderlich.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT 1 FROM $tableNotenBezeichnungen WHERE id = ?");
|
||||
$stmt->bind_param("i", $id);
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Eine Note mit dieser Id existiert bereits.'
|
||||
]);
|
||||
$stmt->close();
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
|
||||
if (!$name) {
|
||||
echo json_encode(['success' => false, 'message' => 'Name ist erforderlich.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableNotenBezeichnungen (id, name, type, berechnung, pro_geraet, default_value, min_value, max_value) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param("isssisss", $id, $name, $type_val, $berechnung, $pro_geraet, $default_value, $min_value, $max_value);
|
||||
$success = $stmt->execute();
|
||||
$new_id = $mysqli->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
$recalculateJSONs = true;
|
||||
|
||||
if ($success) {
|
||||
if (!$recalculateJSONs) { echo json_encode(['success' => true, 'id' => $new_id]); }
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler beim Hinzufügen.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
} elseif ($action === 'update') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
$field = $_POST['field'] ?? '';
|
||||
$value = $_POST['value'] ?? '';
|
||||
|
||||
$allowedFields = ['name', 'type', 'berechnung', 'pro_geraet', 'geraete_json', 'anzahl_laeufe_json', 'default_value', 'min_value', 'max_value', 'zeige_in_tabelle', 'zeige_in_tabelle_mobile', 'zeige_in_tabelle_admin', 'zeige_auf_rangliste', 'nullstellen', 'prefix_display'];
|
||||
if ($id > 0 && in_array($field, $allowedFields)) {
|
||||
if ($field === 'pro_geraet') {
|
||||
$value = intval($value);
|
||||
}
|
||||
|
||||
if ($field === 'berechnung' || $field === 'type') {
|
||||
$recalculateJSONs = true;
|
||||
}
|
||||
|
||||
$updated = db_update($mysqli, $tableNotenBezeichnungen, [$field => $value], ['id' => $id]);
|
||||
if ($updated !== false) {
|
||||
if (!$recalculateJSONs) { echo json_encode(['success' => true]); }
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'DB Update failed.']);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid parameters.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
} elseif ($action === 'delete') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
|
||||
if ($id > 0) {
|
||||
db_delete($mysqli, $tableNotenBezeichnungen, ['id' => $id]);
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID.']);
|
||||
}
|
||||
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Action not found.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($recalculateJSONs) {
|
||||
$noten = db_select($mysqli, $tableNotenBezeichnungen, "id, berechnung, type");
|
||||
|
||||
// 1. Re-index the array so the keys match the database IDs
|
||||
$notenById = array_column($noten, null, 'id');
|
||||
|
||||
$berechnungen = [];
|
||||
foreach ($notenById as $id => $sn) {
|
||||
if ($sn['type'] === 'berechnung') {
|
||||
$berechnungen[] = $sn;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($berechnungen)) {
|
||||
echo json_encode(['success' => true, 'message' => "Keine Berechnungen ausgewählt"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . "/../scripts/string-calculator/string-calculator-functions.php";
|
||||
$notenRechner = new NotenRechner();
|
||||
|
||||
// 1. Build the direct map
|
||||
// Format: [ Changed_Note_ID => [ "CalcId|GeraetId" => [CalcId, GeraetId] ] ]
|
||||
$dependencyMap = [];
|
||||
|
||||
foreach ($berechnungen as $calc) {
|
||||
$neededIdsArray = $notenRechner->getBenoetigteIdsComplex($calc['berechnung']);
|
||||
|
||||
if (empty($neededIdsArray)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$calcId = (int)$calc['id'];
|
||||
|
||||
foreach ($neededIdsArray as $needed) {
|
||||
|
||||
$nId = (int)$needed['noteId'];
|
||||
|
||||
// Keep geraetId as integer if it's a number (e.g., 3), otherwise string ('S')
|
||||
$gId = is_numeric($needed['geraetId']) ? (int)$needed['geraetId'] : $needed['geraetId'];
|
||||
|
||||
// Create a unique string key so we don't store exact duplicates
|
||||
$nodeKey = $calcId . '|' . $gId;
|
||||
|
||||
if (!isset($dependencyMap[$nId])) {
|
||||
$dependencyMap[$nId] = [];
|
||||
}
|
||||
|
||||
// Store it as the "little array" you requested: [DependentCalcId, GeraetId]
|
||||
$dependencyMap[$nId][$nodeKey] = [$calcId, $gId];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Our recursive helper function (Updated for complex nodes)
|
||||
function getCompleteDependencyChain($id, $directMap, $visited = [])
|
||||
{
|
||||
// If this ID doesn't have anything depending on it, return empty
|
||||
if (!isset($directMap[$id])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$allDependencies = [];
|
||||
|
||||
foreach ($directMap[$id] as $nodeKey => $complexNode) {
|
||||
// CIRCULAR DEPENDENCY CHECK:
|
||||
// We check against the string key (e.g., "10|S") to prevent infinite loops
|
||||
if (isset($visited[$nodeKey])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. Mark this specific node as visited
|
||||
$visited[$nodeKey] = true;
|
||||
|
||||
// 2. Add the little array [CalcId, GeraetId] to our master list
|
||||
$allDependencies[$nodeKey] = $complexNode;
|
||||
|
||||
// 3. Recursively find everything that depends on THIS calculation ID
|
||||
// $complexNode[0] is the dependent Calc ID
|
||||
$childDependencies = getCompleteDependencyChain($complexNode[0], $directMap, $visited);
|
||||
|
||||
// 4. Merge the child results into our master list safely
|
||||
foreach ($childDependencies as $childKey => $childNode) {
|
||||
$allDependencies[$childKey] = $childNode;
|
||||
$visited[$childKey] = true; // Ensure the parent loop knows this was visited
|
||||
}
|
||||
}
|
||||
|
||||
return $allDependencies;
|
||||
}
|
||||
|
||||
|
||||
// 3. Create the final flattened map for ALL IDs
|
||||
$flatDependencyMap = [];
|
||||
|
||||
foreach (array_keys($notenById) as $id) {
|
||||
$chain = getCompleteDependencyChain($id, $dependencyMap);
|
||||
|
||||
// Only add it if dependencies exist
|
||||
if (!empty($chain)) {
|
||||
// array_values() removes the "10|S" string keys, turning it into a perfect
|
||||
// 0-indexed array for clean JSON encoding: [[10, "S"], [12, 3]]
|
||||
$flatDependencyMap[$id] = array_values($chain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 4. Database Updates
|
||||
// Step 1: Reset all rows to NULL in a single query
|
||||
$resetSql = "UPDATE $tableNotenBezeichnungen SET `berechnung_json` = NULL";
|
||||
$mysqli->query($resetSql);
|
||||
|
||||
// Step 2: Prepare the statement
|
||||
$updateSql = "UPDATE $tableNotenBezeichnungen SET `berechnung_json` = ? WHERE id = ?";
|
||||
$stmt = $mysqli->prepare($updateSql);
|
||||
|
||||
foreach ($flatDependencyMap as $id => $completeDependencyArray) {
|
||||
if (empty($completeDependencyArray)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$jsonString = json_encode($completeDependencyArray);
|
||||
|
||||
// Bind parameters: 's' for string (JSON), 'i' for integer (ID)
|
||||
$stmt->bind_param("si", $jsonString, $id);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
echo json_encode(['success' => true, 'message' => "Abhaengigkeiten berechnet"]);
|
||||
exit;
|
||||
}
|
||||
204
www/intern/scripts/einstellungen/ajax-upload-image.php
Normal file
204
www/intern/scripts/einstellungen/ajax-upload-image.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Upload Image API
|
||||
* Accepts multipart/form-data POST with 'image' file.
|
||||
* Converts JPG/PNG to WebP (resized to max 2400px), saves to /files/img/admin_upload/{uid}.webp
|
||||
* Returns JSON: { success: true }
|
||||
*/
|
||||
|
||||
// Allow large uploads and enough memory for GD processing
|
||||
ini_set('memory_limit', '256M');
|
||||
ini_set('upload_max_filesize', '50M');
|
||||
ini_set('post_max_size', '55M');
|
||||
ini_set('max_execution_time', '120');
|
||||
|
||||
const MAX_DIMENSION = 2400;
|
||||
const MAX_DIMENSION_ICON = 1000;
|
||||
const WEBP_QUALITY = 80;
|
||||
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
session_start();
|
||||
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
|
||||
// Only accept POST
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$allowedTypes = ['Kampfrichter', 'Trainer', 'Wk_leitung', 'Otl', 'icon', 'logo-normal'];
|
||||
|
||||
if (!isset($_POST['type']) || !in_array($_POST['type'], $allowedTypes)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Typ nicht angegeben oder nicht erlaubt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pngs = ['icon', 'logo-normal'];
|
||||
|
||||
$type = $_POST['type'];
|
||||
$isIcon = in_array($type, $pngs);
|
||||
|
||||
// Check if $_FILES is empty entirely (can happen if post_max_size exceeded)
|
||||
if (empty($_FILES)) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'No files received. The file may exceed the server upload limit).',
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check specific file field
|
||||
if (!isset($_FILES['image'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'No "image" field in upload. Received fields: ' . implode(', ', array_keys($_FILES)),
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) {
|
||||
http_response_code(400);
|
||||
$errors = [
|
||||
UPLOAD_ERR_INI_SIZE => 'File exceeds upload_max_filesize',
|
||||
UPLOAD_ERR_FORM_SIZE => 'File exceeds form MAX_FILE_SIZE',
|
||||
UPLOAD_ERR_PARTIAL => 'File was only partially uploaded',
|
||||
UPLOAD_ERR_NO_FILE => 'No file was uploaded',
|
||||
UPLOAD_ERR_NO_TMP_DIR => 'Missing temp directory',
|
||||
UPLOAD_ERR_CANT_WRITE => 'Failed to write to disk',
|
||||
];
|
||||
$code = $_FILES['image']['error'];
|
||||
$msg = $errors[$code] ?? "Unknown error code: $code";
|
||||
echo json_encode(['success' => false, 'message' => $msg]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $_FILES['image'];
|
||||
$tmpPath = $file['tmp_name'];
|
||||
|
||||
// Validate MIME type
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mime = $finfo->file($tmpPath);
|
||||
|
||||
$allowedMimes = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
|
||||
if (!in_array($mime, $allowedMimes, true)) {
|
||||
http_response_code(415);
|
||||
echo json_encode(['success' => false, 'message' => "Unsupported file type: $mime"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Target directory
|
||||
|
||||
|
||||
if ($isIcon) {
|
||||
$uploadDir = $baseDir . '/intern/img/';
|
||||
} else {
|
||||
$uploadDir = $baseDir . '/intern/img/login';
|
||||
}
|
||||
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
// Load image into GD
|
||||
$srcImage = null;
|
||||
switch ($mime) {
|
||||
case 'image/jpeg':
|
||||
$srcImage = @imagecreatefromjpeg($tmpPath);
|
||||
break;
|
||||
case 'image/png':
|
||||
$srcImage = @imagecreatefrompng($tmpPath);
|
||||
break;
|
||||
case 'image/webp':
|
||||
$srcImage = @imagecreatefromwebp($tmpPath);
|
||||
break;
|
||||
case 'image/gif':
|
||||
$srcImage = @imagecreatefromgif($tmpPath);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$srcImage) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to load image into GD. It may be corrupt or too large.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// ── Resize if needed ────────────────────────────────
|
||||
$origW = imagesx($srcImage);
|
||||
$origH = imagesy($srcImage);
|
||||
|
||||
$maxDimension = ($isIcon) ? MAX_DIMENSION_ICON : MAX_DIMENSION;
|
||||
|
||||
if ($origW > $maxDimension || $origH > $maxDimension) {
|
||||
// Calculate new dimensions keeping aspect ratio
|
||||
if ($origW >= $origH) {
|
||||
$newW = $maxDimension;
|
||||
$newH = intval(round($origH * ($maxDimension / $origW)));
|
||||
} else {
|
||||
$newH = $maxDimension;
|
||||
$newW = intval(round($origW * ($maxDimension / $origH)));
|
||||
}
|
||||
|
||||
$resized = imagecreatetruecolor($newW, $newH);
|
||||
|
||||
// Preserve transparency
|
||||
imagealphablending($resized, false);
|
||||
imagesavealpha($resized, true);
|
||||
$transparent = imagecolorallocatealpha($resized, 0, 0, 0, 127);
|
||||
imagefill($resized, 0, 0, $transparent);
|
||||
|
||||
imagecopyresampled($resized, $srcImage, 0, 0, 0, 0, $newW, $newH, $origW, $origH);
|
||||
imagedestroy($srcImage);
|
||||
$srcImage = $resized;
|
||||
} else {
|
||||
// Still preserve transparency
|
||||
imagepalettetotruecolor($srcImage);
|
||||
imagealphablending($srcImage, true);
|
||||
imagesavealpha($srcImage, true);
|
||||
}
|
||||
|
||||
if ($isIcon) {
|
||||
// ── Save as PNG ────────────────────────────────────
|
||||
$filename = $type . '.png';
|
||||
$destPath = $uploadDir . '/' . $filename;
|
||||
$webPath = '/intern/img/' . $filename;
|
||||
|
||||
$pngCompression = 6;
|
||||
|
||||
$success = imagepng($srcImage, $destPath, $pngCompression);
|
||||
} else {
|
||||
// ── Save as WebP ────────────────────────────────────
|
||||
$filename = 'bg' . $_POST['type'] . '.webp';
|
||||
$destPath = $uploadDir . '/' . $filename;
|
||||
$webPath = '/intern/img/admin_upload/' . $filename;
|
||||
|
||||
$success = imagewebp($srcImage, $destPath, WEBP_QUALITY);
|
||||
}
|
||||
|
||||
imagedestroy($srcImage);
|
||||
|
||||
if (!$success) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to convert to WebP']);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true
|
||||
]);
|
||||
@@ -0,0 +1,321 @@
|
||||
<?php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
session_start();
|
||||
|
||||
if (
|
||||
empty($_SESSION['access_granted_kampfrichter']) ||
|
||||
$_SESSION['access_granted_kampfrichter'] !== true ||
|
||||
empty($_SESSION['passcodekampfrichter_id']) ||
|
||||
intval($_SESSION['passcodekampfrichter_id']) < 1
|
||||
) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
if (!verify_csrf()) {
|
||||
echo json_encode(['success' => false, 'message' => 'Forbidden']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validate editId from POST
|
||||
if (isset($_POST['editId'])) {
|
||||
$editId = intval($_POST['editId']);
|
||||
if ($editId === false || $editId < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Falsche Personen ID']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
$editId = filter_var($editId, FILTER_VALIDATE_INT);
|
||||
|
||||
if ($editId === false) {
|
||||
echo json_encode(['success' => true]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if (!($data['success'] ?? false)) {
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$isAdmin = (($_SESSION['selectedFreigabeKampfrichter'] ?? '') === 'admin') ? true : false;
|
||||
|
||||
$disciplines = db_select($mysqli, $tableGeraete, 'id', '', [], 'start_index ASC');
|
||||
|
||||
$disciplines = array_column($disciplines, "id");
|
||||
|
||||
if (!$isAdmin) {
|
||||
|
||||
$discipline = intval($_POST['geraet']) ?? 0;
|
||||
|
||||
if (!in_array($discipline, $disciplines)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Falsche Geräte ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$disciplines = [$discipline];
|
||||
|
||||
|
||||
$stmt = $mysqli->prepare("
|
||||
SELECT
|
||||
t.name,
|
||||
t.vorname,
|
||||
t.programm,
|
||||
p.id as programm_id,
|
||||
agg.abteilung,
|
||||
agg.geraeteIndex,
|
||||
agg.startIndex
|
||||
FROM $tableTurnerinnen t
|
||||
LEFT JOIN $tableProgramme p ON p.programm = t.programm
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
ta.turnerin_id,
|
||||
GROUP_CONCAT(DISTINCT a.name SEPARATOR ', ') AS abteilung,
|
||||
GROUP_CONCAT(DISTINCT g.start_index SEPARATOR ', ') AS geraeteIndex,
|
||||
ta.turnerin_index AS startIndex
|
||||
FROM $tableTurnerinnenAbt ta
|
||||
INNER JOIN $tableAbt a
|
||||
ON a.id = ta.abteilung_id
|
||||
LEFT JOIN $tableGeraete g
|
||||
ON g.id = ta.geraet_id
|
||||
GROUP BY ta.turnerin_id
|
||||
) agg ON agg.turnerin_id = t.id
|
||||
WHERE t.id = ?
|
||||
");
|
||||
|
||||
} else {
|
||||
$stmt = $mysqli->prepare("SELECT t.`name`, t.`vorname`, t.`programm`, p.id as programm_id FROM $tableTurnerinnen t LEFT JOIN $tableProgramme p ON p.programm = t.programm WHERE t.id = ?");
|
||||
}
|
||||
|
||||
$stmt->bind_param('i', $editId);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$dbresult = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if (!$dbresult || !is_array($dbresult) || count($dbresult) < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Falsche Personen ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$now = new DateTime();
|
||||
|
||||
$jahr = ($now->format('n') > 6) ? $now->modify('+1 year')->format('Y') : $now->format('Y');
|
||||
|
||||
if ($isAdmin) {
|
||||
$stmt = $mysqli->prepare("SELECT `note_bezeichnung_id`, `value`, `geraet_id`, `run_number` FROM $tableNoten WHERE `person_id` = ? AND `jahr` = ?");
|
||||
|
||||
$stmt->bind_param('ss', $editId, $jahr);
|
||||
} else {
|
||||
$stmt = $mysqli->prepare("SELECT `note_bezeichnung_id`, `value`, `geraet_id`, `run_number` FROM $tableNoten WHERE `person_id` = ? AND `geraet_id` = ? AND `jahr` = ?");
|
||||
|
||||
$stmt->bind_param('sss', $editId, $discipline, $jahr);
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$notenDB = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
|
||||
$indexedNotenDB = [];
|
||||
foreach ($notenDB as $sn) {
|
||||
$indexedNotenDB[$sn['geraet_id']][$sn['note_bezeichnung_id']][$sn['run_number']] = $sn['value'];
|
||||
}
|
||||
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT `id`, `default_value`, `nullstellen`, `pro_geraet`, `geraete_json`, `anzahl_laeufe_json` FROM $tableNotenBezeichnungen");
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$notenConfig = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$noten = [];
|
||||
|
||||
$row = $dbresult[0];
|
||||
|
||||
$programm_id = $row['programm_id'];
|
||||
|
||||
foreach ($disciplines as $d) {
|
||||
foreach ($notenConfig as $snC) {
|
||||
$allowedGeraete = !empty($snC['geraete_json']) ? json_decode($snC['geraete_json'], true) : [];
|
||||
$isProGeraet = ($snC['pro_geraet'] === 1);
|
||||
|
||||
if (!$isProGeraet && !in_array($d, $allowedGeraete)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Determine number of runs for this program
|
||||
$anzRunsConfig = !empty($snC['anzahl_laeufe_json']) ? json_decode($snC['anzahl_laeufe_json'], true) : [];
|
||||
|
||||
$runs = $anzRunsConfig[$programm_id] ?? $anzRunsConfig['default'] ?? 1;
|
||||
|
||||
for ($r = 1; $r <= $runs; $r++) {
|
||||
$value = $indexedNotenDB[$d][$snC['id']][$r] ?? $snC['default_value'] ?? 0;
|
||||
$noten[$d][$snC['id']][$r] = number_format($value, $snC['nullstellen'] ?? 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$titel = $row['vorname'].' '.$row['name'].', '.$row['programm'];
|
||||
|
||||
if (!$isAdmin) {
|
||||
|
||||
// $entries = db_select($mysqli, $tableTurnerinnen, 'name, vorname, programm, id', 'abteilung = ? AND startgeraet = ?', [$row['abteilung'], $row['startgeraet']]);
|
||||
|
||||
$stmt = $mysqli->prepare("
|
||||
SELECT
|
||||
t.name,
|
||||
t.vorname,
|
||||
t.programm,
|
||||
t.id,
|
||||
agg.abteilung,
|
||||
agg.geraeteIndex,
|
||||
agg.startIndex
|
||||
FROM $tableTurnerinnen t
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
ta.turnerin_id,
|
||||
GROUP_CONCAT(DISTINCT a.name SEPARATOR ', ') AS abteilung,
|
||||
GROUP_CONCAT(DISTINCT g.start_index SEPARATOR ', ') AS geraeteIndex,
|
||||
ta.turnerin_index AS startIndex
|
||||
FROM $tableTurnerinnenAbt ta
|
||||
INNER JOIN $tableAbt a
|
||||
ON a.id = ta.abteilung_id
|
||||
LEFT JOIN $tableGeraete g
|
||||
ON g.id = ta.geraet_id
|
||||
GROUP BY ta.turnerin_id
|
||||
) agg ON agg.turnerin_id = t.id
|
||||
WHERE agg.abteilung = ? AND agg.geraeteIndex = ?
|
||||
ORDER BY t.id DESC
|
||||
");
|
||||
|
||||
|
||||
$bezahlt = 2;
|
||||
$bezahltoverride = 5;
|
||||
|
||||
$stmt->bind_param('ss', $row['abteilung'], $row['geraeteIndex']);
|
||||
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$entries = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if (!$entries || !is_array($entries) || count($entries) < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'No DB Result for next Turnerin']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$maxstartindex = count($entries);
|
||||
|
||||
if ($maxstartindex < 1) {
|
||||
$maxstartindex = 1;
|
||||
}
|
||||
|
||||
$csti = (int)$row['startIndex'];
|
||||
$nsti = $csti + 1;
|
||||
|
||||
if ($nsti > $maxstartindex){
|
||||
$nsti -= $maxstartindex;
|
||||
}
|
||||
|
||||
$rohstartindex = intval($row['startIndex']);
|
||||
$varstartgeraet = intval($row['geraeteIndex']);
|
||||
|
||||
$aktsubabt = $_SESSION['currentsubabt'];
|
||||
|
||||
foreach ($disciplines as $index => $sdiscipline) {
|
||||
if (isset($sdiscipline) && $sdiscipline === $discipline) {
|
||||
$indexuser = $index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
$calculedstartindex = $rohstartindex - $indexuser;
|
||||
|
||||
$calculedstartindex = $calculedstartindex >= 1 ? $calculedstartindex : $calculedstartindex + $maxstartindex;
|
||||
|
||||
|
||||
$nrow = null;
|
||||
|
||||
if ($calculedstartindex !== count($entries)){
|
||||
$nrow = null;
|
||||
|
||||
foreach ($entries as $entry) {
|
||||
if ($entry['startIndex'] == $nsti) {
|
||||
$nrow = $entry;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($nrow) {
|
||||
$nturnerin = [
|
||||
'name' => $nrow['vorname'].' '.$nrow['name'].', '.$nrow['programm'],
|
||||
'id' => $nrow['id']
|
||||
];
|
||||
} else {
|
||||
$nturnerin = [
|
||||
'name' => '--- nächste Gruppe ---',
|
||||
'id' => 0
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($isAdmin) {
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'id' => $editId,
|
||||
'programm_id' => $programm_id,
|
||||
'titel' => $titel,
|
||||
'noten' => $noten
|
||||
]);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'id' => $editId,
|
||||
'programm_id' => $programm_id,
|
||||
'titel' => $titel,
|
||||
'noten' => $noten,
|
||||
'nturnerin' => $nturnerin
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
327
www/intern/scripts/kampfrichter/ajax/ajax-neu_protokoll.php
Normal file
327
www/intern/scripts/kampfrichter/ajax/ajax-neu_protokoll.php
Normal file
@@ -0,0 +1,327 @@
|
||||
<?php
|
||||
|
||||
/*ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);*/
|
||||
|
||||
// Start session if not already started
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Check access
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true ||
|
||||
empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validate POST input
|
||||
if (!isset($_POST['abteilung'])) {
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
|
||||
$abteilung = trim($_POST['abteilung']);
|
||||
|
||||
$disciplines = db_select($mysqli, $tableGeraete, '*', '', [], 'start_index ASC');
|
||||
|
||||
|
||||
|
||||
// Load TCPDF
|
||||
require $baseDir . '/wp-content/uploads/TCPDF-main/tcpdf.php';
|
||||
|
||||
$current_year = (date('n') > 6) ? date('Y') + 1 : date('Y');
|
||||
|
||||
class MYPDF extends TCPDF
|
||||
{
|
||||
public $current_year;
|
||||
public $abteilung;
|
||||
// Page header
|
||||
public function Header()
|
||||
{
|
||||
$image_file = 'https://kutu-tage-beider-basel.testseite-fh-ht.ch/wp-content/uploads/2025/06/ktbb-logo.png';
|
||||
$this->SetY(15);
|
||||
$this->SetFont('helvetica', 'B', 20);
|
||||
$this->Cell(0, 0, 'Protokoll Kutu-Tage beider Basel ' . $this->current_year . ' Abt. ' . $this->abteilung, 0, false, 'L', 0, '', 0, false, 'M', 'M');
|
||||
$this->Image($image_file, 272, 5, 15, '', 'PNG', '', 'T', false, 300, '', false, false, 0, false, false, false);
|
||||
}
|
||||
|
||||
// Page footer
|
||||
public function Footer()
|
||||
{
|
||||
$this->SetY(-15);
|
||||
$this->SetFont('helvetica', 'I', 8);
|
||||
$this->Cell(0, 10, 'Seite ' . $this->getAliasNumPage() . ' von ' . $this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
|
||||
}
|
||||
}
|
||||
|
||||
$pdf = new MYPDF('L', 'mm', 'A4', true, 'UTF-8', false);
|
||||
//$pdf->AddFont('outfit-bold', '', 'outfitb.php');
|
||||
|
||||
|
||||
$pdf->current_year = $current_year;
|
||||
$pdf->abteilung = $abteilung;
|
||||
|
||||
$pdf->SetCreator(PDF_CREATOR);
|
||||
$pdf->SetAuthor('Turnerinnen System');
|
||||
$pdf->SetTitle("KTBB_Protokoll_Abt." . $abteilung . "_" . $current_year . ".pdf");
|
||||
$pdf->SetMargins(10, 20, 10);
|
||||
$pdf->SetAutoPageBreak(TRUE, 10);
|
||||
$pdf->SetFont('helvetica', '', 9);
|
||||
|
||||
$startindex = 0;
|
||||
|
||||
foreach ($disciplines as $singledisciplin){
|
||||
|
||||
$startindex ++;
|
||||
|
||||
$name_kampfrichterin1 = 'Nicht eingetragen';
|
||||
$name_kampfrichterin2 = 'Nicht eingetragen';
|
||||
|
||||
// Prepare SQL statement
|
||||
$stmt = $mysqli->prepare("
|
||||
SELECT * FROM $tableKrProtokoll
|
||||
WHERE abteilung = ?
|
||||
AND geraet = ?
|
||||
");
|
||||
$stmt->bind_param('ss', $abteilung, $singledisciplin['name']);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$krresults = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
foreach ($krresults as $krresult){
|
||||
if ($krresult['aufgabe'] == 1){
|
||||
$name_kampfrichterin1 = $krresult['name'];
|
||||
} elseif ($krresult['aufgabe'] == 2){
|
||||
$name_kampfrichterin2 = $krresult['name'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($disciplines as $shiftstartindex => $subdisciplin){
|
||||
|
||||
$pdf->AddPage();
|
||||
|
||||
$pdf->Ln(10);
|
||||
$pdf->SetFont('', 'B', 14);
|
||||
$pdf->Cell(0, 0, ucfirst($singledisciplin['name']), 0, 1, 'L');
|
||||
$pdf->Ln(3);
|
||||
$pdf->SetFont('', 'I', 9);
|
||||
$newshiftindex = $shiftstartindex + 1;
|
||||
$pdf->Cell(0, 0, 'Gruppe '. $newshiftindex , 0, 1, 'L');
|
||||
$pdf->SetFont('', '');
|
||||
|
||||
$pdf->Ln(5);
|
||||
|
||||
$pdf->Cell(0, 0, '1. Kampfrichterin: ' . $name_kampfrichterin1, 0, 1, 'L');
|
||||
$pdf->Ln(2);
|
||||
$pdf->Cell(0, 0, '2. Kampfrichterin: ' . $name_kampfrichterin2, 0, 1, 'L');
|
||||
$pdf->Ln(8);
|
||||
|
||||
$startg = $shiftstartindex - $startindex;
|
||||
|
||||
if ($startg < 1) {
|
||||
$startg += 4; // shift into positive range
|
||||
}
|
||||
|
||||
// Prepare SQL statement
|
||||
|
||||
$stmt = $mysqli->prepare("
|
||||
SELECT
|
||||
t.*,
|
||||
agg.abteilung,
|
||||
agg.geraete_index,
|
||||
agg.start_index
|
||||
FROM $tableTurnerinnen t
|
||||
LEFT JOIN (
|
||||
SELECT
|
||||
ta.turnerin_id,
|
||||
GROUP_CONCAT(DISTINCT a.name SEPARATOR ', ') AS abteilung,
|
||||
GROUP_CONCAT(DISTINCT g.start_index SEPARATOR ', ') AS geraete_index,
|
||||
ta.turnerin_index AS start_index
|
||||
FROM $tableTurnerinnenAbt ta
|
||||
INNER JOIN $tableAbt a
|
||||
ON a.id = ta.abteilung_id
|
||||
LEFT JOIN $tableGeraete g
|
||||
ON g.id = ta.geraet_id
|
||||
GROUP BY ta.turnerin_id
|
||||
) agg ON agg.turnerin_id = t.id
|
||||
WHERE (t.bezahlt = ? OR t.bezahltoverride = ?) AND agg.abteilung = ? AND agg.geraete_index = ?
|
||||
ORDER BY agg.start_index DESC
|
||||
");
|
||||
|
||||
$bezahlt1 = '2';
|
||||
$bezahlt2 = '5';
|
||||
$stmt->bind_param('ssss', $bezahlt1, $bezahlt2, $abteilung, $startg);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$entries = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
|
||||
if (!empty($entries)) {
|
||||
$maxindex = $entries[0]['start_index'];
|
||||
|
||||
// Recalculate
|
||||
foreach ($entries as &$singleorderentry) {
|
||||
$singleorderentry['start_index'] -= $shiftstartindex;
|
||||
if ($singleorderentry['start_index'] < 1) {
|
||||
$singleorderentry['start_index'] += $maxindex;
|
||||
}
|
||||
}
|
||||
unset($singleorderentry); // break the reference
|
||||
|
||||
// Reorder by recalculated startindex (ascending)
|
||||
usort($entries, function($a, $b) {
|
||||
return $a['start_index'] <=> $b['start_index'];
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Define columns (including discipline sub-columns)
|
||||
$columns = [
|
||||
'start_index' => ['header' => 'Str.'],
|
||||
'name' => ['header' => 'Name'],
|
||||
'vorname' => ['header' => 'Vorname'],
|
||||
'programm' => ['header' => 'Programm'],
|
||||
'geburtsdatum' => ['header' => 'Jg.'],
|
||||
'verein' => ['header' => 'Verein'],
|
||||
'e1 note '.strtolower($subdisciplin['name']) => ['header' => 'E1 Note '.ucfirst($subdisciplin['name'])],
|
||||
'e2 note '.strtolower($subdisciplin['name']) => ['header' => 'E2 Note '.ucfirst($subdisciplin['name'])],
|
||||
'e note '.strtolower($subdisciplin['name']) => ['header' => 'E Note '.ucfirst($subdisciplin['name'])],
|
||||
'd-note '.strtolower($subdisciplin['name']) => ['header' => 'D Note '.ucfirst($subdisciplin['name'])],
|
||||
'neutrale abzuege '.strtolower($subdisciplin['name']) => ['header' => 'N. Abzüge '.ucfirst($subdisciplin['name'])],
|
||||
'note '.strtolower($subdisciplin['name']) => ['header' => 'Note '.ucfirst($subdisciplin['name'])],
|
||||
];
|
||||
|
||||
// Initialize max widths with header widths (+4 mm padding)
|
||||
foreach ($columns as $key => &$col) {
|
||||
$col['max_width'] = $pdf->GetStringWidth($col['header']) + 4;
|
||||
}
|
||||
|
||||
// Calculate max width of each column based on all data
|
||||
foreach ($entries as $r) {
|
||||
foreach ($columns as $key => &$col) {
|
||||
isset($r[$key]) ? $r[$key] : '';
|
||||
$text = '';
|
||||
|
||||
// Handle different column types
|
||||
if ($key === 'start_index' && !empty($r['start_index'])) {
|
||||
$text = (int)$r[$key];
|
||||
} elseif ($key === 'geburtsdatum' && !empty($r['geburtsdatum'])) {
|
||||
$text = (new DateTime($r['geburtsdatum']))->format('Y');
|
||||
} elseif (strpos($key, 'd-note') === 0 && isset($r[$key]) && is_numeric($r[$key])) {
|
||||
$text = number_format((float)$r[$key], 2, '.', ''); // 2 decimals
|
||||
} elseif (isset($r[$key]) && is_numeric($r[$key])) {
|
||||
$text = number_format((float)$r[$key], 3, '.', ''); // 3 decimals
|
||||
} elseif (isset($r[$key])) {
|
||||
$text = (string)$r[$key];
|
||||
} else {
|
||||
$text = '';
|
||||
}
|
||||
|
||||
// Calculate width with padding
|
||||
$w = $pdf->GetStringWidth($text) + 4;
|
||||
|
||||
// Update max width
|
||||
if ($w > $col['max_width']) {
|
||||
$col['max_width'] = $w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($col);
|
||||
$columns['geburtsdatum']['max_width'] = $pdf->GetStringWidth("0000") + 4;
|
||||
|
||||
// Print first header row
|
||||
$pdf->SetFont('', 'B');
|
||||
foreach ($columns as $key => $col) {
|
||||
if (
|
||||
$key === 'd-note' || // only column with dash
|
||||
strpos($key, 'note') === 0 || // matches 'note...' at start
|
||||
strpos($key, 'e note') === 0 || // matches 'e-note...'
|
||||
strpos($key, 'e1 note') === 0 || // matches 'e1 note ...'
|
||||
strpos($key, 'e2 note') === 0 || // matches 'e2 note ...'
|
||||
strpos($key, 'neutrale abzuege') === 0 ||
|
||||
$key === 'geburtsdatum' ||
|
||||
$key === 'start_index'
|
||||
) {
|
||||
$align = 'C';
|
||||
} else {
|
||||
$align = 'L';
|
||||
}
|
||||
|
||||
$pdf->Cell($col['max_width'], 7, $col['header'], 0, 0, $align);
|
||||
}
|
||||
|
||||
|
||||
// Move to next line after headers
|
||||
$pdf->Ln();
|
||||
|
||||
|
||||
$pdf->SetFont('', '');
|
||||
foreach ($entries as $r) {
|
||||
foreach ($columns as $key => $col) {
|
||||
// Determine alignment
|
||||
if (strpos($key, 'note') === 0 || strpos($key, 'e note') === 0 || strpos($key, 'd-note') === 0 || strpos($key, 'neutrale abzuege') === 0 || $key === 'start_index' || $key === 'geburtsdatum' || strpos($key, 'e1 note') === 0 || strpos($key, 'e2 note') === 0){
|
||||
$align = 'C';
|
||||
} else {
|
||||
$align = 'L';
|
||||
}
|
||||
|
||||
// Format the value based on type
|
||||
if ($key === 'geburtsdatum' && !empty($r['geburtsdatum'])) {
|
||||
$text = (new DateTime($r['geburtsdatum']))->format('Y');
|
||||
} elseif (strpos($key, 'note') === 0 || strpos($key, 'e note') === 0 || strpos($key, 'd-note') === 0 || strpos($key, 'neutrale abzuege') === 0 || $key === 'gesamt' || strpos($key, 'e1 note') === 0 || strpos($key, 'e2 note') === 0){
|
||||
$text = isset($r[$key]) ? number_format((float)$r[$key], 3) : '';
|
||||
} else {
|
||||
$text = isset($r[$key]) ? $r[$key] : '';
|
||||
}
|
||||
|
||||
$pdf->Cell($col['max_width'], 6, $text, 1, 0, $align);
|
||||
}
|
||||
|
||||
$pdf->Ln(); // Move to next row
|
||||
}
|
||||
|
||||
$pdf->SetY(-50);
|
||||
if ($name_kampfrichterin1 !== 'Nicht eingetragen' || $name_kampfrichterin2 !== 'Nicht eingetragen'){
|
||||
$pdf->SetFont('', 'B');
|
||||
$pdf->Cell(0, 28, 'Unterschrift:', 0, 1, 'L');
|
||||
$pdf->SetFont('', '');
|
||||
if ($name_kampfrichterin1 !== 'Nicht eingetragen'){
|
||||
$pdf->Cell(120, 8, $name_kampfrichterin1.': ___________________________________________', 0, 0, 'L');
|
||||
}
|
||||
if ($name_kampfrichterin2 !== 'Nicht eingetragen'){
|
||||
$pdf->Cell(90, 8, $name_kampfrichterin2.': ___________________________________________', 0, 0, 'L');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Close statement
|
||||
$stmt->close();
|
||||
|
||||
$pdf->Output("Protokoll_Kutu-Tage_beider_Basel_{$current_year}_Abt_{$abteilung}.pdf", 'D');
|
||||
|
||||
|
||||
|
||||
exit;
|
||||
606
www/intern/scripts/kampfrichter/ajax/ajax-neu_rangliste.php
Normal file
606
www/intern/scripts/kampfrichter/ajax/ajax-neu_rangliste.php
Normal file
@@ -0,0 +1,606 @@
|
||||
<?php
|
||||
|
||||
use TCPDF;
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
|
||||
|
||||
// Start session if not already started
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
// Check access
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true ||
|
||||
empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validate POST input
|
||||
/*
|
||||
if (!isset($_POST['prog']) && !isset($_POST['type'])) {
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}*/
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
|
||||
|
||||
$programm = trim($_POST['prog'] ?? 'p6a');
|
||||
$buttontype = trim($_POST['type'] ?? 'export_programm');
|
||||
$upperprogramm = strtoupper($programm);
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT `id`, `name` FROM $tableGeraete ORDER BY start_index ASC");
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$geraete = $result->fetch_all(MYSQLI_ASSOC);
|
||||
$disciplines = array_map(
|
||||
'strtolower',
|
||||
array_column($geraete, 'name')
|
||||
);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
// Determine current year
|
||||
$current_year = date('Y');
|
||||
$monat = date('n');
|
||||
if ($monat > 6) $current_year++;
|
||||
|
||||
// Prepare SQL statement
|
||||
$stmt = $mysqli->prepare("
|
||||
SELECT * FROM $tableTurnerinnen
|
||||
WHERE LOWER(programm) = LOWER(?)
|
||||
AND (bezahlt = ? OR bezahltoverride = ?)
|
||||
ORDER BY rang ASC
|
||||
");
|
||||
$bezahlt1 = '2';
|
||||
$bezahlt2 = '5';
|
||||
$stmt->bind_param('sss', $programm, $bezahlt1, $bezahlt2);
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$personen = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
// Close statement
|
||||
$stmt->close();
|
||||
|
||||
// 1. Get the IDs from the first query results
|
||||
$turnerinnenIds = array_column($personen, 'id');
|
||||
|
||||
if (!empty($turnerinnenIds)) {
|
||||
// 2. Create a string of placeholders: ?,?,?
|
||||
$placeholders = implode(',', array_fill(0, count($turnerinnenIds), '?'));
|
||||
|
||||
// 3. Prepare the IN statement
|
||||
$sqlNoten = "SELECT * FROM $tableNoten WHERE person_id IN ($placeholders) AND `jahr` = ?";
|
||||
$stmtNoten = $mysqli->prepare($sqlNoten);
|
||||
|
||||
// --- FIX STARTS HERE ---
|
||||
|
||||
// 1. Combine all values into one flat array for binding
|
||||
$paramsArray = array_merge($turnerinnenIds, [$current_year]);
|
||||
|
||||
// 2. Build the types string
|
||||
// 'i' for every ID, plus 'i' (or 's') for the year
|
||||
$types = str_repeat('i', count($turnerinnenIds)) . 's';
|
||||
|
||||
// 3. Unpack the combined array into the bind_param function
|
||||
$stmtNoten->bind_param($types, ...$paramsArray);
|
||||
|
||||
// --- FIX ENDS HERE ---
|
||||
|
||||
$stmtNoten->execute();
|
||||
$notenResult = $stmtNoten->get_result();
|
||||
$notenEntries = $notenResult->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
$stmtNoten->close(); // Close inside the IF to avoid errors if IDs were empty
|
||||
} else {
|
||||
$notenEntries = [];
|
||||
}
|
||||
|
||||
$rangNote = intval(db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rangNote']));
|
||||
|
||||
var_dump($rangNote);
|
||||
|
||||
$orderBestRang = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['orderBestRang']);
|
||||
|
||||
$okValuesOrderBestRang = ["ASC", "DESC"];
|
||||
|
||||
if (!in_array($orderBestRang, $okValuesOrderBestRang)) {
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$alleNoten = db_select($mysqli, $tableNotenBezeichnungen, "id, default_value, nullstellen, pro_geraet, geraete_json, zeige_auf_rangliste, name", "zeige_auf_rangliste = ? OR id = ?", ['1', $rangNote]);
|
||||
|
||||
$displayedNoten = [];
|
||||
|
||||
foreach ($alleNoten as $sN) {
|
||||
if (intval($sN['zeige_auf_rangliste']) === 1) {
|
||||
$displayedNoten[$sN['id']] = $sN;
|
||||
}
|
||||
}
|
||||
|
||||
$ascArrayDefaultValues = array_column($alleNoten, 'default_value', 'id');
|
||||
$ascArrayGeraeteJSON = array_column($alleNoten, 'geraete_json', 'id');
|
||||
|
||||
foreach ($ascArrayGeraeteJSON as $key => $saagj) {
|
||||
$ascArrayGeraeteJSON[$key] = json_decode($saagj, true) ?? [];
|
||||
}
|
||||
|
||||
// 1. Initialize the structure for every person
|
||||
$indexedNotenArray = [];
|
||||
foreach ($personen as $sp) {
|
||||
$pId = $sp['id'];
|
||||
foreach ($geraete as $g) {
|
||||
$indexedNotenArray[$pId][$g['id']] = [];
|
||||
}
|
||||
$indexedNotenArray[$pId][0] = []; // Total/Overall device per person
|
||||
}
|
||||
|
||||
// 2. Fill with existing database values
|
||||
$sortArray = [];
|
||||
foreach ($notenEntries as $sn) {
|
||||
$pId = $sn['person_id'];
|
||||
$gId = $sn['geraet_id'];
|
||||
$nId = $sn['note_bezeichnung_id'];
|
||||
$val = $sn['value'];
|
||||
|
||||
$indexedNotenArray[$pId][$gId][$nId] = $val;
|
||||
|
||||
// Check if this specific note is the one we rank by
|
||||
// Usually ranking happens on Device 0 (Total) for the $rangNote ID
|
||||
if (intval($nId) === $rangNote && intval($gId) === 0) {
|
||||
$sortArray[$pId] = $val; // FIXED: used = instead of ===
|
||||
}
|
||||
}
|
||||
|
||||
// Load TCPDF
|
||||
require $baseDir . '/../composer/vendor/autoload.php';
|
||||
|
||||
// Optional: load custom font
|
||||
$fontfile = $baseDir . '/wp-content/uploads/fonts/Inter-Regular.ttf'; // adjust path
|
||||
if (file_exists($fontfile)) {
|
||||
$fontname = TCPDF_FONTS::addTTFfont($fontfile, 'TrueTypeUnicode', '', 32);
|
||||
}
|
||||
|
||||
class MYPDF extends TCPDF
|
||||
{
|
||||
public $current_year;
|
||||
public $programm;
|
||||
public $upperprogramm;
|
||||
public $columns;
|
||||
public $disciplines;
|
||||
// Page header
|
||||
|
||||
public $headerBottomY = 0;
|
||||
|
||||
public function Header()
|
||||
{
|
||||
$image_file = 'https://kutu-tage-beider-basel.testseite-fh-ht.chhttps://kutu-tage-beider-basel.testseite-fh-ht.ch/wp-content/uploads/2025/06/ktbb-logo.png';
|
||||
$this->SetY(15);
|
||||
$this->SetFont('helvetica', 'B', 20);
|
||||
$this->Cell(0, 0, 'Rangliste Kutu-Tage beider Basel ' . $this->current_year, 0, 1, 'L', 0, '', 0, false, 'M', 'M');
|
||||
$preimageX = $this->GetX();
|
||||
$preimageY = $this->GetY();
|
||||
$this->Image($image_file, 272, 5, 15, '', 'JPG', '', 'T', false, 300, '', false, false, 0, false, false, false);
|
||||
|
||||
$this->SetX($preimageX);
|
||||
$this->SetY($preimageY);
|
||||
|
||||
$this->SetFont('helvetica', '', 11);
|
||||
$this->Cell(0, 10, 'Programm: ' . $this->upperprogramm, 0, 1, 'L');
|
||||
$this->Ln(5);
|
||||
|
||||
$columns = $this->columns;
|
||||
$disciplines = $this->disciplines;
|
||||
|
||||
// Print first header row
|
||||
$preheaderX = $this->GetX();
|
||||
$preheaderY = $this->GetY();
|
||||
$this->SetFont('', 'B');
|
||||
$this->Cell($columns['rang']['max_width'], 7, $columns['rang']['header'], 0, 0, 'C');
|
||||
$this->Cell($columns['name']['max_width'], 7, $columns['name']['header'], 0, 0, 'L');
|
||||
$this->Cell($columns['vorname']['max_width'], 7, $columns['vorname']['header'], 0, 0, 'L');
|
||||
$this->Cell($columns['geburtsdatum']['max_width'], 7, $columns['geburtsdatum']['header'], 0, 0, 'C');
|
||||
$this->Cell($columns['verein']['max_width'], 7, $columns['verein']['header'], 0, 0, 'L');
|
||||
$startX = $this->GetX();
|
||||
$startY = $this->GetY();
|
||||
$this->SetLineWidth(0.2);
|
||||
|
||||
// Loop through disciplines for rotated headers
|
||||
foreach ($disciplines as $d) {
|
||||
$w = $columns["d-note $d"]['max_width'] + $columns["note $d"]['max_width'];
|
||||
$ws = $columns["note $d"]['max_width'];
|
||||
|
||||
$x = $this->GetX();
|
||||
$y = $this->GetY() + 7;
|
||||
|
||||
// Start transformation for rotation
|
||||
$this->StartTransform();
|
||||
|
||||
// Rotate around top-left of cell
|
||||
$this->Rotate(45, $x, $y);
|
||||
|
||||
// Draw a line **above the first data row**
|
||||
$lineY = $startY + 7; // adjust 7 depending on cell height
|
||||
$this->Line($x, $lineY, $x + $ws, $lineY);
|
||||
|
||||
// Print the rotated header text
|
||||
$this->Cell($w, 7, ucfirst($d), 0, 0, 'L');
|
||||
|
||||
$this->StopTransform();
|
||||
|
||||
$this->SetX($x + $w);
|
||||
}
|
||||
|
||||
$w = $columns["gesamt"]['max_width'];
|
||||
$ws = $w;
|
||||
|
||||
$x = $this->GetX();
|
||||
$y = $this->GetY() + 7;
|
||||
|
||||
// Start transformation for rotation
|
||||
$this->StartTransform();
|
||||
|
||||
// Rotate around top-left of cell
|
||||
$this->Rotate(45, $x, $y);
|
||||
|
||||
// Draw a line **above the first data row**
|
||||
$lineY = $startY + 7; // adjust 7 depending on cell height
|
||||
|
||||
$this->SetLineWidth(0.6);
|
||||
|
||||
$this->Line($x, $lineY, $x + $ws, $lineY);
|
||||
|
||||
$this->SetLineWidth(0.2);
|
||||
|
||||
|
||||
// Print the rotated header text
|
||||
$this->Cell($w, 7, $columns['gesamt']['header'], 0, 0, 'L');
|
||||
|
||||
$this->StopTransform();
|
||||
|
||||
$this->SetX($x + $w);
|
||||
|
||||
$afterheaderX = $this->GetX();
|
||||
|
||||
$this->Ln();
|
||||
|
||||
$xheaderline = $preheaderX;
|
||||
$yheaderline = $this->GetY();
|
||||
|
||||
$this->headerBottomY = $this->GetY();
|
||||
}
|
||||
|
||||
// Page footer
|
||||
public function Footer()
|
||||
{
|
||||
$this->SetY(-15);
|
||||
$this->SetFont('helvetica', 'I', 8);
|
||||
$this->Cell(0, 10, 'Seite ' . $this->getAliasNumPage() . ' von ' . $this->getAliasNbPages(), 0, false, 'C', 0, '', 0, false, 'T', 'M');
|
||||
$this->SetFont('', '');
|
||||
$this->Cell(0, 10, $_SERVER['HTTP_HOST'], 0, 0, 'R', false, 'https://'.$_SERVER['HTTP_HOST'].'/ergebnis/'.$this->current_year, 0, false, 'T', 'M');
|
||||
|
||||
$this->SetLineWidth(0.6);
|
||||
$this->Line(10, $this->headerBottomY, 297 - 10, $this->headerBottomY);
|
||||
|
||||
$this->SetLineWidth(0.2);
|
||||
|
||||
$this->SetY(0);
|
||||
$this->SetX(5);
|
||||
|
||||
$this->SetFillColor(255, 255, 255); // white
|
||||
|
||||
$this->Cell(5, 190, '', 0, 0, 'L', true);
|
||||
|
||||
$this->SetY(0);
|
||||
$this->SetX(297 - 10);
|
||||
|
||||
$this->Cell(5, 190, '', 0, 0, 'L', true);
|
||||
}
|
||||
}
|
||||
|
||||
$pdf = new MYPDF('L', 'mm', 'A4', true, 'UTF-8', false);
|
||||
$pdf->current_year = $current_year;
|
||||
$pdf->programm = $programm;
|
||||
$pdf->upperprogramm = $upperprogramm;
|
||||
|
||||
$pdf->SetCreator(PDF_CREATOR);
|
||||
$pdf->SetAuthor('WKVS-FH');
|
||||
$pdf->SetTitle("KTBB_Ergebnisse_" . $programm . "_" . $current_year . ".pdf");
|
||||
|
||||
$pdf->SetAutoPageBreak(TRUE, 10);
|
||||
$pdf->SetFont('helvetica', '', 11);
|
||||
|
||||
|
||||
// Define columns (including discipline sub-columns)
|
||||
$columns = [
|
||||
'rang' => [ 0 => ['header' => 'Rang']],
|
||||
'name' => [ 0 => ['header' => 'Name']],
|
||||
'vorname' => [ 0 => ['header' => 'Vorname']],
|
||||
'geburtsdatum' => [ 0 => ['header' => 'Jg.']],
|
||||
'verein' => [ 0 => ['header' => 'Verein']],
|
||||
];
|
||||
|
||||
foreach ($displayedNoten as $sdN) {
|
||||
if (intval($sdN['pro_geraet']) === 1) {
|
||||
foreach ($geraete as $g) {
|
||||
$columns[$sdN['name']][$g['id']] = ['header' => $sdN['name'], 'nullstellen' => $sdN['nullstellen'] ?? 2];
|
||||
}
|
||||
} else {
|
||||
$allowed = $ascArrayGeraeteJSON[$sdN['id']] ?? [];
|
||||
foreach ($allowed as $gId) {
|
||||
$columns[$sdN['name']][$gId] = ['header' => $sdN['name'], 'nullstellen' => $sdN['nullstellen'] ?? 2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize max widths with header widths (+4 mm padding)
|
||||
foreach ($columns as $key => $col) {
|
||||
foreach ($col as $skey => $scol) {
|
||||
$columns[$key][$skey]['max_width'] = $pdf->GetStringWidth($scol['header']) + 8;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fill missing defaults and finalize the sortArray
|
||||
foreach ($personen as $sp) {
|
||||
$pId = $sp['id'];
|
||||
|
||||
// We check all possible devices (including 0)
|
||||
foreach ($indexedNotenArray[$pId] as $sG => $currentNoten) {
|
||||
|
||||
foreach ($alleNoten as $noteDef) {
|
||||
$neni = $noteDef['id'];
|
||||
|
||||
// Skip if note already exists for this person/device
|
||||
if (isset($currentNoten[$neni])) continue;
|
||||
|
||||
// Logic for "Pro Gerät" vs "Specific/Total"
|
||||
$isProGeraet = (intval($noteDef['pro_geraet']) === 1);
|
||||
$allowedGeraete = $ascArrayGeraeteJSON[$neni] ?? [];
|
||||
|
||||
if ($isProGeraet) {
|
||||
if ($sG === 0) continue;
|
||||
} else {
|
||||
if (!in_array($sG, $allowedGeraete)) continue;
|
||||
}
|
||||
|
||||
// Assign default value
|
||||
$defaultValue = $ascArrayDefaultValues[$neni] ?? 0;
|
||||
|
||||
$string = nuber_format($defaultValue, $noteDef['nullstellen']);
|
||||
|
||||
$indexedNotenArray[$pId][$sG][$neni] = $string;
|
||||
|
||||
$width = $pdf->GetStringWidth($string) + 4;
|
||||
|
||||
if ($w > $columns[$noteDef['name']][$sG]['max_width']) {
|
||||
$columns[$noteDef['name']][$sG] = $w;
|
||||
}
|
||||
|
||||
// If this missing note was our ranking note, add default to sortArray
|
||||
if ($neni === $rangNote && $sG === 0) {
|
||||
$sortArray[$pId] = $defaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateRanks(array $scoreArray, $direction = 'DESC') {
|
||||
// 1. Sort the scores while preserving keys
|
||||
if ($direction === 'DESC') {
|
||||
arsort($scoreArray); // High scores first
|
||||
} else {
|
||||
asort($scoreArray); // Low scores first
|
||||
}
|
||||
|
||||
$ranks = [];
|
||||
$currentRank = 0;
|
||||
$lastScore = null;
|
||||
$skipped = 0;
|
||||
|
||||
foreach ($scoreArray as $pId => $score) {
|
||||
if ($score !== $lastScore) {
|
||||
$currentRank += ($skipped + 1);
|
||||
$skipped = 0;
|
||||
} else {
|
||||
$skipped++;
|
||||
}
|
||||
|
||||
$ranks[$pId] = $currentRank;
|
||||
$lastScore = $score;
|
||||
}
|
||||
return $ranks;
|
||||
}
|
||||
|
||||
// 4. Calculate Ranks
|
||||
// FIXED: Passing $orderBestRang (the string "ASC"/"DESC") instead of the array
|
||||
$ranks = calculateRanks($sortArray, $orderBestRang);
|
||||
|
||||
// Calculate max width of each column based on all data
|
||||
foreach ($personen as $p) {
|
||||
foreach ($columns as $key => &$col) {
|
||||
if (isset($p[$key])) {
|
||||
$text = $p[$key];
|
||||
} else {
|
||||
$text = '';
|
||||
}
|
||||
$w = $pdf->GetStringWidth($text) + 4;
|
||||
// Add some padding
|
||||
if ($w > $col['max_width']) {
|
||||
$col['max_width'] = $w;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unset($col);
|
||||
$columns['geburtsdatum'][0]['max_width'] = $pdf->GetStringWidth("0000") + 8;
|
||||
|
||||
$tablew = 297 - 20; // total table width (A4 landscape in mm)
|
||||
|
||||
// Step 1: Calculate total width of fixed columns
|
||||
$fixedWidth = 0;
|
||||
|
||||
/*
|
||||
// Discipline columns (each discipline has two columns: "d-note" and "note")
|
||||
foreach ($disciplines as $d) {
|
||||
$fixedWidth += $columns["d-note $d"]['max_width'] + $columns["note $d"]['max_width'];
|
||||
}
|
||||
|
||||
// Other fixed columns
|
||||
$fixedColumns = ['geburtsdatum','rang','gesamt'];
|
||||
foreach ($fixedColumns as $col) {
|
||||
$fixedWidth += $columns[$col]['max_width'];
|
||||
}
|
||||
|
||||
// Step 2: Compute extra space for flexible columns
|
||||
$flexCols = ['name','vorname','verein']; // columns that can grow
|
||||
$flexTotal = 0;
|
||||
|
||||
// Compute current total width of flexible columns
|
||||
foreach ($flexCols as $col) {
|
||||
$flexTotal += $columns[$col]['max_width'];
|
||||
}
|
||||
|
||||
// Available width for flexible columns
|
||||
$effTableWidth = $tablew - $fixedWidth;
|
||||
$extraWidth = $effTableWidth - $flexTotal;
|
||||
|
||||
// Step 3: Distribute extra width proportionally among flexible columns
|
||||
if ($extraWidth > 0) {
|
||||
foreach ($flexCols as $col) {
|
||||
$columns[$col]['max_width'] += ($columns[$col]['max_width'] / $flexTotal) * $extraWidth;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
$pdf->columns = $columns;
|
||||
$pdf->disciplines = $disciplines;
|
||||
|
||||
$pdf->AddPage();
|
||||
|
||||
// After AddPage(), the header has been drawn
|
||||
$margin_top = $pdf->headerBottomY;
|
||||
|
||||
// Now adjust your margins if needed
|
||||
$pdf->SetMargins(10, $margin_top, 10); // +5 mm padding below header
|
||||
$pdf->SetY($margin_top); // Move cursor below header manually
|
||||
|
||||
|
||||
$mbs = false;
|
||||
$mbl = false;
|
||||
$pdf->SetFont('', '');
|
||||
$index = 0;
|
||||
foreach ($personen as $r) {
|
||||
|
||||
$pdf->SetTextColor(0, 0, 0);
|
||||
|
||||
$rang = $ranks[$r['id']];
|
||||
|
||||
if ($rang == 1) {
|
||||
$pdf->SetFillColor(255, 235, 128);
|
||||
} elseif($rang == 2) {
|
||||
$pdf->SetFillColor(224, 224, 224);
|
||||
} elseif($$rang == 3) {
|
||||
$pdf->SetFillColor(230, 191, 153);
|
||||
} elseif ($index % 2 == 0) {
|
||||
$pdf->SetFillColor(255, 255, 255); // white
|
||||
} else {
|
||||
$pdf->SetFillColor(240, 240, 240); // light gray
|
||||
}
|
||||
|
||||
|
||||
$pdf->SetFont('', 'B');
|
||||
/*
|
||||
if ($buttontype === 'export_programm_bm') {
|
||||
if (($r['verein'] === 'BTV Basel' || $r['verein'] === 'TV Basel') && $mbs === false){
|
||||
$pdf->SetFillColor(0, 0, 0);
|
||||
$pdf->SetTextColor(255, 255, 255);
|
||||
$mbs = true;
|
||||
} elseif (($r['verein'] === 'Kutu Regio Basel') && $mbl === false) {
|
||||
$pdf->SetFillColor(255, 0, 0);
|
||||
$pdf->SetTextColor(255, 255, 255);
|
||||
$mbl = true;
|
||||
}
|
||||
}*/
|
||||
|
||||
$pdf->Cell($columns['rang'][0]['max_width'], 8, $rang, 'B', 0, 'C', true);
|
||||
|
||||
$pdf->SetFont('', '');
|
||||
$pdf->Cell($columns['name'][0]['max_width'], 8, $r['name'], 'B', 0, 'L', true);
|
||||
$pdf->Cell($columns['vorname'][0]['max_width'], 8, $r['vorname'], 'B', 0, 'L', true);
|
||||
$pdf->Cell($columns['geburtsdatum'][0]['max_width'], 8, (new DateTime($r['geburtsdatum']))->format("Y"), 'B', 0, 'C', true);
|
||||
$pdf->Cell($columns['verein'][0]['max_width'], 8, $r['verein'], 'B', 0, 'L', true);
|
||||
|
||||
|
||||
foreach ($disciplines as $d) {
|
||||
$d_note = isset($r["d-note $d"]) ?
|
||||
number_format((float)$r["d-note $d"], 2) : '';
|
||||
$note = isset($r["note $d"]) ? number_format((float)$r["note $d"], 3) : '';
|
||||
$pdf->SetFont('', '', 9);
|
||||
$pdf->Cell($columns["d-note $d"]['max_width'], 8, $d_note, 'LB', 0, 'C', true);
|
||||
$pdf->SetFont('', '', 11);
|
||||
$pdf->Cell($columns["note $d"]['max_width'], 8, $note, 'B', 0, 'C', true);
|
||||
}
|
||||
|
||||
$gesamt = isset($r["gesamtpunktzahl"]) ? number_format((float)$r["gesamtpunktzahl"], 3) : '';
|
||||
|
||||
$pdf->SetFont('', 'B');
|
||||
$pdf->Cell($columns['gesamt'][0]['max_width'], 8, $gesamt, 'B', 0, 'C', true);
|
||||
$pdf->SetFont('', '');
|
||||
|
||||
$x = $pdf->GetX() - $columns['gesamt'][0]['max_width'];
|
||||
$y = $pdf->GetY();
|
||||
|
||||
$pdf->SetLineWidth(0.6);
|
||||
$pdf->Line($x, $y, $x, $y + 7.7);
|
||||
|
||||
$pdf->SetLineWidth(0.2);
|
||||
$pdf->Ln();
|
||||
|
||||
$index++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
$pdf->SetFont('', '', 7);
|
||||
$textanzturnerinnen = (count($entries) > 1) ? 'Turnerinnen': 'Turnerin';
|
||||
$pdf->Cell(20, 6, count($entries).' '.$textanzturnerinnen, 0, 0, 'L');
|
||||
|
||||
if ($buttontype === 'export_programm' || $buttontype === 'export_programm_bm') {
|
||||
$pdf->Output("KTBB_Ergebnisse_" . $programm . "_" . $current_year . ".pdf", 'D');
|
||||
exit;
|
||||
} elseif ($buttontype === 'upload_programm') {
|
||||
$dir = $baseDir . '/wp-content/ergebnisse/';
|
||||
if (!file_exists($dir)) mkdir($dir, 0755, true);
|
||||
$localPath = $dir . "KTBB_Ergebnisse_" . $programm . "_" . $current_year . ".pdf";
|
||||
if (file_exists($localPath)) unlink($localPath);
|
||||
$pdf->Output($localPath, 'F');
|
||||
$_SESSION['form_message'] = '<div class="success">PDF wurde hochgeladen</div>';
|
||||
exit;
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
$discipline = isset($_GET['discipline']) ? preg_replace('/[^a-zA-Z0-9 _-]/', '', $_GET['discipline']) : '';
|
||||
|
||||
if ($discipline !== 'boden') {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid discipline']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
$result = $mysqli->query("SELECT t.bodenmusik, agg.filePath FROM `$tableTurnerinnen` t LEFT JOIN (SELECT a.id, a.file_path AS filePath FROM $tableAudiofiles a) agg ON agg.id = t.bodenmusik WHERE t.id = $id");
|
||||
$row = $result->fetch_assoc();
|
||||
if (!$row || !isset($row['bodenmusik'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'Row fetch failed '.$id]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($row['bodenmusik'] === "0" || $row['filePath'] == null) {
|
||||
echo json_encode(['success' => false, 'message' => 'Keine Musik']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$folder = realpath($baseDir . '/displays/json');
|
||||
if ($folder === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Could not find displays folder.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = 'audio.json';
|
||||
$filepath = $folder . '/' . $filename;
|
||||
|
||||
if (!is_writable($folder)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Folder not writable: ']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (!is_file($filepath)){
|
||||
file_put_contents($filepath, []);
|
||||
}
|
||||
|
||||
|
||||
$jsonString = file_get_contents($filepath);
|
||||
|
||||
// decode JSON, fallback to empty array if invalid
|
||||
$oldjson = json_decode($jsonString, true) ?? [];
|
||||
|
||||
|
||||
$oldjson["musik"] = $row['filePath'];
|
||||
$oldjson["start"] = true;
|
||||
|
||||
$jsonData = json_encode($oldjson);
|
||||
|
||||
// Write file
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Failed to write JSON file: ' . $filepath
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'JSON updated successfully for '.$discipline,
|
||||
'disable_musik_button' => true
|
||||
]);
|
||||
exit;
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$discipline = 'boden';
|
||||
|
||||
$folder = realpath($baseDir . '/displays/json');
|
||||
if ($folder === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Could not find displays folder.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = 'audio.json';
|
||||
$filepath = $folder . '/' . $filename;
|
||||
|
||||
if (!is_writable($folder)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Folder not writable']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!is_file($filepath)){
|
||||
file_put_contents($filepath, []);
|
||||
}
|
||||
|
||||
$jsonString = file_get_contents($filepath);
|
||||
|
||||
// decode JSON, fallback to empty array if invalid
|
||||
$oldjson = json_decode($jsonString, true) ?? [];
|
||||
|
||||
$oldjson["start"] = false;
|
||||
|
||||
$jsonData = json_encode($oldjson);
|
||||
|
||||
// Write file
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Failed to write JSON file: ' . $filepath
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'JSON updated successfully for '.$discipline,
|
||||
'disable_musik_button' => true
|
||||
]);
|
||||
exit;
|
||||
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', '1');
|
||||
ini_set('display_startup_errors', '1');
|
||||
error_reporting(E_ALL);
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$abteilung = isset($_POST['abteilung']) ? strval($_POST['abteilung']) : '1';
|
||||
$aufgabe = isset($_POST['aufgabe']) ? strval($_POST['aufgabe']) : '2';
|
||||
$name = isset($_POST['name']) ? strval($_POST['name']) : 'RK';
|
||||
$geraet = isset($_POST['geraet']) ? strtolower($_POST['geraet']) : 'boden';
|
||||
|
||||
if ($abteilung === ''){
|
||||
echo json_encode(['success' => false, 'message' => 'Keine Abteilung angegeben.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($aufgabe === ''){
|
||||
echo json_encode(['success' => false, 'message' => 'Keine Aufgabe angegeben.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!is_numeric($aufgabe)){
|
||||
echo json_encode(['success' => false, 'message' => 'Keine valide Aufgabe. (is not numeric)']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($name === ''){
|
||||
echo json_encode(['success' => false, 'message' => 'Kein Namen angegeben']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT `name` FROM $tableGeraete ORDER BY start_index ASC");
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$disciplines = array_map(
|
||||
'strtolower',
|
||||
array_column($result->fetch_all(MYSQLI_ASSOC), 'name')
|
||||
);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if (!in_array($geraet, $disciplines)){
|
||||
echo json_encode(['success' => false, 'message' => 'Invalides Gerät: '.$geraet]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT * FROM $tableKrProtokoll WHERE abteilung = ? AND geraet = ? AND aufgabe = ? LIMIT 1");
|
||||
$stmt->bind_param("sss", $abteilung, $geraet, $aufgabe);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->get_result();
|
||||
|
||||
$row = $result->fetch_assoc();
|
||||
|
||||
if ($row){
|
||||
$updatestmt = $mysqli->prepare("UPDATE $tableKrProtokoll SET name = ? WHERE id = ?");
|
||||
$updatestmt->bind_param("si", $name, $row['id']);
|
||||
|
||||
if (!$updatestmt->execute()) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Insert ERROR: ' . $updatestmt->error
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Updated: updated']);
|
||||
exit;
|
||||
} else {
|
||||
$insertstmt = $mysqli->prepare("INSERT INTO $tableKrProtokoll (abteilung, geraet, name, aufgabe) VALUES (?, ?, ?, ?)");
|
||||
$insertstmt->bind_param("ssss", $abteilung, $geraet, $name, $aufgabe);
|
||||
|
||||
if (!$insertstmt->execute()) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Insert ERROR: ' . $insertstmt->error
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Updated: inserted']);
|
||||
exit;
|
||||
}
|
||||
?>
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
session_start();
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$new_value = $_POST['freigabe'] ?? '';
|
||||
|
||||
$type = $_POST['type'] ?? 'nan';
|
||||
|
||||
$allowedTypes = ['kampfrichter', 'trainer'];
|
||||
|
||||
if (in_array($type, $allowedTypes)) {
|
||||
|
||||
|
||||
$accessKey = "access_granted_" . $type;
|
||||
$idKey = "passcode" . $type . "_id";
|
||||
|
||||
// 3. Check if they have access
|
||||
$hasAccess = isset($_SESSION[$accessKey]) &&
|
||||
$_SESSION[$accessKey] === true &&
|
||||
!empty($_SESSION[$idKey]) &&
|
||||
$_SESSION[$idKey] > 0;
|
||||
|
||||
|
||||
if (!$hasAccess) {
|
||||
echo json_encode(['success' => false, 'message' => 'no permissions']);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'no permissions']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!$new_value) {
|
||||
echo json_encode('Invalid Input');
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($type === 'kampfrichter'){
|
||||
$_SESSION['selectedFreigabeKampfrichter'] = $new_value;
|
||||
}
|
||||
|
||||
if ($type === 'trainer'){
|
||||
$_SESSION['selectedFreigabeTrainer'] = $new_value;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode(['success' => true, 'message' => 'SESSION updated']);
|
||||
exit;
|
||||
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
|
||||
$person_id = isset($_POST['personId']) ? intval($_POST['personId']) : 0;
|
||||
$field_type_id = intval($_POST['fieldTypeId'] ?? 0);
|
||||
$gereat_id = intval($_POST['gereatId'] ?? 0);
|
||||
$jahr = isset($_POST['jahr']) ? intval($_POST['jahr']) : 0;
|
||||
$run_number = isset($_POST['run']) ? intval($_POST['run']) : 1;
|
||||
|
||||
if (!isset($_POST['value'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'Kein Value angegeben']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$valueNoteUpdate = floatval($_POST['value']);
|
||||
|
||||
if ($person_id < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Personen-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($jahr < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalides Jahr']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($gereat_id < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Geraet-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$geratExistiert = db_get_var($mysqli, "SELECT 1 FROM $tableGeraete WHERE id = ? LIMIT 1", [$gereat_id]);
|
||||
|
||||
if (!$geratExistiert) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Geraet-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($field_type_id < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Notentyp-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$noteConfig = db_select($mysqli, $tableNotenBezeichnungen, "*", "id = ?", [$field_type_id]);
|
||||
|
||||
if (count($noteConfig) !== 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Notentyp-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$singleNoteConfig = $noteConfig[0];
|
||||
|
||||
if ($singleNoteConfig['max_value'] !== null && $valueNoteUpdate > $singleNoteConfig['max_value']) {
|
||||
echo json_encode(['success' => false, 'message' => "Wert zu hoch (max " . $singleNoteConfig['max_value'].")"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($singleNoteConfig['min_value'] !== null && $valueNoteUpdate < $singleNoteConfig['min_value']){
|
||||
echo json_encode(['success' => false, 'message' => "Wert zu niedrig (min " . $singleNoteConfig['min_value'].")"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO $tableNoten (`value`, `person_id`, `note_bezeichnung_id`, `geraet_id`, `jahr`, `run_number`)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
$stmt->bind_param("siiiii", $valueNoteUpdate, $person_id, $field_type_id, $gereat_id, $jahr, $run_number);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if ($singleNoteConfig['berechnung_json'] === null) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . "/../scripts/string-calculator/string-calculator-functions.php";
|
||||
|
||||
$updateNoten = [];
|
||||
|
||||
$notenRechner = new NotenRechner();
|
||||
|
||||
try {
|
||||
$abhaenigeRechnungen = json_decode($singleNoteConfig['berechnung_json']);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert, fehler bei der Berechnung der weiteren Werte"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$geraete = db_select($mysqli, $tableGeraete, "id");
|
||||
|
||||
// Alle Werte werden von der Datenbank geholt und werden, wenn nicht vorhanden, durch den Standartwert ersetzt.
|
||||
|
||||
$alleNoten = db_select($mysqli, $tableNotenBezeichnungen, "id, berechnung, default_value, nullstellen, pro_geraet, geraete_json, anzahl_laeufe_json");
|
||||
|
||||
$noten = db_select($mysqli, $tableNoten, "`value`, `note_bezeichnung_id`, `geraet_id`, `run_number`", "`person_id` = ? AND `jahr` = ?", [$person_id, $jahr]);
|
||||
|
||||
$ascArrayDefaultValues = array_column($alleNoten, 'default_value', 'id');
|
||||
$ascArrayProGeraet = array_column($alleNoten, 'pro_geraet', 'id');
|
||||
$ascArrayGeraeteJSON = array_column($alleNoten, 'geraete_json', 'id');
|
||||
$ascArrayAnzahlLaeufeJSON = array_column($alleNoten, 'anzahl_laeufe_json', 'id');
|
||||
$ascArrayRechnungen = array_column($alleNoten, 'berechnung', 'id');
|
||||
|
||||
|
||||
// $proGeraet = intval($calc['pro_geraet']) !== 1;
|
||||
|
||||
|
||||
$indexedNotenArray = [];
|
||||
|
||||
foreach ($ascArrayGeraeteJSON as $key => $saagj) {
|
||||
$ascArrayGeraeteJSON[$key] = json_decode($saagj, true);
|
||||
}
|
||||
|
||||
foreach ($ascArrayAnzahlLaeufeJSON as $key => $saalj) {
|
||||
$ascArrayAnzahlLaeufeJSON[$key] = json_decode($saalj, true) ?? [];
|
||||
}
|
||||
|
||||
foreach ($geraete as $g) {
|
||||
$indexedNotenArray[$g['id']] = [];
|
||||
}
|
||||
|
||||
$indexedNotenArray[0] = [];
|
||||
|
||||
foreach ($noten as $sn) {
|
||||
$indexedNotenArray[$sn['geraet_id']][$sn['note_bezeichnung_id']][$sn['run_number']] = $sn['value'];
|
||||
}
|
||||
|
||||
$alleNotenIds = array_column($alleNoten, 'id') ?? [];
|
||||
|
||||
foreach ($indexedNotenArray as $sG => $siNA) {
|
||||
$existierendeNotenIds = array_keys($siNA) ?? [];
|
||||
|
||||
$nichtExistierendeNotenIds = array_diff($alleNotenIds, $existierendeNotenIds) ?? [];
|
||||
|
||||
foreach ($nichtExistierendeNotenIds as $neni) {
|
||||
if (!isset($ascArrayDefaultValues[$neni])) { continue; }
|
||||
if (intval($ascArrayProGeraet[$neni]) === 1 && intval($sG) === 0) { continue; }
|
||||
if (intval($ascArrayProGeraet[$neni]) !== 1 && (!is_array($ascArrayGeraeteJSON[$neni]) || !in_array($sG, $ascArrayGeraeteJSON[$neni]))) { continue; }
|
||||
|
||||
// For non-existent notes, we fill all runs with default value
|
||||
// We set Run 1 by default, and if more are configured, also those
|
||||
$indexedNotenArray[$sG][$neni][1] = $ascArrayDefaultValues[$neni];
|
||||
|
||||
// Check for more runs in config? (Actually, this might be overkill for defaults,
|
||||
// but the calculator might need them)
|
||||
}
|
||||
}
|
||||
|
||||
// We only want to save the IDs that were actually recalculated
|
||||
$idsToSave = [];
|
||||
|
||||
foreach ($abhaenigeRechnungen as $sRechnung) {
|
||||
if ($sRechnung[1] !== "A" && intval($sRechnung[1]) !== $gereat_id) { continue; }
|
||||
|
||||
$rechnung = $ascArrayRechnungen[$sRechnung[0]] ?? null;
|
||||
|
||||
$gereadIdArrays = ($sRechnung[1] === "A") ? $gereat_id : $sRechnung[1];
|
||||
|
||||
$targetNoteId = $sRechnung[0];
|
||||
$isProGeraet = (intval($ascArrayProGeraet[$targetNoteId]) === 1);
|
||||
$allowedGeraete = $ascArrayGeraeteJSON[$targetNoteId] ?? [];
|
||||
|
||||
if ($isProGeraet) {
|
||||
$gereadIdArrays = $gereat_id;
|
||||
} elseif (in_array($gereat_id, $allowedGeraete)) {
|
||||
$gereadIdArrays = $gereat_id;
|
||||
} else {
|
||||
$gereadIdArrays = 0;
|
||||
}
|
||||
|
||||
if ($rechnung === null) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert, Fehler: Rechnung" . $sRechnung[0] . "nicht gefunden"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$calcResult = $notenRechner->berechneStringComplex($rechnung, $indexedNotenArray, $gereat_id);
|
||||
if ($calcResult['success'] !== true) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert, Rechenfehler: " . ($calcResult['value'] ?? '')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Update the local array (Always Run 1 for calculations for now, UNLESS we want calculated runs?)
|
||||
// Most calculations are "Total" points which have run_number = 1
|
||||
$indexedNotenArray[$gereadIdArrays][$sRechnung[0]][1] = $calcResult['value'];
|
||||
|
||||
// Track that this ID needs to be written to the database (Target run is 1)
|
||||
$updatedValues[$gereadIdArrays][$sRechnung[0]][1] = $calcResult['value'];
|
||||
}
|
||||
|
||||
|
||||
// Prepare the statement once
|
||||
$sql = "INSERT INTO $tableNoten (`value`, `person_id`, `note_bezeichnung_id`, `geraet_id`, `jahr`, `run_number`)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
$indexedNullstellen = array_column($alleNoten, 'nullstellen', 'id');
|
||||
|
||||
$formatedNoten = [];
|
||||
|
||||
foreach ($updatedValues as $gereat => $notenArray) {
|
||||
foreach ($notenArray as $note => $runArray) {
|
||||
foreach ($runArray as $run => $value) {
|
||||
$stmt->bind_param("siiiii", $value, $person_id, $note, $gereat, $jahr, $run);
|
||||
$stmt->execute();
|
||||
$formatedNoten[$gereat][$note][$run] = number_format($value ,$indexedNullstellen[$note] ?? 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$formatedNoten[$gereat_id][$field_type_id][$run_number] = number_format($valueNoteUpdate ,$indexedNullstellen[$field_type_id] ?? 2);
|
||||
|
||||
$stmt->close();
|
||||
$mysqli->close();
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => "Wert aktualisiert, alle Berechnungen durchgeführt",
|
||||
"noten" => $formatedNoten
|
||||
]);
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1 || !isset($_SESSION['selectedFreigabeKampfrichter']) || $_SESSION['selectedFreigabeKampfrichter'] !== 'admin') {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
$fieldType = isset($_POST['field_type']) ? preg_replace('/[^a-zA-Z0-9 _-]/', '', $_POST['field_type']) : '';
|
||||
$discipline = isset($_POST['discipline']) ? preg_replace('/[^a-zA-Z0-9 _-]/', '', $_POST['discipline']) : '';
|
||||
$value = isset($_POST['value']) ? floatval($_POST['value']) : 0;
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($value) || floatval($value) < 0 || !isset($discipline) || $discipline === ''|| !isset($fieldType) || $fieldType === '') {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($discipline === 'all') {
|
||||
$column = $fieldType;
|
||||
} else {
|
||||
$column = $fieldType . ' ' . $discipline;
|
||||
}
|
||||
|
||||
$excluded_columns = [
|
||||
'id',
|
||||
'name',
|
||||
'vorname',
|
||||
'bezahlt',
|
||||
'bezahltoverride',
|
||||
'geburtsdatum',
|
||||
'programm',
|
||||
'verein',
|
||||
'bodenmusik'
|
||||
];
|
||||
|
||||
$sql = "SHOW COLUMNS FROM `$tableTurnerinnen`";
|
||||
$result = $mysqli->query($sql);
|
||||
|
||||
$all_columns = [];
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$all_columns[] = $row['Field'];
|
||||
}
|
||||
|
||||
$allowed_columns = array_values(
|
||||
array_diff($all_columns, $excluded_columns)
|
||||
);
|
||||
|
||||
|
||||
if (!in_array($column, $allowed_columns, true)) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("UPDATE `$tableTurnerinnen` SET `$column` = ? WHERE id = ?");
|
||||
$stmt->bind_param("di", $value, $id);
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
$stmt->close();
|
||||
$mysqli->close();
|
||||
|
||||
http_response_code(200);
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'Updated successfully'
|
||||
]);
|
||||
exit;
|
||||
@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$id = intval($_POST['personId']) ?? 0;
|
||||
$geraetId = intval($_POST['geraetId']) ?? 0;
|
||||
$jahr = isset($_POST['jahr']) ? preg_replace('/[^0-9]/', '', $_POST['jahr']) : '';
|
||||
$anfrageType = $_POST['type'] ?? '';
|
||||
|
||||
$allowedTypes = ["neu", "start", "result"];
|
||||
|
||||
if (!in_array($anfrageType, $allowedTypes)) {
|
||||
echo json_encode(['success' => false, 'message' => "Operation nicht gestattet."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($anfrageType !== "start" && ($id < 1 || intval($jahr) < 1)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Personen ID ist nicht valide.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($geraetId < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid discipline']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT `name` FROM $tableGeraete WHERE `id` = ? LIMIT 1");
|
||||
$stmt->bind_param("s", $geraetId);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows === 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid discipline']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$geraetData = $result->fetch_assoc();
|
||||
$geraetName = $geraetData['name'];
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$folder = realpath($baseDir . '/displays/json');
|
||||
|
||||
if ($folder === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Could not find displays folder.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = 'display_' . strtolower($geraetName) . '.json';
|
||||
$filepath = $folder . '/' . $filename;
|
||||
|
||||
if (!is_writable($folder)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Folder not writable']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$jsonString = file_get_contents($filepath);
|
||||
|
||||
// decode JSON, fallback to empty array if invalid
|
||||
$oldjson = json_decode($jsonString, true) ?? [];
|
||||
|
||||
switch ($anfrageType) {
|
||||
case "neu":
|
||||
$stmt = $mysqli->prepare("SELECT * FROM `$tableTurnerinnen` WHERE id = ? LIMIT 1");
|
||||
$stmt->bind_param("i", $id);
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$rows = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
if (!$rows || !is_array($rows) || count($rows) !== 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Row fetch failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row = $rows[0];
|
||||
|
||||
// safely get value, default 0 if missing
|
||||
$olduniqueid = $oldjson['uniqueid'] ?? 0;
|
||||
$uniqueid = $olduniqueid + 1;
|
||||
|
||||
$data = ["noteLinks" => '',
|
||||
"noteRechts" => '',
|
||||
"id" => $id,
|
||||
"name" => $row['name'],
|
||||
"vorname" => $row['vorname'],
|
||||
"programm" => $row['programm'],
|
||||
"verein" => $row['verein'],
|
||||
"start" => false,
|
||||
"musik" => 'nan',
|
||||
"uniqueid" => $uniqueid];
|
||||
$jsonData = json_encode($data);
|
||||
break;
|
||||
case "start":
|
||||
if (array_key_exists("start", $oldjson)) {
|
||||
$oldjson["start"] = true;
|
||||
|
||||
$jsonData = json_encode($oldjson);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Turnerin nicht auf Display '.json_encode($oldjson).'; '.$jsonString]);
|
||||
exit;
|
||||
}
|
||||
break;
|
||||
case "result":
|
||||
// 1. Get IDs and filter out empty values
|
||||
$noteLinksId = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayIdNoteL']);
|
||||
$noteRechtsId = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['displayIdNoteR']);
|
||||
|
||||
// Create an array of IDs that actually exist
|
||||
$validIds = array_filter([$noteLinksId, $noteRechtsId]);
|
||||
|
||||
$noten = [];
|
||||
$notenConfig = [];
|
||||
|
||||
if (!empty($validIds)) {
|
||||
// 2. Fetch Noten (Only if we have IDs to look for)
|
||||
$placeholders = implode(',', array_fill(0, count($validIds), '?'));
|
||||
|
||||
$sqlNoten = "SELECT `value`, `note_bezeichnung_id` FROM $tableNoten
|
||||
WHERE person_id = ? AND `jahr` = ? AND `geraet_id` = ?
|
||||
AND `note_bezeichnung_id` IN ($placeholders)";
|
||||
|
||||
$stmt = $mysqli->prepare($sqlNoten);
|
||||
// Combine standard params with our dynamic ID list
|
||||
$params = array_merge([$id, $jahr, $geraetId], $validIds);
|
||||
$types = str_repeat('s', count($params));
|
||||
$stmt->bind_param($types, ...$params);
|
||||
$stmt->execute();
|
||||
$notenDB = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
|
||||
$noten = array_column($notenDB, 'value', 'note_bezeichnung_id');
|
||||
$stmt->close();
|
||||
|
||||
// 3. Fetch Config
|
||||
$sqlConfig = "SELECT `id`, `default_value`, `nullstellen`, `prefix_display`
|
||||
FROM $tableNotenBezeichnungen WHERE `id` IN ($placeholders)";
|
||||
|
||||
$stmt = $mysqli->prepare($sqlConfig);
|
||||
$typesConfig = str_repeat('s', count($validIds));
|
||||
$stmt->bind_param($typesConfig, ...$validIds);
|
||||
$stmt->execute();
|
||||
$notenConfigDB = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
|
||||
$notenConfig = array_column($notenConfigDB, null, 'id');
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
// 4. Helper function to safely format the output without crashing
|
||||
$formatNote = function($id) use ($noten, $notenConfig) {
|
||||
if (!$id || !isset($notenConfig[$id])) {
|
||||
return ""; // Return empty string if ID is not set or not found in DB
|
||||
}
|
||||
|
||||
$conf = $notenConfig[$id];
|
||||
$val = $noten[$id] ?? $conf['default_value'] ?? 0;
|
||||
$prec = $conf['nullstellen'] ?? 2;
|
||||
$pre = $conf['prefix_display'] ?? '';
|
||||
|
||||
return $pre . number_format((float)$val, (int)$prec, '.', '');
|
||||
};
|
||||
|
||||
// 5. Assign to JSON
|
||||
$oldjson["noteLinks"] = $formatNote($noteLinksId);
|
||||
$oldjson["noteRechts"] = $formatNote($noteRechtsId);
|
||||
|
||||
$jsonData = json_encode($oldjson);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Write file
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Failed to write JSON file'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'JSON updated successfully for ' . $geraetName,
|
||||
'data' => json_decode($jsonData, true),
|
||||
'nameGeraet' => strtolower($geraetName)
|
||||
]);
|
||||
exit;
|
||||
@@ -0,0 +1,115 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
$discipline = isset($_POST['discipline']) ? preg_replace('/[^a-zA-Z0-9 _-]/', '', $_POST['discipline']) : '';
|
||||
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT `name` FROM $tableGeraete ORDER BY start_index ASC");
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$allowed_disciplines = array_map(
|
||||
'strtolower',
|
||||
array_column($result->fetch_all(MYSQLI_ASSOC), 'name')
|
||||
);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if (!in_array($discipline, $allowed_disciplines)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid discipline']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
$result = $mysqli->query("SELECT * FROM `$tableTurnerinnen` WHERE id = $id");
|
||||
$row = $result->fetch_assoc();
|
||||
if (!$row) {
|
||||
echo json_encode(['success' => false, 'message' => 'Row fetch failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$folder = realpath($baseDir . '/displays/json');
|
||||
if ($folder === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Could not find displays folder.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = 'display_' . $discipline . '.json';
|
||||
$filepath = $folder . '/' . $filename;
|
||||
|
||||
if (!is_writable($folder)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Folder not writable: ' . $folder]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$jsonString = file_get_contents($filepath);
|
||||
|
||||
// decode JSON, fallback to empty array if invalid
|
||||
$oldjson = json_decode($jsonString, true) ?? [];
|
||||
|
||||
|
||||
if (array_key_exists("note", $oldjson) && array_key_exists("dnote", $oldjson)) {
|
||||
$oldjson["note"] = (float)$row['note '.$discipline];
|
||||
$oldjson["dnote"] = (float)$row['d-note '.$discipline];
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'ERROR: JSON keys "note" or "dnote" do not exist'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$jsonData = json_encode($oldjson);
|
||||
|
||||
// Write file
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Failed to write JSON file: ' . $filepath
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'JSON updated successfully for '.$discipline,
|
||||
]);
|
||||
exit;
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$discipline = isset($_GET['discipline']) ? preg_replace('/[^a-zA-Z0-9 _-]/', '', $_GET['discipline']) : '';
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT `name` FROM $tableGeraete ORDER BY start_index ASC");
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$allowed_disciplines = array_map(
|
||||
'strtolower',
|
||||
array_column($result->fetch_all(MYSQLI_ASSOC), 'name')
|
||||
);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if (!in_array($discipline, $allowed_disciplines)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid discipline']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$folder = realpath($baseDir . '/displays/json');
|
||||
if ($folder === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Could not find displays folder.'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = 'display_' . $discipline . '.json';
|
||||
$filepath = $folder . '/' . $filename;
|
||||
|
||||
if (!is_writable($folder)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Folder not writable']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$jsonString = file_get_contents($filepath);
|
||||
|
||||
// decode JSON, fallback to empty array if invalid
|
||||
$oldjson = json_decode($jsonString, true) ?? [];
|
||||
|
||||
if (array_key_exists("start", $oldjson)) {
|
||||
$oldjson["start"] = true;
|
||||
|
||||
$jsonData = json_encode($oldjson);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Turnerin nicht auf Display '.json_encode($oldjson).'; '.$jsonString]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// Write file
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Failed to write JSON file'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'JSON updated successfully for '.$discipline,
|
||||
'disable_start_button' => true
|
||||
]);
|
||||
exit;
|
||||
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
session_start();
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
$discipline = isset($_GET['discipline']) ? preg_replace('/[^a-zA-Z0-9 _-]/', '', $_GET['discipline']) : '';
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT `name` FROM $tableGeraete ORDER BY start_index ASC");
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$allowed_disciplines = array_map(
|
||||
'strtolower',
|
||||
array_column($result->fetch_all(MYSQLI_ASSOC), 'name')
|
||||
);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if (!in_array($discipline, $allowed_disciplines)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid discipline']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
$result = $mysqli->query("SELECT name, vorname, verein, programm FROM `$tableTurnerinnen` WHERE id = $id");
|
||||
$row = $result->fetch_assoc();
|
||||
if (!$row) {
|
||||
echo json_encode(['success' => false, 'message' => 'Row fetch failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$folder = realpath($baseDir . '/displays/json');
|
||||
if ($folder === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Could not find displays folder. Tried: ' . __DIR__ . '/../displays'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$filename = 'display_' . $discipline . '.json';
|
||||
$filepath = $folder . '/' . $filename;
|
||||
|
||||
if (!is_writable($folder)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Folder not writable: ' . $folder]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to write file: ' . $filepath]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$jsonString = file_get_contents($folder . $filename);
|
||||
|
||||
// decode JSON, fallback to empty array if invalid
|
||||
$oldjson = json_decode($jsonString, true) ?? [];
|
||||
|
||||
// safely get value, default 0 if missing
|
||||
$olduniqueid = $oldjson['uniqueid'] ?? 0;
|
||||
$uniqueid = $olduniqueid + 1;
|
||||
|
||||
$data = ["note" => 'nan',
|
||||
"dnote" => 'nan',
|
||||
"id" => $id,
|
||||
"name" => $row['name'],
|
||||
"vorname" => $row['vorname'],
|
||||
"programm" => $row['programm'],
|
||||
"verein" => $row['verein'],
|
||||
"start" => false,
|
||||
"musik" => 'nan',
|
||||
"uniqueid" => $uniqueid];
|
||||
$jsonData = json_encode($data);
|
||||
|
||||
|
||||
// Encode JSON with readable formatting
|
||||
$jsonData = json_encode($data);
|
||||
|
||||
// Write file
|
||||
if (file_put_contents($filepath, $jsonData) === false) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Failed to write JSON file: ' . $filepath
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'JSON updated successfully for '.$discipline,
|
||||
'disable_turnerin_button' => true,
|
||||
'enable_result_button' => true
|
||||
]);
|
||||
exit;
|
||||
160
www/intern/scripts/kampfrichter/ajax/neu copy.php
Normal file
160
www/intern/scripts/kampfrichter/ajax/neu copy.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
//ini_set('display_errors', 1);
|
||||
//ini_set('display_startup_errors', 1);
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$noten = db_select($mysqli, $tableNotenBezeichnungen, "id, berechnung, type");
|
||||
|
||||
// 1. Re-index the array so the keys match the database IDs
|
||||
$notenById = array_column($noten, null, 'id');
|
||||
|
||||
$berechnungen = [];
|
||||
foreach ($notenById as $id => $sn) {
|
||||
if ($sn['type'] === 'berechnung') {
|
||||
$berechnungen[] = $sn;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($berechnungen)) {
|
||||
echo json_encode(['success' => true, 'message' => "Keine Berechnungen ausgewählt"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . "/../scripts/string-calculator/string-calculator-functions.php";
|
||||
$notenRechner = new NotenRechner();
|
||||
|
||||
// 1. Build the direct map
|
||||
// Format: [ Changed_Note_ID => [ "CalcId|GeraetId" => [CalcId, GeraetId] ] ]
|
||||
$dependencyMap = [];
|
||||
|
||||
foreach ($berechnungen as $calc) {
|
||||
$neededIdsArray = $notenRechner->getBenoetigteIdsComplex($calc['berechnung']);
|
||||
|
||||
if (empty($neededIdsArray)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$calcId = (int)$calc['id'];
|
||||
|
||||
foreach ($neededIdsArray as $needed) {
|
||||
$nId = (int)$needed['noteId'];
|
||||
|
||||
// Keep geraetId as integer if it's a number (e.g., 3), otherwise string ('S')
|
||||
$gId = is_numeric($needed['geraetId']) ? (int)$needed['geraetId'] : $needed['geraetId'];
|
||||
|
||||
// Create a unique string key so we don't store exact duplicates
|
||||
$nodeKey = $calcId . '|' . $gId;
|
||||
|
||||
if (!isset($dependencyMap[$nId])) {
|
||||
$dependencyMap[$nId] = [];
|
||||
}
|
||||
|
||||
// Store it as the "little array" you requested: [DependentCalcId, GeraetId]
|
||||
$dependencyMap[$nId][$nodeKey] = [$calcId, $gId];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Our recursive helper function (Updated for complex nodes)
|
||||
function getCompleteDependencyChain($id, $directMap, $visited = [])
|
||||
{
|
||||
// If this ID doesn't have anything depending on it, return empty
|
||||
if (!isset($directMap[$id])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$allDependencies = [];
|
||||
|
||||
foreach ($directMap[$id] as $nodeKey => $complexNode) {
|
||||
// CIRCULAR DEPENDENCY CHECK:
|
||||
// We check against the string key (e.g., "10|S") to prevent infinite loops
|
||||
if (isset($visited[$nodeKey])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. Mark this specific node as visited
|
||||
$visited[$nodeKey] = true;
|
||||
|
||||
// 2. Add the little array [CalcId, GeraetId] to our master list
|
||||
$allDependencies[$nodeKey] = $complexNode;
|
||||
|
||||
// 3. Recursively find everything that depends on THIS calculation ID
|
||||
// $complexNode[0] is the dependent Calc ID
|
||||
$childDependencies = getCompleteDependencyChain($complexNode[0], $directMap, $visited);
|
||||
|
||||
// 4. Merge the child results into our master list safely
|
||||
foreach ($childDependencies as $childKey => $childNode) {
|
||||
$allDependencies[$childKey] = $childNode;
|
||||
$visited[$childKey] = true; // Ensure the parent loop knows this was visited
|
||||
}
|
||||
}
|
||||
|
||||
return $allDependencies;
|
||||
}
|
||||
|
||||
|
||||
// 3. Create the final flattened map for ALL IDs
|
||||
$flatDependencyMap = [];
|
||||
|
||||
foreach (array_keys($notenById) as $id) {
|
||||
$chain = getCompleteDependencyChain($id, $dependencyMap);
|
||||
|
||||
// Only add it if dependencies exist
|
||||
if (!empty($chain)) {
|
||||
// array_values() removes the "10|S" string keys, turning it into a perfect
|
||||
// 0-indexed array for clean JSON encoding: [[10, "S"], [12, 3]]
|
||||
$flatDependencyMap[$id] = array_values($chain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 4. Database Updates
|
||||
// Step 1: Reset all rows to NULL in a single query
|
||||
$resetSql = "UPDATE $tableNotenBezeichnungen SET `berechnung_json` = NULL";
|
||||
$mysqli->query($resetSql);
|
||||
|
||||
// Step 2: Prepare the statement
|
||||
$updateSql = "UPDATE $tableNotenBezeichnungen SET `berechnung_json` = ? WHERE id = ?";
|
||||
$stmt = $mysqli->prepare($updateSql);
|
||||
|
||||
foreach ($flatDependencyMap as $id => $completeDependencyArray) {
|
||||
if (empty($completeDependencyArray)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$jsonString = json_encode($completeDependencyArray);
|
||||
|
||||
// Bind parameters: 's' for string (JSON), 'i' for integer (ID)
|
||||
$stmt->bind_param("si", $jsonString, $id);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
echo json_encode(['success' => true, 'message' => "Abhaengigkeiten berechnet"]);
|
||||
exit;
|
||||
201
www/intern/scripts/kampfrichter/ajax/neu.php
Normal file
201
www/intern/scripts/kampfrichter/ajax/neu.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
|
||||
session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_kampfrichter']) || $_SESSION['access_granted_kampfrichter'] !== true || empty($_SESSION['passcodekampfrichter_id']) || $_SESSION['passcodekampfrichter_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'kr';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
|
||||
$person_id = isset($_POST['personId']) ? intval($_POST['personId']) : 0;
|
||||
$field_type_id = intval($_POST['fieldTypeId'] ?? 0);
|
||||
$gereat_id = intval($_POST['gereatId'] ?? 0);
|
||||
$jahr = isset($_POST['jahr']) ? intval($_POST['jahr']) : 0;
|
||||
|
||||
if (!isset($_POST['value'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'Kein Value angegeben']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$value = floatval($_POST['value']);
|
||||
|
||||
if ($person_id < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Personen-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($jahr < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalides Jahr']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($gereat_id < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Geraet-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$geratExistiert = db_get_var($mysqli, "SELECT 1 FROM $tableNotenBezeichnungen WHERE id = ? LIMIT 1", [$gereat_id]);
|
||||
|
||||
if (!$geratExistiert) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Geraet-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($field_type_id < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Notentyp-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$noteConfig = db_select($mysqli, $tableNotenBezeichnungen, "*", "id = ?", [$field_type_id]);
|
||||
|
||||
if (count($noteConfig) !== 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Notentyp-ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$singleNoteConfig = $noteConfig[0];
|
||||
|
||||
if ($singleNoteConfig['max_value'] !== null && $value > $singleNoteConfig['max_value']) {
|
||||
echo json_encode(['success' => false, 'message' => "Wert zu hoch (max " . $singleNoteConfig['max_value'].")"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($singleNoteConfig['min_value'] !== null && $value < $singleNoteConfig['min_value']){
|
||||
echo json_encode(['success' => false, 'message' => "Wert zu niedrig (min " . $singleNoteConfig['min_value'].")"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO $tableNoten (`value`, `person_id`, `note_bezeichnung_id`, `geraet_id`, `jahr`)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
$stmt->bind_param("siiii", $value, $person_id, $field_type_id, $gereat_id, $jahr);
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if ($singleNoteConfig['berechnung_json'] === null) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . "/../scripts/string-calculator/string-calculator-functions.php";
|
||||
|
||||
$updateNoten = [];
|
||||
|
||||
$notenRechner = new NotenRechner();
|
||||
|
||||
try {
|
||||
$abhaenigeRechnungen = json_decode($singleNoteConfig['berechnung_json']);
|
||||
} catch (Exception $e) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert, fehler bei der Berechnung der weiteren Werte"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Alle Werte werden von der Datenbank geholt und werden, wenn nicht vorhanden, durch den Standartwert ersetzt.
|
||||
|
||||
$alleNoten = db_select($mysqli, $tableNotenBezeichnungen, "id, berechnung, default_value, nullstellen");
|
||||
|
||||
$noten = db_select($mysqli, $tableNoten, "`value`, `note_bezeichnung_id`", "`person_id` = ? AND `geraet_id` = ? AND `jahr` = ?", [$person_id, $gereat_id, $jahr]);
|
||||
|
||||
$ascArrayDefaultValues = array_column($alleNoten, 'default_value', 'id');
|
||||
$ascArrayRechnungen = array_column($alleNoten, 'berechnung', 'id');
|
||||
|
||||
$existierendeNotenIds = array_column($noten, 'note_bezeichnung_id') ?? [];
|
||||
|
||||
$alleNotenIds = array_column($alleNoten, 'id') ?? [];
|
||||
|
||||
$nichtExistierendeNotenIds = array_diff($alleNotenIds, $existierendeNotenIds) ?? [];
|
||||
|
||||
$noten = array_column($noten, 'value', 'note_bezeichnung_id');
|
||||
|
||||
foreach ($nichtExistierendeNotenIds as $neni) {
|
||||
if (!isset($ascArrayDefaultValues[$neni])) { continue; }
|
||||
$noten[$neni] = $ascArrayDefaultValues[$neni];
|
||||
}
|
||||
|
||||
// We only want to save the IDs that were actually recalculated
|
||||
$idsToSave = [];
|
||||
|
||||
foreach ($abhaenigeRechnungen as $sRechnung) {
|
||||
$rechnung = $ascArrayRechnungen[$sRechnung] ?? null;
|
||||
|
||||
if ($rechnung === null) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert, Fehler: Rechnung $sRechnung nicht gefunden"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$calcResult = $notenRechner->berechneString($rechnung, $noten);
|
||||
if ($calcResult['success'] !== true) {
|
||||
echo json_encode(['success' => true, 'message' => "Wert aktualisiert, Rechenfehler: " . ($calcResult['value'] ?? '')]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Update the local array so the NEXT calculation in the loop can use this new value
|
||||
$noten[$sRechnung] = $calcResult['value'];
|
||||
|
||||
// Track that this ID needs to be written to the database
|
||||
$idsToSave[] = $sRechnung;
|
||||
}
|
||||
|
||||
// Prepare the statement once
|
||||
$sql = "INSERT INTO $tableNoten (`value`, `person_id`, `note_bezeichnung_id`, `geraet_id`, `jahr`)
|
||||
VALUES (?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
foreach ($idsToSave as $notenId) {
|
||||
$currentValue = $noten[$notenId]; // Get the calculated value from our array
|
||||
|
||||
// i = integer, s = string (use 's' for decimals/floats to prevent rounding issues in PHP)
|
||||
$stmt->bind_param("siiii", $currentValue, $person_id, $notenId, $gereat_id, $jahr);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$mysqli->close();
|
||||
|
||||
// 1. Combine the ID the user sent with the IDs we recalculated
|
||||
$changedIds = array_merge([$field_type_id], $idsToSave);
|
||||
|
||||
// 2. Filter the $noten array to only include these keys
|
||||
// array_flip turns [10, 20] into [10 => 0, 20 => 1] so we can intersect by keys
|
||||
$changedNoten = array_intersect_key($noten, array_flip($changedIds));
|
||||
|
||||
$indexedNullstellen = array_column($alleNoten, 'nullstellen', 'id');
|
||||
|
||||
foreach ($changedNoten as $key => $scN) {
|
||||
$changedNoten[$key] = number_format($scN ,$indexedNullstellen[$key] ?? 2);
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => "Wert aktualisiert, alle Berechnungen durchgeführt",
|
||||
"noten" => $changedNoten
|
||||
]);
|
||||
192
www/intern/scripts/kampfrichter/js/js-kampfrichter-admin.js
Normal file
192
www/intern/scripts/kampfrichter/js/js-kampfrichter-admin.js
Normal file
@@ -0,0 +1,192 @@
|
||||
jQuery(document).ready(function($) {
|
||||
$('.ranglisteExport').on('click', function() {
|
||||
const $button = $(this);
|
||||
const progId = $button.data('id');
|
||||
const fieldType = $button.data('field_type');
|
||||
|
||||
// Visual feedback (optional but recommended)
|
||||
$button.prop('disabled', true).text('Generating...');
|
||||
|
||||
const url = '/intern/scripts/kampfrichter/ajax/ajax-neu_rangliste.php';
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
prog: progId,
|
||||
type: fieldType
|
||||
})
|
||||
})
|
||||
.then(response => {
|
||||
// CRITICAL: Check if the server actually returned a success code
|
||||
if (!response.ok) {
|
||||
throw new Error('Server returned an error (Status ' + response.status + ')');
|
||||
}
|
||||
return response.blob();
|
||||
})
|
||||
.then(blob => {
|
||||
if (fieldType !== 'upload_programm') {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = `Ergebnisse_${progId}.pdf`;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
window.URL.revokeObjectURL(url);
|
||||
} else {
|
||||
alert('PDF auf Webseite geladen!');
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Export Error:', error);
|
||||
alert('Fehler beim Exportieren der Rangliste.');
|
||||
})
|
||||
.finally(() => {
|
||||
// Restore button state
|
||||
$button.prop('disabled', false).text('Export PDF');
|
||||
});
|
||||
});
|
||||
|
||||
$('.protokollExport').on('click', function() {
|
||||
console.log('ok');
|
||||
const $input = $(this);
|
||||
|
||||
// Build the data to send
|
||||
const data = new URLSearchParams();
|
||||
data.append('abteilung', $input.data('abteilung'));
|
||||
|
||||
// Record start time
|
||||
const start = performance.now();
|
||||
|
||||
const url = '/intern/scripts/kampfrichter/ajax/ajax-neu_protokoll.php';
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
abteilung: $input.data('abteilung')
|
||||
})
|
||||
})
|
||||
.then(res => res.blob())
|
||||
.then(blob => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = "KTBB_Protokoll.pdf"; // optional
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
let activeEdit = null;
|
||||
|
||||
console.log('pre');
|
||||
|
||||
$(document).on('click', '.editableValue', function () {
|
||||
console.log('ok');
|
||||
const input = $(this);
|
||||
|
||||
// Already editing
|
||||
if (!input.prop('readonly')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Close another active edit
|
||||
if (activeEdit && activeEdit.get(0) !== input.get(0)) {
|
||||
cancelEdit(activeEdit);
|
||||
}
|
||||
|
||||
input.data('original', input.val());
|
||||
input.prop('readonly', false).focus().select();
|
||||
|
||||
activeEdit = input;
|
||||
|
||||
input.on('keydown.edit', function (e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
saveEdit(input);
|
||||
}
|
||||
|
||||
if (e.key === 'Escape') {
|
||||
e.preventDefault();
|
||||
cancelEdit(input);
|
||||
}
|
||||
});
|
||||
|
||||
input.on('blur.edit', function () {
|
||||
saveEdit(input);
|
||||
});
|
||||
});
|
||||
|
||||
function saveEdit(input) {
|
||||
const originalValue = input.data('original');
|
||||
const newValue = input.val();
|
||||
const type = input.data('type');
|
||||
const discipline = input.data('discipline');
|
||||
const dataId = input.data('id');
|
||||
|
||||
if (newValue === originalValue) {
|
||||
input.prop('readonly', true);
|
||||
cleanup(input);
|
||||
return;
|
||||
}
|
||||
|
||||
input.addClass('is-saving');
|
||||
|
||||
$.ajax({
|
||||
url: '/intern/scripts/kampfrichter/ajax/ajax-update_value_kampfrichter_admin.php',
|
||||
method: 'POST',
|
||||
data: {
|
||||
id: dataId,
|
||||
field_type: type,
|
||||
discipline: discipline,
|
||||
value: newValue
|
||||
},
|
||||
success: function () {
|
||||
input.prop('readonly', true);
|
||||
|
||||
const row = input.closest('td');
|
||||
if (row.length) {
|
||||
row.css(
|
||||
'background',
|
||||
'radial-gradient(circle at bottom right, #22c55e, transparent 55%)'
|
||||
);
|
||||
|
||||
setTimeout(() => row.css('background', ''), 2000);
|
||||
}
|
||||
|
||||
ws.send(JSON.stringify({
|
||||
type: "KAMPFRICHTER_UPDATE",
|
||||
payload: {
|
||||
discipline: discipline,
|
||||
id: dataId,
|
||||
val: newValue
|
||||
}
|
||||
}));
|
||||
},
|
||||
error: function () {
|
||||
input.val(originalValue).prop('readonly', true);
|
||||
alert('Speichern fehlgeschlagen');
|
||||
},
|
||||
complete: function () {
|
||||
input.removeClass('is-saving');
|
||||
cleanup(input);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function cancelEdit(input) {
|
||||
input.val(input.data('original')).prop('readonly', true);
|
||||
cleanup(input);
|
||||
}
|
||||
|
||||
function cleanup(input) {
|
||||
input.off('.edit');
|
||||
activeEdit = null;
|
||||
}
|
||||
|
||||
});
|
||||
876
www/intern/scripts/kampfrichter/js/js-kampfrichter-normal.js
Normal file
876
www/intern/scripts/kampfrichter/js/js-kampfrichter-normal.js
Normal file
@@ -0,0 +1,876 @@
|
||||
document.addEventListener('keydown', function (e) {
|
||||
// Mac = Option, Windows/Linux = Alt
|
||||
const isOptionOrAlt = e.altKey || e.metaKey;
|
||||
|
||||
if (isOptionOrAlt && e.shiftKey && e.key.toLowerCase() === 'f') {
|
||||
toggleFullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
function toggleFullscreen() {
|
||||
// If not in fullscreen → enter fullscreen
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement.requestFullscreen()
|
||||
.catch(err => console.error("Fullscreen error:", err));
|
||||
}
|
||||
// If already fullscreen → exit fullscreen
|
||||
else {
|
||||
document.exitFullscreen();
|
||||
}
|
||||
}
|
||||
|
||||
let messagePosArray = [];
|
||||
|
||||
function displayMsg(type, msg) {
|
||||
const colors = ["#900000ff", "#00b200ff"];
|
||||
if (type !== 0 && type !== 1) return;
|
||||
|
||||
|
||||
// idx is ALWAYS a valid non-negative index now
|
||||
const $div = $('<div class="msgBox"></div>')
|
||||
.css({'border-color': colors[type]})
|
||||
.text(msg);
|
||||
|
||||
$('.msgDiv').append($div);
|
||||
|
||||
// trigger entry animation
|
||||
setTimeout(() => {
|
||||
$div.addClass('show');
|
||||
}, 200);
|
||||
|
||||
setTimeout(() => {
|
||||
// First: set the transition properties
|
||||
$div.css({
|
||||
'transition': 'all 0.3s ease'
|
||||
});
|
||||
|
||||
// Next frame: apply the transform so the transition animates
|
||||
requestAnimationFrame(() => {
|
||||
$div.removeClass('show');
|
||||
$div.css({
|
||||
'transform': 'scaleY(0) translateX(calc(100% + 40px))'
|
||||
});
|
||||
});
|
||||
}, 3000);
|
||||
|
||||
// auto-remove
|
||||
setTimeout(() => {
|
||||
$div.remove();
|
||||
}, 3500);
|
||||
}
|
||||
|
||||
const text = document.getElementById('wsInfo');
|
||||
const rect = document.getElementById('wsInfoRectangle');
|
||||
|
||||
let ws;
|
||||
let firstConnect = true;
|
||||
const RETRY_DELAY = 2000; // ms
|
||||
|
||||
const urlAjaxNewWSToken = '/intern/scripts/ajax-create-ws-token.php';
|
||||
|
||||
async function fetchNewWSToken(freigabe) {
|
||||
try {
|
||||
const response = await fetch(urlAjaxNewWSToken, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({ access: freigabe })
|
||||
});
|
||||
|
||||
if (!response.ok) return null;
|
||||
|
||||
const data = await response.json();
|
||||
return data.success ? data.token : null;
|
||||
} catch (error) {
|
||||
console.error("Token fetch failed:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function startWebSocket() {
|
||||
console.log("Attempting WebSocket connection...");
|
||||
|
||||
let token;
|
||||
if (firstConnect) {
|
||||
token = window.WS_ACCESS_TOKEN;
|
||||
} else {
|
||||
token = await fetchNewWSToken('kampfrichter');
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
console.error("No valid token available. Retrying...");
|
||||
scheduleRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ws = new WebSocket(`wss://${window.location.hostname}/ws/?access=token&token=${token}`);
|
||||
} catch (err) {
|
||||
console.error("Malformed WebSocket URL", err);
|
||||
scheduleRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log("WebSocket connected!");
|
||||
if (!firstConnect) {
|
||||
displayMsg(1, "Live Syncronisation wieder verfügbar");
|
||||
}
|
||||
firstConnect = true;
|
||||
rect.innerHTML =
|
||||
'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" fill="#28a745"></circle><path d="M7 12l3 3 7-7" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"></path></svg>';
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
text.style.opacity = 1;
|
||||
});
|
||||
};
|
||||
|
||||
ws.onerror = (event) => {
|
||||
console.error("WebSocket error observed." + JSON.stringify(event));
|
||||
};
|
||||
|
||||
ws.onclose = (event) => {
|
||||
displayMsg(0, "Live Syncronisation verloren");
|
||||
firstConnect = false;
|
||||
rect.innerHTML =
|
||||
'<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="12" cy="12" r="10" fill="#dc3545"/><path d="M8 8l8 8M16 8l-8 8" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
text.style.opacity = 1;
|
||||
});
|
||||
|
||||
scheduleRetry();
|
||||
};
|
||||
}
|
||||
|
||||
function scheduleRetry() {
|
||||
console.log(`Retrying in ${RETRY_DELAY}ms...`);
|
||||
setTimeout(startWebSocket, RETRY_DELAY);
|
||||
}
|
||||
|
||||
// Start the initial connection attempt safely
|
||||
startWebSocket();
|
||||
|
||||
|
||||
|
||||
$.fn.updateCurrentEdit = function() {
|
||||
return this.each(function() {
|
||||
const $input = $(this);
|
||||
|
||||
const url = '/intern/scripts/kampfrichter/ajax/ajax-kampfrichter_currentedit.php';
|
||||
|
||||
if ($input.attr('data-person-id') === "0"){
|
||||
$('<form>', {
|
||||
action: '/intern/kampfrichter',
|
||||
method: 'post'
|
||||
})
|
||||
.append($('<input>', {
|
||||
type: 'hidden',
|
||||
name: 'next_subabt',
|
||||
value: 1
|
||||
}))
|
||||
.append($('<input>', {
|
||||
type: 'hidden',
|
||||
name: 'next_subabt_submit',
|
||||
value: '>'
|
||||
}))
|
||||
.appendTo('body')
|
||||
.submit();
|
||||
}
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
csrf_token: window.CSDR_TOKEN,
|
||||
editId: $input.attr('data-person-id'),
|
||||
geraet: $input.attr('data-geraet-id') ?? null
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
|
||||
$(".current-turnerin-name").css({
|
||||
'color': '#209200ff',
|
||||
'transition': 'all 0.3s ease-out'
|
||||
});
|
||||
setTimeout(() => $(".current-turnerin-name").css({
|
||||
'color': ''
|
||||
}), 2000);
|
||||
|
||||
$(".div_edit_values_user").css("display", "flex");
|
||||
|
||||
$(".current-turnerin-name").text(response.titel);
|
||||
|
||||
$(".fv_nextturnerin").text(response.nturnerin?.name ?? '');
|
||||
$(".fv_nextturnerin").val(response.nturnerin?.id ?? 0).attr('data-person-id', response.nturnerin?.id ?? 0);
|
||||
|
||||
$(".submit-display-turnerin").css("opacity", "1");
|
||||
$(".submit-display-start").css("opacity", "1");
|
||||
$(".submit-display-result").css("opacity", "1");
|
||||
|
||||
const $editAllDiv = $('.div_edit_values_all_gereate');
|
||||
const noten = response.noten;
|
||||
const programmId = response.programm_id;
|
||||
|
||||
// First, reset all containers to a single input state and clear values
|
||||
$editAllDiv.find('.note-container').each(function() {
|
||||
const $container = $(this);
|
||||
const $tbody = $container.find('tbody');
|
||||
const $headerRow = $container.find('thead tr');
|
||||
|
||||
// Reset header
|
||||
$headerRow.find('.run-num-header').remove();
|
||||
|
||||
// Remove extra inputs beyond run 1
|
||||
$tbody.find('.inputs-row').each(function() {
|
||||
$(this).find('td:not(.input-cell-run-1)').remove();
|
||||
});
|
||||
|
||||
// Clear value of run 1
|
||||
$container.find('input[data-run="1"]').val('').attr('data-person-id', response.id);
|
||||
});
|
||||
|
||||
// Now loop through the data and populate/expand
|
||||
for (const [geraetId, noteGroup] of Object.entries(noten)) {
|
||||
for (const [noteId, runGroup] of Object.entries(noteGroup)) {
|
||||
const $container = $editAllDiv.find(`.note-container[data-note-id="${noteId}"]`);
|
||||
if ($container.length === 0) continue;
|
||||
|
||||
const $tbody = $container.find('tbody');
|
||||
const $headerRow = $container.find('thead tr');
|
||||
const $inputsRow = $tbody.find('.inputs-row');
|
||||
|
||||
const runCount = Object.keys(runGroup).length;
|
||||
|
||||
$headerRow.find('.note-name-header .rm').remove();
|
||||
|
||||
const originalText = $headerRow.find('.note-name-header').text().trim();
|
||||
|
||||
// If more than 1 run, add headers if not already present
|
||||
if (runCount > 1 && $headerRow.find('.run-num-header').length === 0) {
|
||||
$headerRow.find('.note-name-header').html(originalText + ' <span class="rm">(R1)</span>');
|
||||
for (let r = 2; r <= runCount; r++) {
|
||||
$headerRow.append(`<th class="run-num-header">${originalText} <span class="rm">(R${r})</span></th>`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const [runNum, val] of Object.entries(runGroup)) {
|
||||
let $input = $inputsRow.find(`input[data-run="${runNum}"][data-geraet-id="${geraetId}"]`);
|
||||
|
||||
// If input doesn't exist yet (for Run 2+), clone it
|
||||
if ($input.length === 0) {
|
||||
const $cell1 = $inputsRow.find('.input-cell-run-1');
|
||||
const $newCell = $cell1.clone();
|
||||
$newCell.removeClass('input-cell-run-1').addClass(`input-cell-run-${runNum}`);
|
||||
|
||||
$input = $newCell.find('input');
|
||||
$input.attr('data-run', runNum).val(val ?? '');
|
||||
$inputsRow.append($newCell);
|
||||
|
||||
// Re-bind change event to new input
|
||||
//bindAjaxInput($input);
|
||||
} else {
|
||||
$input.val(val ?? '').attr('data-person-id', response.id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(".submit-display-turnerin").attr('data-person-id', response.id);
|
||||
$(".submit-display-start").attr('data-person-id', response.id);
|
||||
|
||||
|
||||
const submitMusikStart = $(".submit-musik-start");
|
||||
const submitMusikStopp = $(".submit-musik-stopp");
|
||||
|
||||
if (submitMusikStart.length > 0 && submitMusikStopp.length > 0){
|
||||
submitMusikStart.attr('data-id', response.id);
|
||||
submitMusikStopp.attr('data-id', response.id);
|
||||
}
|
||||
|
||||
$(".submit-display-result").attr('data-person-id', response.id);
|
||||
|
||||
} else {
|
||||
displayMsg(0, response.message);
|
||||
$input.css({
|
||||
'background-color': '#f8d7da',
|
||||
'color': '#fff',
|
||||
'transition': 'all 0.3s ease-out'
|
||||
});
|
||||
setTimeout(() => $input.css({
|
||||
'background-color': '',
|
||||
'color': ''
|
||||
}), 2000);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css('background-color', '#f8d7da');
|
||||
console.error('AJAX fetch error:', err);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
jQuery(document).ready(function($) {
|
||||
|
||||
|
||||
$('.editTurnerin').on('click', function() {
|
||||
$(this).updateCurrentEdit();
|
||||
});
|
||||
|
||||
|
||||
|
||||
function bindAjaxInput($el) {
|
||||
$el.on('change', function() {
|
||||
const start = performance.now();
|
||||
const $input = $(this);
|
||||
|
||||
const url = `/intern/scripts/kampfrichter/ajax/ajax-update_value_kampfrichter.php`;
|
||||
|
||||
personId = $input.data('person-id');
|
||||
fieldTypeId = $input.data('field-type-id');
|
||||
gereatId = $input.data('geraet-id');
|
||||
runNum = $input.attr('data-run') || 1;
|
||||
jahr = window.AKTUELLES_JAHR;
|
||||
value = $input.val();
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
personId: personId,
|
||||
fieldTypeId: fieldTypeId,
|
||||
gereatId: gereatId,
|
||||
run: runNum,
|
||||
jahr: jahr,
|
||||
value: value
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
const end = performance.now();
|
||||
console.log(`Total AJAX time: ${(end - start).toFixed(3)} ms`);
|
||||
|
||||
if (response.success) {
|
||||
|
||||
let objValues = [];
|
||||
|
||||
const rowId = $input.attr('data-id');
|
||||
|
||||
$input.css({"color": "#0e670d", "font-weight": "600"});
|
||||
|
||||
|
||||
setTimeout(() => $input.css({'color': '', "font-weight": ""}), 2000);
|
||||
|
||||
const noten = response.noten;
|
||||
|
||||
for (const [keyN, noteGroup] of Object.entries(noten)) {
|
||||
for (const [key, runGroup] of Object.entries(noteGroup)) {
|
||||
if (key == fieldTypeId && keyN == gereatId) { continue; }
|
||||
|
||||
for (const [run, value] of Object.entries(runGroup)) {
|
||||
$(`input.changebleValue[data-field-type-id="${key}"][data-geraet-id="${keyN}"][data-person-id="${personId}"][data-run="${run}"]`)
|
||||
.val(value ?? '');
|
||||
$(`.changebleValue:not(input)[data-field-type-id="${key}"][data-geraet-id="${keyN}"][data-person-id="${personId}"][data-run="${run}"]`)
|
||||
.text(value ?? '');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ws.send(JSON.stringify({
|
||||
type: "KAMPFRICHTER_UPDATE",
|
||||
payload: {
|
||||
discipline: window.FREIGABE,
|
||||
gereatId: gereatId,
|
||||
personId: personId,
|
||||
jahr: jahr,
|
||||
noten: noten
|
||||
}
|
||||
}));
|
||||
|
||||
} else {
|
||||
// Flash red on error
|
||||
$input.css({'color': '#ff6a76ff'});
|
||||
displayMsg(0, response.message || 'Unknown error');
|
||||
console.error(response.message || 'Unknown error');
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css({'color': '#670d0d'});
|
||||
console.error('AJAX fetch error:', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$('.ajax-input').each(function() {
|
||||
bindAjaxInput($(this));
|
||||
});
|
||||
|
||||
|
||||
/*$('.ranglisteExport').on('click', function(e) {
|
||||
const $input = $(this);
|
||||
if ($input.data('field_type') !== 'upload_programm') {e.preventDefault();}
|
||||
|
||||
|
||||
// Build the data to send
|
||||
const data = new URLSearchParams();
|
||||
data.append('prog', $input.data('id'));
|
||||
data.append('type', $input.data('field_type'));
|
||||
|
||||
// Record start time
|
||||
const start = performance.now();
|
||||
|
||||
const url = '/intern/scripts/kampfrichter/ajax/ajax-neu_rangliste.php';
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
prog: $input.data('id'),
|
||||
type: $input.data('field_type')
|
||||
})
|
||||
})
|
||||
.then(res => res.blob())
|
||||
.then(blob => {
|
||||
if ($input.data('field_type') !== 'upload_programm'){
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = "KTBB_Ergebnisse.pdf"; // optional
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
} else {
|
||||
alert('PDF auf Webseite geladen!');
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$('.protokollExport').on('click', function() {
|
||||
console.log('ok');
|
||||
const $input = $(this);
|
||||
|
||||
// Build the data to send
|
||||
const data = new URLSearchParams();
|
||||
data.append('abteilung', $input.data('abteilung'));
|
||||
|
||||
// Record start time
|
||||
const start = performance.now();
|
||||
|
||||
const url = '/intern/scripts/kampfrichter/ajax/ajax-neu_protokoll.php';
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
abteilung: $input.data('abteilung')
|
||||
})
|
||||
})
|
||||
.then(res => res.blob())
|
||||
.then(blob => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = "KTBB_Protokoll.pdf"; // optional
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
a.remove();
|
||||
window.URL.revokeObjectURL(url);
|
||||
});
|
||||
|
||||
});*/
|
||||
|
||||
$('.inputnamekr').on('change', function() {
|
||||
const $input = $(this);
|
||||
|
||||
|
||||
const url = '/intern/scripts/kampfrichter/ajax/ajax-update_name_kampfrichter_protokoll.php';
|
||||
|
||||
fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
aufgabe: $input.data('id'),
|
||||
abteilung: $input.data('abt'),
|
||||
geraet: $input.data('user'),
|
||||
name: $input.val()
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
console.log(response.message);
|
||||
$input.css({
|
||||
'background-color': '#a4bf4a',
|
||||
'color': '#fff',
|
||||
'transition': 'all 0.3s ease-out'
|
||||
});
|
||||
setTimeout(() => $input.css({
|
||||
'background-color': '',
|
||||
'color': ''
|
||||
}), 2000);
|
||||
} else {
|
||||
console.error(response.message);
|
||||
$input.css({
|
||||
'background-color': '#f8d7da',
|
||||
'color': '#fff',
|
||||
'transition': 'all 0.3s ease-out'
|
||||
});
|
||||
setTimeout(() => $input.css({
|
||||
'background-color': '',
|
||||
'color': ''
|
||||
}), 2000);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css('background-color', '#f8d7da');
|
||||
console.error('AJAX fetch error:', err);
|
||||
displayMsg(0, 'AJAX fetch error:' + err);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Handle namekr input updates
|
||||
|
||||
$('.ajax-input-namekr').on('change', function() {
|
||||
let $input = $(this);
|
||||
|
||||
$.post(ajax_object.ajaxurl, {
|
||||
action: 'save_namekr_input',
|
||||
id: $input.data('id'),
|
||||
abt: $input.data('abt'),
|
||||
user: $input.data('user'),
|
||||
value: $input.val()
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
console.log(response.data.message);
|
||||
$input.css({
|
||||
'background-color': '#a4bf4a',
|
||||
'color': '#fff',
|
||||
'transition': 'all 0.3s ease-out'
|
||||
});
|
||||
setTimeout(() => $input.css({
|
||||
'background-color': '',
|
||||
'color': ''
|
||||
}), 2000);
|
||||
} else {
|
||||
console.error(response.data.message);
|
||||
$input.css({
|
||||
'background-color': '#f8d7da',
|
||||
'color': '#fff',
|
||||
'transition': 'all 0.3s ease-out'
|
||||
});
|
||||
setTimeout(() => $input.css({
|
||||
'background-color': '',
|
||||
'color': ''
|
||||
}), 2000);
|
||||
}
|
||||
}, 'json');
|
||||
}); */
|
||||
|
||||
|
||||
/**
|
||||
* Handle display JSON updates
|
||||
*/
|
||||
$('.submit-display-turnerin').on('click', function() {
|
||||
const $input = $(this);
|
||||
|
||||
// Build the URL with GET parameters safely
|
||||
const url = '/intern/scripts/kampfrichter/ajax/displays/ajax-display-functions.php';
|
||||
|
||||
fetch(url,{
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
personId: $input.attr('data-person-id'),
|
||||
geraetId: $input.attr('data-geraet-id'),
|
||||
jahr: window.AKTUELLES_JAHR,
|
||||
type: "neu"
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
|
||||
if (response.success) {
|
||||
ws.send(JSON.stringify({
|
||||
type: "UPDATE_SCORE",
|
||||
payload: {
|
||||
geraet: response.nameGeraet,
|
||||
data: response.data
|
||||
}
|
||||
}));
|
||||
displayMsg(1, 'Neue Turnerin wird angezigt');
|
||||
|
||||
$input.css('opacity', 0.5);
|
||||
} else {
|
||||
displayMsg(0, response.message);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css('background-color', '#f8d7da');
|
||||
displayMsg(0, 'AJAX fetch error:' + err);
|
||||
console.error('AJAX fetch error:', err);
|
||||
});
|
||||
});
|
||||
|
||||
$('.submit-display-start').on('click', function() {
|
||||
const $input = $(this);
|
||||
|
||||
const url = '/intern/scripts/kampfrichter/ajax/displays/ajax-display-functions.php';
|
||||
|
||||
fetch(url,{
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
geraetId: $input.attr('data-geraet-id'),
|
||||
type: "start"
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
|
||||
if (response.success) {
|
||||
ws.send(JSON.stringify({
|
||||
type: "UPDATE_SCORE",
|
||||
payload: {
|
||||
geraet: response.nameGeraet,
|
||||
data: response.data
|
||||
}
|
||||
}));
|
||||
displayMsg(1, 'Start freigegeben');
|
||||
|
||||
$input.css('opacity', 0.5);
|
||||
} else {
|
||||
alert('Error: ' + response.message);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css('background-color', '#f8d7da');
|
||||
displayMsg(0, 'AJAX fetch error:' + err);
|
||||
console.error('AJAX fetch error:', err);
|
||||
});
|
||||
});
|
||||
|
||||
/*$('.submit-display-start').on('click', function() {
|
||||
let discipline = $(this).data('discipline');
|
||||
|
||||
$.post(ajax_object.ajaxurl, {
|
||||
action: 'write_discipline_json_start',
|
||||
discipline: discipline
|
||||
}, function(response) {
|
||||
if (response.success) {
|
||||
alert('Start freigegeben');
|
||||
|
||||
if (response.data.disable_start_button) {
|
||||
$('.submit-display-start').css({
|
||||
'border': '1px solid #aaa',
|
||||
'background-color': '#aaa',
|
||||
'color': '#555',
|
||||
'pointer-events': 'none'
|
||||
});
|
||||
$('.submit-musik-start').css({
|
||||
'background-color': '#077',
|
||||
'border': '1px solid #077',
|
||||
'color': '#fff',
|
||||
'cursor': 'pointer',
|
||||
'pointer-events': 'auto'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
alert('Error: ' + response.data.message);
|
||||
}
|
||||
}, 'json');
|
||||
});*/
|
||||
|
||||
|
||||
$('.submit-musik-start').on('click', function() {
|
||||
const $input = $(this);
|
||||
|
||||
// Build the URL with GET parameters safely
|
||||
const url = `/intern/scripts/kampfrichter/ajax/ajax-update_kampfrichter_start_musik.php` +
|
||||
`?id=${$input.attr('data-id')}` +
|
||||
`&discipline=${encodeURIComponent($input.data('geraet'))}`;
|
||||
|
||||
fetch(url)
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
const end = performance.now();
|
||||
ws.send(JSON.stringify({
|
||||
type: "AUDIO",
|
||||
payload: {}
|
||||
}));
|
||||
|
||||
if (response.success) {
|
||||
displayMsg(1, 'Musik wird abgespielt werden');
|
||||
} else {
|
||||
displayMsg(0, 'Error: ' + response.message);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css('background-color', '#f8d7da');
|
||||
displayMsg(0, 'AJAX fetch error:' + err);
|
||||
console.error('AJAX fetch error:', err);
|
||||
});
|
||||
});
|
||||
|
||||
$('.submit-musik-stopp').on('click', function() {
|
||||
const $input = $(this);
|
||||
|
||||
// Build the URL with GET parameters safely
|
||||
const url = `/intern/scripts/kampfrichter/ajax/ajax-update_kampfrichter_stopp_musik.php`;
|
||||
|
||||
fetch(url)
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
ws.send(JSON.stringify({
|
||||
type: "AUDIO",
|
||||
payload: {}
|
||||
}));
|
||||
displayMsg(1, 'Musik wird gestoppt werden');
|
||||
} else {
|
||||
alert('Error: ' + response.message);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css('background-color', '#f8d7da');
|
||||
displayMsg(0, 'AJAX fetch error:' + err);
|
||||
console.error('AJAX fetch error:', err);
|
||||
});
|
||||
});
|
||||
|
||||
$('.submit-display-result').on('click', function() {
|
||||
$input = $(this);
|
||||
|
||||
// Build the URL with GET parameters safely
|
||||
const url = '/intern/scripts/kampfrichter/ajax/displays/ajax-display-functions.php';
|
||||
|
||||
fetch(url,{
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
|
||||
body: new URLSearchParams({
|
||||
personId: $input.attr('data-person-id'),
|
||||
geraetId: $input.attr('data-geraet-id'),
|
||||
jahr: window.AKTUELLES_JAHR,
|
||||
type: "result"
|
||||
})
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(response => {
|
||||
|
||||
if (response.success) {
|
||||
ws.send(JSON.stringify({
|
||||
type: "UPDATE_SCORE",
|
||||
payload: {
|
||||
geraet: response.nameGeraet,
|
||||
data: response.data
|
||||
}
|
||||
}));
|
||||
$input.css('opacity', 0.5);
|
||||
displayMsg(1, 'Resultat wird angezeigt');
|
||||
} else {
|
||||
alert('Error: ' + response.message);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
$input.css('background-color', '#f8d7da');
|
||||
displayMsg(0, 'AJAX fetch error:' + err);
|
||||
console.error('AJAX fetch error:', err);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
const selecteddiscipline = window.FREIGABE;
|
||||
|
||||
ws.addEventListener("message", event => { // Use 'event' as it's more standard than 'blob'
|
||||
let msgOBJ;
|
||||
|
||||
try {
|
||||
msgOBJ = JSON.parse(event.data);
|
||||
} catch (error) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure it's an UPDATE type (matches your sendToGroup logic)
|
||||
if (msgOBJ?.type === "UPDATE") {
|
||||
const data = msgOBJ.payload;
|
||||
|
||||
// Check access rights
|
||||
if (data.discipline === selecteddiscipline.toLowerCase() || selecteddiscipline.toLowerCase() === 'admin') {
|
||||
const noten = data.noten;
|
||||
|
||||
for (const [keyG, noteGroup] of Object.entries(noten)) {
|
||||
for (const [key, runGroup] of Object.entries(noteGroup)) {
|
||||
|
||||
for (const [run, value] of Object.entries(runGroup)) {
|
||||
// OPTIONAL: Skip if the current user is currently focused on this specific input
|
||||
if (document.activeElement.dataset.fieldTypeId === key &&
|
||||
document.activeElement.dataset.geraetId === keyG &&
|
||||
document.activeElement.dataset.run == run) continue;
|
||||
|
||||
// Select all matching elements (inputs and spans)
|
||||
const $elements = $(`.changebleValue[data-field-type-id="${key}"][data-geraet-id="${keyG}"][data-person-id="${data.personId}"][data-run="${run}"]`);
|
||||
|
||||
$elements.each(function() {
|
||||
const $el = $(this);
|
||||
|
||||
// Update value or text
|
||||
if ($el.is('input')) {
|
||||
$el.val(value ?? '');
|
||||
} else {
|
||||
$el.text(value ?? '');
|
||||
}
|
||||
|
||||
// Visual feedback: Flash color
|
||||
const nativeEl = $el[0];
|
||||
nativeEl.style.transition = 'color 0.3s';
|
||||
nativeEl.style.color = '#008e85';
|
||||
|
||||
setTimeout(() => {
|
||||
nativeEl.style.color = '';
|
||||
}, 1000);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/*document.getElementById('freigabe-select').addEventListener('change', function() {
|
||||
const freigabe = this.value;
|
||||
const user_id = document.getElementById('user_id').value;
|
||||
const nonce = document.getElementById('freigabe_nonce').value;
|
||||
const type = document.getElementById('type_freigabe').value;
|
||||
|
||||
const params = new URLSearchParams();
|
||||
params.append('action', 'save_freigabe');
|
||||
params.append('freigabe', freigabe);
|
||||
params.append('user_id', user_id);
|
||||
params.append('type', type);
|
||||
|
||||
fetch('/intern/scripts/kampfrichter/ajax/ajax-update_selected_kampfrichter.php', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: params
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
if (data.success) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
alert('Error: ' + data.data);
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err);
|
||||
displayMsg(0, 'AJAX fetch error:' + err);
|
||||
});
|
||||
});*/
|
||||
@@ -0,0 +1,34 @@
|
||||
function allNameKrValid() {
|
||||
var isValid = true;
|
||||
|
||||
$('.ajax-input-namekr').each(function () {
|
||||
if ($(this).val() === '---') {
|
||||
isValid = false;
|
||||
return false; // break loop
|
||||
}
|
||||
});
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
function updateSelectKrDiv() {
|
||||
const krDiv = $('.noKampfrichterDiv');
|
||||
|
||||
if (krDiv.length !== 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (allNameKrValid()) {
|
||||
krDiv.css('display', 'none');
|
||||
} else {
|
||||
krDiv.css('display', 'flex');
|
||||
}
|
||||
}
|
||||
|
||||
// initial check
|
||||
updateSelectKrDiv();
|
||||
|
||||
// react to changes
|
||||
$('.ajax-input-namekr').on('change', function () {
|
||||
updateSelectKrDiv();
|
||||
});
|
||||
84
www/intern/scripts/logindata/ajax-neu_programm.php
Normal file
84
www/intern/scripts/logindata/ajax-neu_programm.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
$token = isset($_GET['token']) ? $_GET['token'] : '';
|
||||
|
||||
if ($token !== 'sWZ4GxbsoVhUPk5zhjH0uU9hets3zV2KsV8CZUvAWCCRk4uuuDr9vfFVgxWqr5FtDttbtm50EdWK9YxuMPswGZBQZFHAUAET1aG1'){
|
||||
echo json_encode(['success' => false, 'message' => '500 Error - Critical Server Error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$value = isset($_GET['value']) ? preg_replace('/[^a-zA-Z0-9\s\-"]/u', '', $_GET['value']) : '';
|
||||
|
||||
if (!$value || $value === ''){
|
||||
echo json_encode(['success' => false, 'message' => 'No input']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO `$tableProgramme` (programm) VALUES (?)");
|
||||
if (!$stmt) {
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB ERROR']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param("s", $value);
|
||||
$success = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if (!$success) {
|
||||
echo json_encode(['success' => false, 'message' => 'Insert failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch all rows
|
||||
$query2 = "SELECT * FROM `$tableProgramme` ORDER BY programm ASC";
|
||||
$programme = $mysqli->query($query2);
|
||||
|
||||
if (!$programme) {
|
||||
echo json_encode(['success' => false, 'message' => 'Select failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$output = [];
|
||||
while ($entry = $programme->fetch_assoc()) {
|
||||
$output[] = [
|
||||
'id' => $entry['id'],
|
||||
'programm' => $entry['programm'],
|
||||
'aktiv' => intval($entry['aktiv']),
|
||||
'preis' => floatval($entry['preis'])
|
||||
];
|
||||
}
|
||||
|
||||
// Return JSON
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'output' => $output,
|
||||
'message' => $value.' hinzugefügt'
|
||||
]);
|
||||
exit;
|
||||
89
www/intern/scripts/logindata/ajax-remove_programm.php
Normal file
89
www/intern/scripts/logindata/ajax-remove_programm.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
$token = isset($_GET['token']) ? $_GET['token'] : '';
|
||||
|
||||
if ($token !== 'bKqBAPjwojZdarJaE7jwvRrIEf2WzJUlFlufQadfLJ98qJcrWZK5pRlGoUQOHp1L06urGRbEdE9v5oIRirPiUCjm93wATghO4qx'){
|
||||
echo json_encode(['success' => false, 'message' => '500 Error - Critical Server Error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
|
||||
$stmt = $mysqli->prepare("DELETE FROM `$tableProgramme` WHERE id = ?");
|
||||
if (!$stmt) {
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB ERROR']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param("i", $id);
|
||||
|
||||
$success = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if (!$success) {
|
||||
echo json_encode(['success' => false, 'message' => 'Insert failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Fetch all rows
|
||||
$query2 = "SELECT * FROM `$tableProgramme` ORDER BY programm ASC";
|
||||
$programme = $mysqli->query($query2);
|
||||
|
||||
if (!$programme) {
|
||||
echo json_encode(['success' => false, 'message' => 'Select failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$output = [];
|
||||
while ($entry = $programme->fetch_assoc()) {
|
||||
$output[] = [
|
||||
'id' => $entry['id'],
|
||||
'programm' => $entry['programm'],
|
||||
'aktiv' => intval($entry['aktiv']),
|
||||
'preis' => floatval($entry['preis'])
|
||||
];
|
||||
}
|
||||
|
||||
// Return JSON
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'output' => $output,
|
||||
'message' => $id.' gelöscht'
|
||||
]);
|
||||
exit;
|
||||
159
www/intern/scripts/logindata/ajax-update-user-information.php
Normal file
159
www/intern/scripts/logindata/ajax-update-user-information.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['field_id'])){
|
||||
$id = intval($_POST['field_id']);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid Input.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$editor_id = $_SESSION['passcodewk_leitung_id'];
|
||||
$plain = trim($_POST['password'] ?? '');
|
||||
|
||||
if (!$plain) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid Input.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$username = htmlspecialchars(trim($_POST['username'] ?? ''));
|
||||
|
||||
if (!$username) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid Input.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$freigaben = $_POST['freigaben'] ?? [];
|
||||
$freigabenTrainer = $_POST['freigabenTrainer'] ?? [];
|
||||
$freigabenKampfrichter = $_POST['freigabenKampfrichter'] ?? [];
|
||||
|
||||
if (!is_array($freigaben)) {
|
||||
$freigaben = [];
|
||||
}
|
||||
if (!is_array($freigabenTrainer)) {
|
||||
$freigabenTrainer = [];
|
||||
}
|
||||
if (!is_array($freigabenKampfrichter)) {
|
||||
$freigabenKampfrichter = [];
|
||||
}
|
||||
|
||||
$array = [
|
||||
'types' => $freigaben,
|
||||
'freigabenTrainer' => $freigabenTrainer,
|
||||
'freigabenKampfrichter' => $freigabenKampfrichter
|
||||
];
|
||||
|
||||
// Store as proper JSON string
|
||||
$freigabe_store = json_encode($array);
|
||||
|
||||
// Hash for login
|
||||
$hash = password_hash($plain, PASSWORD_ARGON2ID);
|
||||
|
||||
|
||||
require $baseDir . '/../composer/vendor/autoload.php';
|
||||
|
||||
$envFile = realpath($baseDir . '/../config/.env.pw-encryption-key');
|
||||
|
||||
if ($envFile === false) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Environment file not found"
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
try {
|
||||
$envDir = dirname($envFile);
|
||||
|
||||
$dotenv = Dotenv::createImmutable($envDir, '.env.pw-encryption-key');
|
||||
|
||||
$dotenv->load();
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Dotenv error"
|
||||
]);
|
||||
}
|
||||
|
||||
// Encrypt for display
|
||||
$iv_length = openssl_cipher_iv_length('aes-256-cbc');
|
||||
$iv = random_bytes($iv_length);
|
||||
$encrypted = openssl_encrypt($plain, 'aes-256-cbc', $_ENV['PW_ENCRYPTION_KEY'], 0, $iv);
|
||||
$cipher_store = base64_encode($iv . $encrypted);
|
||||
|
||||
|
||||
if ($id > 0) {
|
||||
$updated = db_update($mysqli, $tableInternUsers, [
|
||||
'password_hash' => $hash,
|
||||
'password_cipher' => $cipher_store,
|
||||
'username' => $username,
|
||||
'freigabe' => $freigabe_store,
|
||||
'updated_at' => date('Y-m-d H:i:s'),
|
||||
'edited_by' => $editor_id
|
||||
], ['id' => $id]);
|
||||
} else {
|
||||
$stmt = $mysqli->prepare(
|
||||
"INSERT INTO {$tableInternUsers}
|
||||
(username, password_hash, password_cipher, freigabe, created_at, updated_at, edited_by)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
|
||||
$stmt->bind_param(
|
||||
"ssssssi",
|
||||
$username,
|
||||
$hash,
|
||||
$cipher_store,
|
||||
$freigabe_store,
|
||||
$created_at,
|
||||
$updated_at,
|
||||
$editor_id
|
||||
);
|
||||
|
||||
$created_at = date('Y-m-d H:i:s');
|
||||
$updated_at = $created_at;
|
||||
|
||||
$updated = $stmt->execute();
|
||||
}
|
||||
|
||||
if ($updated !== false) {
|
||||
if ($id == 0) { // new user
|
||||
$new_id = $mysqli->insert_id;
|
||||
|
||||
echo json_encode(['success' => true, 'message' => $username.' wurde erfolgreich erstellt.', 'id' => $new_id]);
|
||||
} else {
|
||||
echo json_encode(['success' => true, 'message' => $username.' wurde erfolgreich aktualisiert.']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'DB Error']);
|
||||
}
|
||||
60
www/intern/scripts/logindata/ajax-update_programm_aktiv.php
Normal file
60
www/intern/scripts/logindata/ajax-update_programm_aktiv.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$token = isset($_GET['token']) ? $_GET['token'] : '';
|
||||
|
||||
if ($token !== '0UgBVHutbxTRTYsB04ujFKMjMRA8GgdqRJjVh3DKU1LRJfwtcDfrpDc7jpMxcrg9rYurAEwYPy5gu15R77MsgKsDMkFZEykx0A67'){
|
||||
echo json_encode(['success' => false, 'message' => '500 Error - Critical Server Error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
$value = isset($_GET['value']) ? floatval($_GET['value']) : 0;
|
||||
|
||||
|
||||
if ($id < 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
|
||||
$query = "UPDATE `$tableProgramme` SET aktiv = '$value' WHERE id = $id";
|
||||
$result = $mysqli->query($query);
|
||||
|
||||
if (!$result) {
|
||||
echo json_encode(['success' => false, 'message' => 'Update failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'Aktualisiert'
|
||||
]);
|
||||
exit;
|
||||
60
www/intern/scripts/logindata/ajax-update_programm_preis.php
Normal file
60
www/intern/scripts/logindata/ajax-update_programm_preis.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$token = isset($_GET['token']) ? $_GET['token'] : '';
|
||||
|
||||
if ($token !== 'k7uweziEUWZiJhwe7687UWIQZ28SQIH2ug74pINKyxHxPerB6wUZ'){
|
||||
echo json_encode(['success' => false, 'message' => '500 Error - Critical Server Error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// ---------- Get and sanitize input ----------
|
||||
$id = isset($_GET['id']) ? intval($_GET['id']) : 0;
|
||||
$value = isset($_GET['value']) ? round(floatval($_GET['value']), 2) : 0;
|
||||
|
||||
|
||||
if ($id < 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
|
||||
$query = "UPDATE `$tableProgramme` SET preis = '$value' WHERE id = $id";
|
||||
$result = $mysqli->query($query);
|
||||
|
||||
if (!$result) {
|
||||
echo json_encode(['success' => false, 'message' => 'Update failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// ---------- Return JSON ----------
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'Startgebüren set to '.$value.' Fr.'
|
||||
]);
|
||||
exit;
|
||||
67
www/intern/scripts/logindata/ajax-vereine-handler.php
Normal file
67
www/intern/scripts/logindata/ajax-vereine-handler.php
Normal file
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = intval($_POST['field_id']) ?? '';
|
||||
$verein = htmlspecialchars(trim($_POST['verein'] ?? ''));
|
||||
|
||||
if (!isset($id) || !is_int($id) || !isset($verein)){
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid Input.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($id > 0) {
|
||||
$updated = db_update($mysqli, $tableVereine, [
|
||||
'verein' => $verein,
|
||||
], ['id' => $id]);
|
||||
} else {
|
||||
$stmt = $mysqli->prepare(
|
||||
"INSERT INTO {$tableVereine}
|
||||
(verein)
|
||||
VALUES (?)"
|
||||
);
|
||||
|
||||
$stmt->bind_param(
|
||||
"s",
|
||||
$verein
|
||||
);
|
||||
|
||||
$updated = $stmt->execute();
|
||||
}
|
||||
|
||||
if ($updated !== false) {
|
||||
if ($id == 0) { // new user
|
||||
$new_id = $mysqli->insert_id;
|
||||
|
||||
echo json_encode(['success' => true, 'message' => $verein.' wurde erfolgreich erstellt.', 'id' => $new_id]);
|
||||
} else {
|
||||
echo json_encode(['success' => true, 'message' => $verein.' wurde erfolgreich aktualisiert.']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'DB Error']);
|
||||
}
|
||||
46
www/intern/scripts/logindata/ajax02.php
Normal file
46
www/intern/scripts/logindata/ajax02.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = intval($_POST['field_id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid Input.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$deleted = db_delete($mysqli, $tableInternUsers, ['id' => $id]);
|
||||
|
||||
if ($deleted !== true) {
|
||||
// DB query failed (syntax/connection issue)
|
||||
echo json_encode(['success' => false, 'message' => 'DB Error.']);
|
||||
exit;
|
||||
} else {
|
||||
// Success
|
||||
echo json_encode(['success' => true, 'message' => "Benutzer $id erfolgreich gelöscht.", 'id' => $id]);
|
||||
exit;
|
||||
}
|
||||
|
||||
36
www/intern/scripts/logindata/ajax04.php
Normal file
36
www/intern/scripts/logindata/ajax04.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
}
|
||||
|
||||
$id = intval($_POST['field_id'] ?? 0);
|
||||
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'No valid ID']);
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!db_delete($mysqli, $tableVereine, ['id' => $id])) {
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to delete verein']);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'message' => '200, ok']);
|
||||
61
www/intern/scripts/logindata/ajax05.php
Normal file
61
www/intern/scripts/logindata/ajax05.php
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/csrf_functions.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
$id = intval($_POST['user_id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'No valid ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Delete old OTL links for this user (recommended)
|
||||
db_delete($mysqli, $tableOTL, ['user_id' => $id]);
|
||||
|
||||
// Insert the row — url + timestamp are auto-generated by MySQL
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO {$tableOTL} (user_id) VALUES (?)");
|
||||
$stmt->bind_param("i", $id);
|
||||
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to create OTL record']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row_id = $stmt->insert_id;
|
||||
|
||||
$stmt->close();
|
||||
|
||||
// Now fetch the auto-generated URL
|
||||
$url = db_get_var($mysqli, "SELECT url FROM $tableOTL WHERE id = ? LIMIT 1", [$row_id]);
|
||||
|
||||
if (!$url) {
|
||||
echo json_encode(['success' => false, 'message' => 'Could not fetch generated URL']);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'url' => $url]);
|
||||
73
www/intern/scripts/rechnungen/ajax_delete_order.php
Normal file
73
www/intern/scripts/rechnungen/ajax_delete_order.php
Normal file
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
if (!isset($_POST['ids']) || !is_array($_POST['ids']) || count($_POST['ids']) < 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Keine Id angegeben']);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$ids = $_POST['ids'];
|
||||
|
||||
// Validate: all IDs must be integers
|
||||
$ids = array_filter($ids, fn($id) => ctype_digit(strval($id)));
|
||||
|
||||
if (count($ids) === 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Kein gültiger Input']);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Build placeholders for prepared statement
|
||||
$placeholders = implode(',', array_fill(0, count($ids), '?'));
|
||||
|
||||
// Prepare the SQL statement
|
||||
$sql = "DELETE FROM $tableOrders WHERE order_id IN ($placeholders)";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
if (!$stmt) {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler beim Vorbereiten der Abfrage']);
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Bind parameters dynamically
|
||||
$types = str_repeat('i', count($ids)); // all integers
|
||||
$stmt->bind_param($types, ...$ids);
|
||||
|
||||
// Execute
|
||||
if (!$stmt->execute()) {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler beim Löschen']);
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$mysqli->close();
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Bestellungen erfolgreich gelöscht']);
|
||||
http_response_code(200);
|
||||
exit;
|
||||
69
www/intern/scripts/rechnungen/ajax_update_order_status.php
Normal file
69
www/intern/scripts/rechnungen/ajax_update_order_status.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
if (!isset($_POST['scor']) || empty($_POST['scor']) || $_POST['scor'] === '') {
|
||||
echo json_encode(['success' => false, 'message' => 'Keine Referenz angegeben']);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$scorFullStr = strval($_POST['scor']);
|
||||
|
||||
$scor = intval(substr($scorFullStr, 2));
|
||||
|
||||
$stmt = $mysqli->prepare(
|
||||
"SELECT 1 FROM $tableOrders WHERE order_id = ? LIMIT 1"
|
||||
);
|
||||
$stmt->bind_param('i', $scor);
|
||||
$stmt->execute();
|
||||
$stmt->store_result();
|
||||
|
||||
if ($stmt->num_rows !== 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalide Referenz']);
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$sql = "UPDATE $tableOrders SET order_status = 2 WHERE order_id = ?";
|
||||
|
||||
$nstmt = $mysqli->prepare($sql);
|
||||
|
||||
$nstmt->bind_param('i', $scor);
|
||||
|
||||
if (!$nstmt->execute()) {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler']);
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$nstmt->close();
|
||||
$mysqli->close();
|
||||
|
||||
echo json_encode(['success' => true, 'message' => 'Rechnung wurde aktualisiert']);
|
||||
http_response_code(200);
|
||||
exit;
|
||||
@@ -0,0 +1,233 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$allGeraete = db_select($mysqli, $tableGeraete, "id, name, start_index", "", [], "start_index ASC");
|
||||
$allAbt = db_select($mysqli, $tableAbt, "name, id", "", [], "name ASC");
|
||||
|
||||
$maxTurnerinnenGruppe = 8;
|
||||
|
||||
// $allGeraete[] = ['name' => 'null', 'id' => 'null'];
|
||||
// $allAbt[] = ['name' => 'null', 'id' => 'null'];
|
||||
|
||||
/*$stmt = $mysqli->prepare("
|
||||
SELECT
|
||||
t.id,
|
||||
t.programm,
|
||||
t.verein,
|
||||
GROUP_CONCAT(ta.id SEPARATOR ', ') AS abt_table_id
|
||||
FROM $tableTurnerinnen t
|
||||
LEFT JOIN $tableTurnerinnenAbt ta ON ta.turnerin_id = t.id
|
||||
GROUP BY t.id, t.programm, t.verein
|
||||
ORDER BY t.id DESC
|
||||
");
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$allTurnerinnen = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
print_r($allTurnerinnen);*/
|
||||
|
||||
|
||||
$allTurnerinnen = db_select($mysqli, $tableTurnerinnen, "id, programm, verein, name" , "", [], "programm ASC");
|
||||
|
||||
$grouped = [];
|
||||
|
||||
foreach ($allTurnerinnen as $t) {
|
||||
$sanitasedprogramm = str_replace(['-kader'], '', strtolower($t['programm']));
|
||||
$grouped[$sanitasedprogramm][$t['verein']][] = $t;
|
||||
}
|
||||
|
||||
function getMinKey(array $array): string|int {
|
||||
return array_search(min($array), $array, true);
|
||||
}
|
||||
|
||||
function arrayRiegeneiteilung($allturnerinnen, $maxTurnerinnenGruppe, $allGeraete) {
|
||||
$indabt = 1;
|
||||
$arrayAutoRiegeneinteilung = [];
|
||||
foreach ($allturnerinnen as $prog => $vereine) {
|
||||
// ABTEILUNG BERECHNEN
|
||||
$countturterinnenprog = 0;
|
||||
foreach ($vereine as $verein => $turnerinnen) {
|
||||
foreach ($turnerinnen as $ind => $turnerin) {
|
||||
$countturterinnenprog++;
|
||||
$abt = intdiv($countturterinnenprog, $maxTurnerinnenGruppe * count($allGeraete)) + $indabt;
|
||||
$allturnerinnen[$prog][$verein][$ind]['abt'] = $abt;
|
||||
$arrayAbt[$abt][$verein][] = $turnerin;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$indabt += intdiv($countturterinnenprog - 1, $maxTurnerinnenGruppe * count($allGeraete)) + 1;
|
||||
}
|
||||
|
||||
foreach ($arrayAbt as $abt => $vereine) {
|
||||
|
||||
// AUSGLEICHEN DER GRUPPEN
|
||||
$arrayAbt = [];
|
||||
$arrayGruppen = [];
|
||||
foreach ($allGeraete as $geraet) {
|
||||
$arrayGruppen[$geraet['id']] = 0;
|
||||
}
|
||||
|
||||
$turnerinnenCount = 0;
|
||||
|
||||
foreach ($vereine as $verein => $turnerinnen) {
|
||||
$turnerinnenCount += count($turnerinnen);
|
||||
}
|
||||
|
||||
foreach ($vereine as $verein => $turnerinnen) {
|
||||
|
||||
if (count($turnerinnen) > $maxTurnerinnenGruppe || count($turnerinnen) > $turnerinnenCount / count($allGeraete)) {
|
||||
|
||||
if (count($turnerinnen) > $turnerinnenCount / count($allGeraete)) {
|
||||
$maxTurnerinnenGruppeTemp = ceil($turnerinnenCount / count($allGeraete));
|
||||
} else {
|
||||
$maxTurnerinnenGruppeTemp = $maxTurnerinnenGruppe;
|
||||
}
|
||||
// AUFTEILEN IN MEHRERE GRUPPEN
|
||||
$chunks = array_chunk($turnerinnen, $maxTurnerinnenGruppeTemp);
|
||||
foreach ($chunks as $chunk) {
|
||||
|
||||
$minKey = getMinKey($arrayGruppen);
|
||||
|
||||
$arrayGruppen[$minKey] += count($chunk);
|
||||
|
||||
foreach ($chunk as $ind =>$turnerin) {
|
||||
$arrayAutoRiegeneinteilung[$abt][$minKey][] = $turnerin;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$minKey = getMinKey($arrayGruppen);
|
||||
|
||||
$arrayGruppen[$minKey] += count($turnerinnen);
|
||||
|
||||
foreach ($turnerinnen as $ind =>$turnerin) {
|
||||
$arrayAutoRiegeneinteilung[$abt][$minKey][] = $turnerin;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
foreach ($arrayAutoRiegeneinteilung as $indAbt => $abt) {
|
||||
foreach ($abt as $indGeraet => $geraet) {
|
||||
foreach ($geraet as $indTurnerin => $turnerin) {
|
||||
$arrayAutoRiegeneinteilung[$indAbt][$indGeraet][$indTurnerin]['turnerin_index'] = $indTurnerin + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $arrayAutoRiegeneinteilung;
|
||||
}
|
||||
|
||||
$arrayAutoRiegeneinteilung = arrayRiegeneiteilung($grouped, $maxTurnerinnenGruppe, $allGeraete);
|
||||
|
||||
|
||||
|
||||
$stmt = $mysqli->prepare("DELETE FROM $tableTurnerinnenAbt");
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
$stmt = $mysqli->prepare("DELETE FROM $tableAbt");
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
|
||||
foreach ($arrayAutoRiegeneinteilung as $indAbt => $abt) {
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableAbt (name) VALUES (?)");
|
||||
$stmt->bind_param("s", $indAbt);
|
||||
$stmt->execute();
|
||||
$idAbt = $stmt->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
foreach ($abt as $indGeraet => $geraet) {
|
||||
foreach ($geraet as $indTurnerin => $turnerin) {
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableTurnerinnenAbt (turnerin_id, abteilung_id, geraet_id, turnerin_index) VALUES (?, ?, ?, ?)");
|
||||
$stmt->bind_param("ssss", $turnerin['id'], $idAbt, $indGeraet, $turnerin['turnerin_index']);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return http_response_code(201);
|
||||
|
||||
|
||||
|
||||
|
||||
/*foreach ($grouped as $ind => $g) {
|
||||
echo $ind;
|
||||
foreach ($g as $verein) {
|
||||
foreach ($verein as $turnerin) {
|
||||
echo '<div class="riegeneinteilung_turnerin_row" data-turnerin_id="' . $turnerin['id'] . '">';
|
||||
echo '<div class="riegeneinteilung_turnerin_info">';
|
||||
echo '<span class="riegeneinteilung_turnerin_name">' . htmlspecialchars($turnerin['name']) . '</span>';
|
||||
echo '<span class="riegeneinteilung_turnerin_verein">(' . htmlspecialchars($turnerin['verein']) . ')</span>';
|
||||
echo '<span class="riegeneinteilung_turnerin_verein">(' . htmlspecialchars($turnerin['abt']) . ')</span>';
|
||||
echo '<span class="riegeneinteilung_turnerin_verein">(' . htmlspecialchars($turnerin['geraet_id']) . ')</span>';
|
||||
echo '</div>';
|
||||
|
||||
echo '</div></div>';
|
||||
}
|
||||
}
|
||||
echo '<br><br>';
|
||||
}
|
||||
|
||||
foreach ($arrayAutoRiegeneinteilung as $ind => $abt) {
|
||||
|
||||
echo '<br>ABT:' . $ind;
|
||||
foreach ($abt as $g) {
|
||||
echo '<br>GERÄT';
|
||||
foreach ($g as $turnerin) {
|
||||
echo '<div class="riegeneinteilung_turnerin_row" data-turnerin_id="' . $turnerin['id'] . '">';
|
||||
echo '<div class="riegeneinteilung_turnerin_info">';
|
||||
echo '<span class="riegeneinteilung_turnerin_name">' . htmlspecialchars($turnerin['name']) . '</span>';
|
||||
echo '<span class="riegeneinteilung_turnerin_verein">(' . htmlspecialchars($turnerin['verein']) . ')</span>';
|
||||
echo '<span class="riegeneinteilung_turnerin_verein">(' . htmlspecialchars($turnerin['turnerin_index']) . ')</span>';
|
||||
echo '<span class="riegeneinteilung_turnerin_verein">(' . htmlspecialchars($turnerin['programm']) . ')</span>';
|
||||
echo '</div>';
|
||||
|
||||
echo '</div></div>';
|
||||
}
|
||||
}
|
||||
echo '<br><br>';
|
||||
}
|
||||
|
||||
print_r($arrayAutoRiegeneinteilung);*/
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validate input
|
||||
if (!isset($_POST['anz_abt']) || !ctype_digit($_POST['anz_abt'])) {
|
||||
http_response_code(406);
|
||||
exit;
|
||||
}
|
||||
|
||||
$anz_abt = (int) $_POST['anz_abt'];
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// Fetch existing Abteilungen
|
||||
$abts = db_select($mysqli, $tableAbt, '*');
|
||||
|
||||
// Delete excess Abteilungen
|
||||
foreach ($abts as $dbabt) {
|
||||
if ((int)$dbabt['name'] > $anz_abt) {
|
||||
db_delete($mysqli, $tableAbt, ['name' => $dbabt['name']]);
|
||||
}
|
||||
}
|
||||
|
||||
// Build lookup of existing names
|
||||
$existing = array_map('intval', array_column($abts, 'name'));
|
||||
|
||||
// Insert missing Abteilungen
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableAbt (name) VALUES (?)");
|
||||
|
||||
for ($i = 1; $i <= $anz_abt; $i++) {
|
||||
if (!in_array($i, $existing, true)) {
|
||||
$stmt->bind_param('i', $i);
|
||||
$stmt->execute();
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
http_response_code(201);
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
|
||||
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Validate input
|
||||
if (!isset($_POST['abt']) || !ctype_digit($_POST['abt'])) {
|
||||
http_response_code(406);
|
||||
exit;
|
||||
}
|
||||
|
||||
$abtInput = (int) $_POST['abt'];
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// Fetch existing Abteilungen ordered by name
|
||||
$abts = db_select($mysqli, $tableAbt, '*', '', [], 'name ASC');
|
||||
|
||||
$deleteId = null;
|
||||
$deleteIndex = null;
|
||||
|
||||
foreach ($abts as $ind => $abt) {
|
||||
if ((int)$abt['name'] === (int)$abtInput) {
|
||||
$deleteId = (int)$abt['id'];
|
||||
$deleteIndex = $ind;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($deleteId === null) {
|
||||
http_response_code(406);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Delete selected row
|
||||
db_delete($mysqli, $tableAbt, ['id' => $deleteId]);
|
||||
|
||||
// Reindex subsequent rows
|
||||
for ($i = $deleteIndex + 1; $i < count($abts); $i++) {
|
||||
db_update(
|
||||
$mysqli,
|
||||
$tableAbt,
|
||||
['name' => (int)$abts[$i]['name'] - 1],
|
||||
['id' => (int)$abts[$i]['id']]
|
||||
);
|
||||
}
|
||||
|
||||
http_response_code(201);
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$input = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (!$input || !isset($input['new'])) {
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$mysqli->begin_transaction();
|
||||
|
||||
try {
|
||||
$stmt = $mysqli->prepare("
|
||||
UPDATE $tableTurnerinnenAbt
|
||||
SET turnerin_index = ?
|
||||
WHERE turnerin_id = ?
|
||||
");
|
||||
|
||||
foreach (['new', 'old'] as $bucket) {
|
||||
if (empty($input[$bucket])) continue;
|
||||
|
||||
foreach ($input[$bucket] as $row) {
|
||||
$stmt->bind_param("ii", $row['order_index'], $row['id']);
|
||||
$stmt->execute();
|
||||
}
|
||||
}
|
||||
|
||||
$mysqli->commit();
|
||||
http_response_code(200);
|
||||
|
||||
} catch (Throwable $e) {
|
||||
$mysqli->rollback();
|
||||
http_response_code(500);
|
||||
}
|
||||
74
www/intern/scripts/riegeneinteilung/ajax_update_turnerin.php
Normal file
74
www/intern/scripts/riegeneinteilung/ajax_update_turnerin.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_wk_leitung']) || $_SESSION['access_granted_wk_leitung'] !== true || empty($_SESSION['passcodewk_leitung_id']) || intval($_SESSION['passcodewk_leitung_id']) < 0 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo 'Critical DB Error.';
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$turnerinId = (int)$_POST['turnerin_id'];
|
||||
$abteilung = $_POST['abteilung'];
|
||||
$geraet = $_POST['geraet'];
|
||||
|
||||
// Default to NULL if frontend sends "null"
|
||||
$abtId = null;
|
||||
$geraetId = null;
|
||||
|
||||
// Resolve Abteilung ID
|
||||
if ($abteilung !== 'null') {
|
||||
$stmt = $mysqli->prepare("SELECT id FROM $tableAbt WHERE name = ?");
|
||||
$stmt->bind_param("s", $abteilung);
|
||||
$stmt->execute();
|
||||
if ($row = $stmt->get_result()->fetch_assoc()) {
|
||||
$abtId = (int)$row['id'];
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
// Resolve Gerät ID
|
||||
if ($geraet !== 'null') {
|
||||
$stmt = $mysqli->prepare("SELECT id FROM $tableGeraete WHERE name = ?");
|
||||
$stmt->bind_param("s", $geraet);
|
||||
$stmt->execute();
|
||||
if ($row = $stmt->get_result()->fetch_assoc()) {
|
||||
$geraetId = (int)$row['id'];
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
// Upsert into turnerinnen_abt (turnerin_id is UNIQUE)
|
||||
$stmt = $mysqli->prepare("
|
||||
INSERT INTO $tableTurnerinnenAbt (turnerin_id, abteilung_id, geraet_id)
|
||||
VALUES (?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
abteilung_id = VALUES(abteilung_id),
|
||||
geraet_id = VALUES(geraet_id)
|
||||
");
|
||||
$stmt->bind_param("iii", $turnerinId, $abtId, $geraetId);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
// Return JSON
|
||||
http_response_code(200);
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'turnerin_id' => $turnerinId,
|
||||
'abteilung_id' => $abtId,
|
||||
'geraet_id' => $geraetId
|
||||
]);
|
||||
204
www/intern/scripts/sidebar/sidebar.php
Normal file
204
www/intern/scripts/sidebar/sidebar.php
Normal file
@@ -0,0 +1,204 @@
|
||||
<?php
|
||||
/**
|
||||
* Shared Sidebar Navigation
|
||||
*
|
||||
* Include this file after <body> on any intern page.
|
||||
* Set $currentPage before including, e.g.:
|
||||
* $currentPage = 'trainer';
|
||||
* require $baseDir . '/intern/scripts/sidebar/sidebar.php';
|
||||
*/
|
||||
|
||||
$isWKL = $_SESSION['access_granted_wk_leitung'] ?? false;
|
||||
$isTrainer = $_SESSION['access_granted_trainer'] ?? false;
|
||||
$isKampfrichter = $_SESSION['access_granted_kampfrichter'] ?? false;
|
||||
|
||||
if (!isset($currentPage)) $currentPage = '';
|
||||
|
||||
if (isset($_POST['abmelden'])) {
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
$_SESSION = array();
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
header("Location: " . $_SERVER['PHP_SELF']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// SVG Icons (stroke-based, 24x24 viewBox)
|
||||
$icons = [
|
||||
'trainer' => '<svg viewBox="0 0 24 24"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
|
||||
'kampfrichter' => '<svg viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>',
|
||||
'rechnungen' => '<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg>',
|
||||
'logindata' => '<svg viewBox="0 0 24 24"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>',
|
||||
'displaycontrol' => '<svg viewBox="0 0 24 24"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><line x1="8" y1="21" x2="16" y2="21"/><line x1="12" y1="17" x2="12" y2="21"/></svg>',
|
||||
'kalender' => '<svg viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/></svg>',
|
||||
'riegeneinteilung' => '<svg viewBox="0 0 24 24"><path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><rect x="8" y="2" width="8" height="4" rx="1" ry="1"/><line x1="9" y1="12" x2="15" y2="12"/><line x1="9" y1="16" x2="15" y2="16"/></svg>',
|
||||
'einstellungen' => '<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>',
|
||||
];
|
||||
|
||||
if (isset($mysqli) && isset($tableInternUsers)) {
|
||||
|
||||
if ($currentPage === 'kampfrichter' && checkIfUserHasSessionId('kampfrichter')):
|
||||
$userDispId = intval($_SESSION['passcodekampfrichter_id']);
|
||||
elseif ($currentPage === 'kampfrichter' && checkIfUserHasSessionId('trainer')):
|
||||
$userDispId = intval($_SESSION['passcodetrainer_id']);
|
||||
elseif ($isWKL && checkIfUserHasSessionId('wk_leitung')):
|
||||
$userDispId = intval($_SESSION['passcodewk_leitung_id']);
|
||||
endif;
|
||||
|
||||
$sql = "SELECT `username`, `freigabe` FROM $tableInternUsers WHERE id = ?";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
$stmt->bind_param('i', $userDispId);
|
||||
$stmt->execute();
|
||||
|
||||
$stmt->bind_result($usernameDB, $freigabenDB);
|
||||
$stmt->fetch();
|
||||
|
||||
$username = $usernameDB ?? '';
|
||||
|
||||
$decoded = json_decode($freigabenDB, true);
|
||||
$freigabenSidebar = is_array($decoded) ? $decoded : [];
|
||||
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
$links = [];
|
||||
|
||||
$renderMenu = true;
|
||||
|
||||
// Trainer & Kampfrichter are visible to their own role + WKL
|
||||
if ($isTrainer || $isWKL) {
|
||||
$links[] = ['key' => 'trainer', 'label' => 'Trainer', 'url' => '/intern/trainer', 'freigaben' => true];
|
||||
}
|
||||
if ($isKampfrichter || $isWKL) {
|
||||
$links[] = ['key' => 'kampfrichter', 'label' => 'Kampfrichter', 'url' => '/intern/kampfrichter', 'freigaben' => true];
|
||||
}
|
||||
|
||||
// WKL-only pages
|
||||
if ($isWKL) {
|
||||
$links[] = ['key' => 'rechnungen', 'label' => 'Rechnungen', 'url' => '/intern/wk-leitung/rechnungen', 'freigaben' => false];
|
||||
$links[] = ['key' => 'logindata', 'label' => 'Benutzerverwaltung', 'url' => '/intern/wk-leitung/logindata', 'freigaben' => false];
|
||||
$links[] = ['key' => 'displaycontrol', 'label' => 'Displaycontrol', 'url' => '/intern/wk-leitung/displaycontrol', 'freigaben' => false];
|
||||
//$links[] = ['key' => 'kalender', 'label' => 'Kalender', 'url' => '/intern/wk-leitung/kalender'];
|
||||
$links[] = ['key' => 'riegeneinteilung', 'label' => 'Riegeneinteilung', 'url' => '/intern/wk-leitung/riegeneinteilung', 'freigaben' => false];
|
||||
$links[] = ['key' => 'einstellungen', 'label' => 'Einstellungen', 'url' => '/intern/wk-leitung/einstellungen', 'freigaben' => false];
|
||||
}
|
||||
|
||||
function checkIfUserHasSessionId($type) : bool {
|
||||
if (isset($_SESSION['passcode'.$type.'_id']) && intval(['passcode'.$type.'_id']) > 0) { return true; }
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
function sidebarRender(string $mode) {
|
||||
global $isWKL, $isTrainer, $isKampfrichter, $links, $currentPage, $icons, $renderMenu, $username, $freigabenSidebar;
|
||||
|
||||
if (!$renderMenu) { return; }
|
||||
|
||||
if ($mode === 'button') {
|
||||
?>
|
||||
<!-- Sidebar Toggle Button -->
|
||||
<button class="sidebar-toggle" id="sidebar-toggle" aria-label="Navigation öffnen">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</button>
|
||||
<?php } elseif ($mode === 'modal') { ?>
|
||||
<!-- Sidebar Overlay -->
|
||||
<div class="sidebar-overlay" id="sidebar-overlay"></div>
|
||||
|
||||
<!-- Sidebar Panel -->
|
||||
<nav class="sidebar-nav" id="sidebar-nav">
|
||||
<div class="sidebar-header">
|
||||
<h3>Navigation</h3>
|
||||
<button class="sidebar-close-btn" id="sidebar-close" aria-label="Schliessen">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<?php if ($isWKL && ($isTrainer || $isKampfrichter || true)): ?>
|
||||
<div class="sidebar-section-label">Allgemein</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<ul class="sidebar-links">
|
||||
<?php foreach ($links as $i => $link):
|
||||
$isCurrentPage = ($currentPage === $link['key']);
|
||||
$activeClass = $isCurrentPage ? ' active' : '';
|
||||
$icon = $icons[$link['key']] ?? '';
|
||||
$freigbenArrayName = 'freigaben' . ucfirst($link['key']);
|
||||
|
||||
// Insert section divider before WKL-only links
|
||||
if ($isWKL && $link['key'] === 'rechnungen' && $i > 0): ?>
|
||||
</ul>
|
||||
<div class="sidebar-section-label">WK-Leitung</div>
|
||||
<ul class="sidebar-links">
|
||||
<?php endif; ?>
|
||||
|
||||
<li>
|
||||
<a href="<?php echo $link['url']; ?>" class="<?php echo trim($activeClass); ?>">
|
||||
<?php echo $icon; ?>
|
||||
<?php echo htmlspecialchars($link['label']); ?>
|
||||
</a>
|
||||
</li>
|
||||
<?php if ($isCurrentPage && $link['freigaben'] === true && isset($freigabenSidebar[$freigbenArrayName]) && count($freigabenSidebar[$freigbenArrayName]) > 1) : ?>
|
||||
<?php $selectedFreigabe = $_SESSION['selectedFreigabe' . ucfirst($link['key'])] ?? ''; ?>
|
||||
<li class="sidebar-li-freigaben">
|
||||
<label class="sidebar-freigaben-label" for="selectTriggerFreigabe">Freigabe</label>
|
||||
<div class="customSelect" id="selectedOption" data-value="[]">
|
||||
<button type="button" id="selectTriggerFreigabe" class="selectTrigger" aria-expanded="false">
|
||||
<span class="selectLabel"><?= $selectedFreigabe ?></span>
|
||||
<svg class="selectArrow" xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' height="14" width="14">
|
||||
<path d='M6 9L12 15L18 9' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/>
|
||||
</svg>
|
||||
</button>
|
||||
<ul class="selectOptions">
|
||||
<?php foreach ($freigabenSidebar[$freigbenArrayName] as $f) :?>
|
||||
<?php $selected = ($f === $selectedFreigabe) ? 'selected' : '' ?>
|
||||
<li data-value="<?= htmlspecialchars($f) ?>" class="<?= $selected ?>"><?= htmlspecialchars($f) ?></li>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
<input type="hidden" name="type" class="selectValue" id="freigabenSidebarSelect" value="">
|
||||
</div>
|
||||
</li>
|
||||
<?php endif; ?>
|
||||
<?php endforeach; ?>
|
||||
</ul>
|
||||
|
||||
|
||||
<?php
|
||||
if (isset($username)) : ?>
|
||||
<div class="sidebarUsername">Benutzer: <?= $username ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
|
||||
<div class="sidebar-footer">
|
||||
<form method="POST" action="" class="abmelden"><input class="abmeldenbutton" type="submit" href="?logout=1" name="abmelden" value="Abmelden"></form>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<script>
|
||||
|
||||
const siteType = '<?= $currentPage ?>';
|
||||
// Close button binding (inline to avoid race condition with sidebar.js)
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var closeBtn = document.getElementById('sidebar-close');
|
||||
if (closeBtn) {
|
||||
closeBtn.addEventListener('click', function() {
|
||||
document.getElementById('sidebar-nav').classList.remove('open');
|
||||
document.getElementById('sidebar-overlay').classList.remove('open');
|
||||
document.getElementById('sidebar-toggle').classList.remove('open');
|
||||
localStorage.setItem('intern_sidebar_open', 'false');
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<script src="/intern/js/sidebar.js"></script>
|
||||
|
||||
<?php
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
172
www/intern/scripts/trainer/ajax-add_entry_fees_to_basket.php
Normal file
172
www/intern/scripts/trainer/ajax-add_entry_fees_to_basket.php
Normal file
@@ -0,0 +1,172 @@
|
||||
<?php
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if ( empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || intval($_SESSION['passcodetrainer_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
$type = 'tr';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$ids = isset($_GET['ids']) ? htmlspecialchars(strip_tags(trim($_GET['ids'])), ENT_QUOTES) : '';
|
||||
$user = intval($_SESSION['passcodetrainer_id']);
|
||||
|
||||
|
||||
$arrayids = array_filter(array_map('trim', explode(',', $ids)));
|
||||
|
||||
if (!$arrayids || !is_array($arrayids) || count($arrayids) === 0) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($user <= 0) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$placeholders = [];
|
||||
$values = [];
|
||||
$types = '';
|
||||
|
||||
foreach ($arrayids as $id) {
|
||||
if ($id <= 0) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "SELECT bezahlt FROM $tableTurnerinnen WHERE id = ?";
|
||||
|
||||
$checkstmt = $mysqli->prepare($sql);
|
||||
$checkstmt->bind_param("i", $id);
|
||||
if (!$checkstmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$checkstmt->bind_result($bezahlt);
|
||||
|
||||
$checkstmt->fetch();
|
||||
|
||||
$checkstmt->close();
|
||||
|
||||
$sql2 = "SELECT COUNT(*) FROM $tableBasketItems WHERE user_id = ? AND item_id = ?";
|
||||
|
||||
$checkstmt2 = $mysqli->prepare($sql2); // ✔ use $sql2
|
||||
$checkstmt2->bind_param("ii", $user, $id);
|
||||
|
||||
if (!$checkstmt2->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Bind the result
|
||||
$checkstmt2->bind_result($countProd);
|
||||
$checkstmt2->fetch(); // fetch into $countProd
|
||||
|
||||
$checkstmt2->close();
|
||||
|
||||
if ((isset($bezahlt) && (intval($bezahlt) === 0 || intval($bezahlt) === 1)) && $countProd === 0) {
|
||||
$placeholders[] = '(?, ?)';
|
||||
$types .= 'ii'; // assuming user_id and item_id are integers
|
||||
$values[] = $user;
|
||||
$values[] = $id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($values === [] || $placeholders === [] || $types === '') {
|
||||
http_response_code(406);
|
||||
exit;
|
||||
}
|
||||
|
||||
$sql = "INSERT INTO `$tableBasketItems` (user_id, item_id) VALUES " . implode(',', $placeholders);
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
$stmt->bind_param($types, ...$values);
|
||||
|
||||
$success = $stmt->execute();
|
||||
|
||||
$stmt->close();
|
||||
|
||||
if (!$success) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Prepare statements once
|
||||
$sSql = "SELECT `name`, `vorname`, `programm`
|
||||
FROM $tableTurnerinnen
|
||||
WHERE id = ?";
|
||||
|
||||
$pSql = "SELECT preis
|
||||
FROM $tableProgramme
|
||||
WHERE programm = ? AND aktiv = 1";
|
||||
|
||||
$sStmt = $mysqli->prepare($sSql);
|
||||
$pStmt = $mysqli->prepare($pSql);
|
||||
|
||||
foreach ($arrayids as $id) {
|
||||
|
||||
// --- Turnerinnen ---
|
||||
$sStmt->bind_param("i", $id);
|
||||
|
||||
if (!$sStmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$row = $sStmt->get_result()->fetch_assoc();
|
||||
|
||||
if (!$row || !isset($row['programm'])) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
// --- Programme ---
|
||||
$pStmt->bind_param("s", $row['programm']);
|
||||
|
||||
if (!$pStmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pRow = $pStmt->get_result()->fetch_assoc();
|
||||
|
||||
if (!$pRow || !isset($pRow['preis'])) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
// --- Build response ---
|
||||
$arrayresponse[$id] = [
|
||||
'turnerinName' => $row['name'],
|
||||
'turnerinVorname' => $row['vorname'],
|
||||
'programm' => $row['programm'],
|
||||
'preis' => $pRow['preis']
|
||||
];
|
||||
}
|
||||
|
||||
// Close statements once
|
||||
$sStmt->close();
|
||||
$pStmt->close();
|
||||
|
||||
|
||||
http_response_code(200);
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'message' => 'Zum Warenkorb hinzugefügt',
|
||||
'arrayData' => $arrayresponse
|
||||
]);
|
||||
exit;
|
||||
0
www/intern/scripts/trainer/ajax-create_otlurl.php
Normal file
0
www/intern/scripts/trainer/ajax-create_otlurl.php
Normal file
46
www/intern/scripts/trainer/ajax-fetch_temp_order.php
Normal file
46
www/intern/scripts/trainer/ajax-fetch_temp_order.php
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || intval($_SESSION['passcodetrainer_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
$userId = $_SESSION['passcodetrainer_id'];
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
$type = 'tr';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// --- Check for existing open order ---
|
||||
$sql = "SELECT * FROM `$tableOrders` WHERE user_id = ? AND order_status = 0 LIMIT 1";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("i", $userId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$result = $result->fetch_assoc();
|
||||
$stmt->close();
|
||||
|
||||
if ($result) {
|
||||
$_SESSION['order_id'] = $result['order_id'];
|
||||
$_SESSION['order_preis'] = $result['preis'];
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true, 'result' => $result]);
|
||||
exit;
|
||||
?>
|
||||
149
www/intern/scripts/trainer/ajax-neu_temp_order.php
Normal file
149
www/intern/scripts/trainer/ajax-neu_temp_order.php
Normal file
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
$token = isset($_GET['token']) ? $_GET['token'] : '';
|
||||
|
||||
/*if ($token !== 'OOlhSGI8CraW6BFmJbj6JFy4sxrYyZ0UxzzbASLhY1sWm0IgqmBXjqqwtqKSvpVFBSBgOFrXHuQLGQj1pxlxj3rlTt1r7kAAWX67dcP'){
|
||||
echo json_encode(['success' => false, 'message' => '500 Error - Critical Server Error']);
|
||||
exit;
|
||||
}*/
|
||||
|
||||
if (empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || intval($_SESSION['passcodetrainer_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
function generateInvoiceNumber(): int {
|
||||
return random_int(10000000, 99999999);
|
||||
}
|
||||
|
||||
$orderType = 'Startgebühr';
|
||||
|
||||
function createInvoice(mysqli $conn, $tableOrders, $orderType , $preis, $userId, $jsonIds, $order_status): int
|
||||
{
|
||||
$maxRetries = 5;
|
||||
|
||||
for ($i = 0; $i < $maxRetries; $i++) {
|
||||
|
||||
$invoiceNumber = generateInvoiceNumber();
|
||||
|
||||
|
||||
$stmt = $conn->prepare(
|
||||
"INSERT INTO `$tableOrders` (order_id, order_type, preis, user_id, item_ids, order_status)
|
||||
VALUES (?, ?, ?, ?, ?, ?)"
|
||||
);
|
||||
|
||||
$stmt->bind_param(
|
||||
"isdisi",
|
||||
$invoiceNumber, $orderType, $preis, $userId, $jsonIds, $order_status
|
||||
);
|
||||
|
||||
if ($stmt->execute()) {
|
||||
return $invoiceNumber; // SUCCESS
|
||||
}
|
||||
|
||||
// Duplicate key error → retry
|
||||
if ($conn->errno !== 1062) {
|
||||
throw new RuntimeException(
|
||||
"Database error ({$conn->errno}): {$conn->error}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
throw new RuntimeException('Failed to generate unique invoice number');
|
||||
}
|
||||
|
||||
$userId = $_SESSION['passcodetrainer_id'];
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
$type = 'tr';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$sql = "SELECT bi.id AS basket_id, bi.item_id, p.programm AS programm_name, p.preis, bi.id
|
||||
FROM $tableBasketItems bi
|
||||
LEFT JOIN $tableTurnerinnen t ON bi.item_id = t.id
|
||||
LEFT JOIN $tableProgramme p ON p.programm = t.programm
|
||||
WHERE bi.user_id = ?";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("i", $userId);
|
||||
$stmt->execute();
|
||||
$result = $stmt->get_result();
|
||||
$rows = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
if (!$rows || count($rows) < 1) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$preis = 0;
|
||||
|
||||
foreach ($rows as $r) {
|
||||
$preis += floatval($r['preis']);
|
||||
$ids[] = strval($r['item_id']);
|
||||
}
|
||||
|
||||
if ($preis < 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Negative price']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$jsonIds = json_encode($ids);
|
||||
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid JSON']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// --- Check for existing open order ---
|
||||
$sql = "SELECT order_id FROM `$tableOrders` WHERE user_id = ? AND order_status = 0 LIMIT 1";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("i", $userId);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($order_id);
|
||||
|
||||
if ($stmt->fetch()) {
|
||||
// --- UPDATE existing order ---
|
||||
$stmt->close();
|
||||
|
||||
$sql = "
|
||||
UPDATE `$tableOrders`
|
||||
SET preis = ?, item_ids = ?
|
||||
WHERE order_id = ?
|
||||
";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("dsi", $preis, $jsonIds, $order_id);
|
||||
$stmt->execute();
|
||||
|
||||
$_SESSION['order_id'] = $order_id;
|
||||
$_SESSION['order_preis'] = $preis;
|
||||
} else {
|
||||
// --- INSERT new order ---
|
||||
$stmt->close();
|
||||
|
||||
$order_status = 0;
|
||||
|
||||
$new_id = createInvoice($mysqli, $tableOrders, $orderType, $preis, $userId, $jsonIds, $order_status);
|
||||
$_SESSION['order_id'] = $new_id;
|
||||
$_SESSION['order_preis'] = $preis;
|
||||
}
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
exit;
|
||||
?>
|
||||
47
www/intern/scripts/trainer/ajax-remove_basket_item.php
Normal file
47
www/intern/scripts/trainer/ajax-remove_basket_item.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if ( empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || intval($_SESSION['passcodetrainer_id']) < 1 ) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
$type = 'tr';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
// --- Get input ---
|
||||
$id = isset($_POST['id']) ? intval($_POST['id']) : 0;
|
||||
$userId = intval($_SESSION['passcodetrainer_id']);
|
||||
|
||||
// --- Validate inputs ---
|
||||
if ($id < 1) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
// --- Check for existing open order ---
|
||||
$sql = "DELETE FROM $tableBasketItems WHERE user_id = ? AND item_id = ?";
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("ii", $userId, $id);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
http_response_code(200);
|
||||
exit;
|
||||
?>
|
||||
83
www/intern/scripts/trainer/ajax_link_bodenmusik.php
Normal file
83
www/intern/scripts/trainer/ajax_link_bodenmusik.php
Normal file
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
$isTrainer =
|
||||
isset($_SESSION['access_granted_trainer'], $_SESSION['passcodetrainer_id']) &&
|
||||
$_SESSION['access_granted_trainer'] === true &&
|
||||
(int)$_SESSION['passcodetrainer_id'] > 0;
|
||||
|
||||
if (!$isTrainer) {
|
||||
echo json_encode(['success' => false]);
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_POST['musicId']) || !isset($_POST['turnerinId']) || intval($_POST['musicId']) < 1 || intval($_POST['turnerinId']) < 1) {
|
||||
echo json_encode(['success' => false]);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
$type = 'tr';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$musicId = intval($_POST['musicId']);
|
||||
$turnerinId = intval($_POST['turnerinId']);
|
||||
|
||||
$sql = "UPDATE $tableTurnerinnen SET bodenmusik = ? WHERE id = ?";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("ss", $musicId, $turnerinId);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$sql = "SELECT name, vorname FROM $tableTurnerinnen WHERE id = ?";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("s", $turnerinId);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$rows = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$_SESSION['form_message_type'] = 1;
|
||||
|
||||
if (!isset($rows) || !is_array($rows) || count($rows) !== 1) {
|
||||
$_SESSION['form_message'] = 'Musik aktualisiert';
|
||||
} else {
|
||||
$_SESSION['form_message'] = 'Musik für '.$rows[0]['name'].' '.$rows[0]['vorname'].' aktualisiert';
|
||||
}
|
||||
|
||||
$mysqli->close();
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
59
www/intern/scripts/trainer/ajax_unlink_delete_bodenmusik.php
Normal file
59
www/intern/scripts/trainer/ajax_unlink_delete_bodenmusik.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
$isTrainer =
|
||||
isset($_SESSION['access_granted_trainer'], $_SESSION['passcodetrainer_id']) &&
|
||||
$_SESSION['access_granted_trainer'] === true &&
|
||||
(int)$_SESSION['passcodetrainer_id'] > 0;
|
||||
|
||||
if (!$isTrainer) {
|
||||
echo json_encode(['success' => false]);
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_POST['oldMusicId'])) {
|
||||
echo json_encode(['success' => false]);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$oldMusicId = intval($_POST['oldMusicId']);
|
||||
|
||||
if ($oldMusicId < 1) {
|
||||
echo json_encode(['success' => true]);
|
||||
http_response_code(202);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
$type = 'tr';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$sql = "DELETE $tableAudiofiles WHERE id = ?";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("i", $oldMusicId);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
$mysqli->close();
|
||||
|
||||
echo json_encode(['success' => true]);
|
||||
http_response_code(200);
|
||||
exit;
|
||||
122
www/intern/scripts/trainer/rechnung/ajax-neu_qr_rechnung.php
Normal file
122
www/intern/scripts/trainer/rechnung/ajax-neu_qr_rechnung.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || $_SESSION['passcodetrainer_id'] < 1) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_POST['preis']) || !isset($_POST['name']) || !isset($_POST['vorname']) || !isset($_POST['strasse']) || !isset($_POST['plz']) || !isset($_POST['ort']) || !isset($_POST['hausnummer'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid input']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require $baseDir . '/../composer/vendor/autoload.php';
|
||||
|
||||
use Sprain\SwissQrBill as QrBill;
|
||||
|
||||
|
||||
// This is an example how to create a typical qr bill:
|
||||
// - with reference number
|
||||
// - with known debtor
|
||||
// - with specified amount
|
||||
// - with human-readable additional information
|
||||
// - using your QR-IBAN
|
||||
//
|
||||
// Likely the most common use-case in the business world.
|
||||
|
||||
// Create a new instance of QrBill, containing default headers with fixed values
|
||||
$qrBill = QrBill\QrBill::create();
|
||||
|
||||
$name = trim((string)($rechnungenVorname ?? '') . ' ' . (string)($rechnungenName ?? ''));
|
||||
$strasse = (string)($rechnungenStrasse ?? '');
|
||||
$hausnr = (string)($rechnungenHausnummer ?? '');
|
||||
$plz = (string)($rechnungenPostleitzahl ?? '');
|
||||
$ort = (string)($rechnungenOrt ?? '');
|
||||
|
||||
$qrBill->setCreditor(
|
||||
QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
|
||||
$name,
|
||||
$strasse,
|
||||
$hausnr,
|
||||
$plz,
|
||||
$ort,
|
||||
'CH'
|
||||
)
|
||||
);
|
||||
|
||||
$iban = strtoupper(str_replace(' ', '', (string)($rechnungenIBAN ?? '')));
|
||||
|
||||
$qrBill->setCreditorInformation(
|
||||
QrBill\DataGroup\Element\CreditorInformation::create($iban)
|
||||
);
|
||||
|
||||
// Add debtor information
|
||||
// Who has to pay the invoice? This part is optional.
|
||||
$qrBill->setUltimateDebtor(
|
||||
QrBill\DataGroup\Element\StructuredAddress::createWithStreet(
|
||||
$_POST['vorname'] . ' ' . $_POST['name'],
|
||||
$_POST['strasse'],
|
||||
$_POST['hausnummer'],
|
||||
$_POST['plz'],
|
||||
$_POST['ort'],
|
||||
'CH'
|
||||
)
|
||||
);
|
||||
|
||||
// Add payment amount information
|
||||
// What amount is to be paid?
|
||||
$qrBill->setPaymentAmountInformation(
|
||||
QrBill\DataGroup\Element\PaymentAmountInformation::create(
|
||||
'CHF',
|
||||
$totalPreis
|
||||
)
|
||||
);
|
||||
|
||||
// Add payment reference
|
||||
// This is what you will need to identify incoming payments.
|
||||
$qrBill->setPaymentReference(
|
||||
QrBill\DataGroup\Element\PaymentReference::create(
|
||||
QrBill\DataGroup\Element\PaymentReference::TYPE_SCOR,
|
||||
QrBill\Reference\RfCreditorReferenceGenerator::generate($dbresult['order_id'])
|
||||
)
|
||||
);
|
||||
|
||||
$month = date('m');
|
||||
|
||||
if ($month < 6){
|
||||
$jahr = date('Y');
|
||||
} else {
|
||||
$jahr = date('Y') + 1;
|
||||
}
|
||||
|
||||
$referenz = "Startgebühren ". $wkName. " ".$jahr;
|
||||
|
||||
// Optionally, add some human-readable information about what the bill is for.
|
||||
$qrBill->setAdditionalInformation(
|
||||
QrBill\DataGroup\Element\AdditionalInformation::create(
|
||||
$referenz
|
||||
)
|
||||
);
|
||||
|
||||
// Now get the QR code image and save it as a file.
|
||||
/*try {
|
||||
$qrBill->getQrCode()->writeFile(__DIR__ . '/qrneu.png');
|
||||
$qrBill->getQrCode()->writeFile(__DIR__ . '/qrneu.svg');
|
||||
} catch (\Throwable $e) {
|
||||
foreach ($qrBill->getViolations() as $violation) {
|
||||
print $violation->getMessage()."\n";
|
||||
}
|
||||
// Also print exception message when available
|
||||
error_log('QR bill error: ' . $e->getMessage());
|
||||
exit;
|
||||
}*/
|
||||
|
||||
// Next: Output full payment parts, depending on the format you want to use:
|
||||
//
|
||||
// - FpdfOutput/fpdf-example.php
|
||||
// - HtmlOutput/html-example.php
|
||||
// - TcPdfOutput/tcpdf-example.php
|
||||
424
www/intern/scripts/trainer/rechnung/rechnung-pdf.php
Normal file
424
www/intern/scripts/trainer/rechnung/rechnung-pdf.php
Normal file
@@ -0,0 +1,424 @@
|
||||
<?php
|
||||
|
||||
use Sprain\SwissQrBill\PaymentPart\Output\DisplayOptions;
|
||||
use Sprain\SwissQrBill\PaymentPart\Output\TcPdfOutput\TcPdfOutput;
|
||||
use TCPDF;
|
||||
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require $baseDir . '/../composer/vendor/autoload.php';
|
||||
|
||||
ini_set('display_errors', 1);
|
||||
ini_set('display_startup_errors', 1);
|
||||
// Show all errors except deprecation notices (these come from vendor libraries
|
||||
// that aren't yet typed for newer PHP versions). Long-term fix: update
|
||||
// dependencies to versions compatible with your PHP runtime.
|
||||
error_reporting(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
|
||||
// Add a higher memory limit
|
||||
ini_set('memory_limit', '256M'); // Start with 256M, increase if needed
|
||||
|
||||
session_start();
|
||||
|
||||
|
||||
if (empty($_SESSION['access_granted_trainer']) || $_SESSION['access_granted_trainer'] !== true || empty($_SESSION['passcodetrainer_id']) || $_SESSION['passcodetrainer_id'] < 1) {
|
||||
http_response_code(403);
|
||||
header("Location: /intern/trainer");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_SESSION['order_id']) || !isset($_SESSION['order_preis'])) {
|
||||
http_response_code(403);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($_POST['order_id']) || !isset($_POST['preis']) || !isset($_POST['name']) || !isset($_POST['vorname']) || !isset($_POST['strasse']) || !isset($_POST['plz']) || !isset($_POST['ort'])) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (intval($_SESSION['order_id']) !== intval($_POST['order_id']) || intval($_SESSION['order_preis']) !== intval($_POST['preis'])) {
|
||||
http_response_code(401);
|
||||
exit;
|
||||
}
|
||||
|
||||
$type = 'tr';
|
||||
|
||||
$data = include $baseDir. '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
require $baseDir. '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
|
||||
$dbresult = db_select($mysqli, $tableOrders, '*', 'order_id = ?', [$_POST['order_id']]);
|
||||
|
||||
if ($dbresult === false || count($dbresult) === 0) {
|
||||
echo json_encode(['success' => false, 'message' => 'Order not found']);
|
||||
exit;
|
||||
} elseif (count($dbresult) > 1) {
|
||||
echo json_encode(['success' => false, 'message' => 'Error: Multiple orders found with the same ID']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$wkName = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['wkName']);
|
||||
|
||||
$rechnungenName = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenName']);
|
||||
$rechnungenVorname = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenVorname']);
|
||||
$rechnungenStrasse = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenStrasse']);
|
||||
$rechnungenHausnummer = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenHausnummer']);
|
||||
$rechnungenPostleitzahl = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenPostleitzahl']);
|
||||
$rechnungenOrt = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenOrt']);
|
||||
$rechnungenIBAN = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['rechnungenIBAN']);
|
||||
$linkWebseite = db_get_var($mysqli, "SELECT `value` FROM $tableVar WHERE `name` = ?", ['linkWebseite']);
|
||||
|
||||
|
||||
$dbresult = $dbresult[0];
|
||||
|
||||
|
||||
$orderStatus = (floatval($_SESSION['order_preis']) === 0.0 && !isset($_POST['postversand'])) ? 2 : 1 ;
|
||||
|
||||
$orderId = intval($_POST['order_id']);
|
||||
|
||||
|
||||
$current_year = date('Y');
|
||||
$monat = date('n');
|
||||
if ($monat > 6) $current_year++;
|
||||
|
||||
|
||||
|
||||
class MYPDF extends TCPDF
|
||||
{
|
||||
public $columns;
|
||||
public $headerBottomY = 0;
|
||||
public $firstPageDone = false; // track first page
|
||||
public $printfooter;
|
||||
|
||||
public function Header()
|
||||
{
|
||||
// Logo always
|
||||
$image_file = $_SERVER['DOCUMENT_ROOT'] . '/intern/img/logo-normal.png';
|
||||
$this->Image($image_file, 180, 15, 15);
|
||||
|
||||
// Table header only for subsequent pages
|
||||
if ($this->firstPageDone && !empty($this->columns)) {
|
||||
// Use same top margin as table
|
||||
$this->SetY(35); // or another fixed Y
|
||||
$this->SetX(15);
|
||||
$this->SetFont('GoogleSansFlex-Regular', '', 11);
|
||||
$this->setCellPaddings(2, 0, 2, 0);
|
||||
foreach ($this->columns as $c) {
|
||||
$this->Cell($c['max_width'], 10, $c['header'], 0, 0, 'L');
|
||||
}
|
||||
$this->Ln();
|
||||
$this->headerBottomY = $this->GetY();
|
||||
$this->SetLineWidth(0.6);
|
||||
$this->Line(15, $this->GetY(), 210 - 15, $this->GetY());
|
||||
$this->SetLineWidth(0.2);
|
||||
}
|
||||
}
|
||||
|
||||
public function Footer()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// --- Create PDF ---
|
||||
$pdf = new MYPDF('P', 'mm', 'A4', true, 'UTF-8', false);
|
||||
$pdf->current_year = (date('n') > 6) ? date('Y') + 1 : date('Y');
|
||||
$pdf->wkp_name = $rechnungenVorname . ' ' . $rechnungenName;
|
||||
$pdf->wkp_adresse = $rechnungenStrasse . ' ' . $rechnungenHausnummer;
|
||||
$pdf->wkp_plz_ort = $rechnungenPostleitzahl . ' ' . $rechnungenOrt;
|
||||
$pdf->wkp_url = $linkWebseite;
|
||||
$pdf->wk_name = $wkName;
|
||||
$pdf->pers_name = $_POST['vorname'] . ' ' . $_POST['name'];
|
||||
$pdf->pers_adresse = $_POST['strasse'] . ' ' . $_POST['hausnummer'];
|
||||
$pdf->pers_plz_ort = $_POST['plz'] . ' ' . $_POST['ort'];
|
||||
$pdf->printfooter = true;
|
||||
|
||||
// Mark first page done so Header() prints table headers on subsequent pages
|
||||
$pdf->firstPageDone = false;
|
||||
|
||||
$pdf->setCellPaddings(2, 0, 2, 0);
|
||||
|
||||
$pdf->SetMargins(15, 35, 15);
|
||||
|
||||
// Fonts
|
||||
$pdf->AddFont('GoogleSansFlex9pt-Bold', '', $_SERVER['DOCUMENT_ROOT'] . '/../private-files/tcpdf-fonts/googlesansflex_9ptb.php');
|
||||
$pdf->AddFont('GoogleSansFlex-Regular', '', $_SERVER['DOCUMENT_ROOT'] . '/../private-files/tcpdf-fonts/gsf.php');
|
||||
|
||||
$pdf->SetCreator(PDF_CREATOR);
|
||||
$pdf->SetAuthor('WKVS');
|
||||
$pdf->SetAutoPageBreak(TRUE, 10);
|
||||
|
||||
$pdf->SetFont('GoogleSansFlex-Regular', '', 11);
|
||||
|
||||
// --- Add a page ---
|
||||
$pdf->AddPage();
|
||||
|
||||
// --- Sender block (left) ---
|
||||
$pdf->SetX(15);
|
||||
$pdf->Cell(0, 0, $pdf->wkp_name, 0, 1);
|
||||
$pdf->Cell(0, 0, $pdf->wkp_adresse, 0, 1);
|
||||
$pdf->Cell(0, 0, $pdf->wkp_plz_ort, 0, 1);
|
||||
$pdf->Ln(7);
|
||||
$pdf->Cell(0, 0, $pdf->wkp_url, 0, 1);
|
||||
|
||||
// --- Recipient block (right / window) ---
|
||||
$x = 110; // X coordinate for right window
|
||||
$y = 50; // Y coordinate
|
||||
$w = 80; // Width of recipient block
|
||||
|
||||
$address = implode("\n", [
|
||||
$pdf->pers_name,
|
||||
$pdf->pers_adresse,
|
||||
$pdf->pers_plz_ort
|
||||
]);
|
||||
|
||||
$pdf->MultiCell($w, 5, $address, 0, 'L', false, 1, $x, $y, true);
|
||||
|
||||
date_default_timezone_set('UTC');
|
||||
|
||||
// --- Invoice title ---
|
||||
$pdf->Ln(20); // space below recipient
|
||||
$pdf->SetFont('GoogleSansFlex9pt-Bold', '', 15);
|
||||
$pdf->Cell(0, 10, 'Startgebührenrechnung ' . $pdf->wk_name . ' ' . $pdf->current_year, 0, 1, 'L');
|
||||
$pdf->SetFont('GoogleSansFlex-Regular', '', 10);
|
||||
$pdf->Cell(0, 9, "Rechnungsnummer: " . $orderId, 0, 1, 'L');
|
||||
$pdf->SetFont('GoogleSansFlex-Regular', '', 7);
|
||||
$pdf->Cell(0, 0, "Ausstellungsdatum: " . date("d.m.y"), 0, 1, 'L');
|
||||
|
||||
$pdf->Ln(10); // space below title
|
||||
|
||||
$pdf->SetFont('GoogleSansFlex9pt-Bold', '', 13);
|
||||
|
||||
//$turnerinnnenIds = [];
|
||||
|
||||
|
||||
$turnerinnnenIds = explode(',', str_replace(['[', ']','"'], '', $dbresult['item_ids']));
|
||||
|
||||
$columns = ['name' => ['header' => 'Name'],
|
||||
'programm' => ['header' => 'Programm'],
|
||||
'verein' => ['header' => 'Verein'],
|
||||
'preis' => ['header' => 'Startgebühr']];
|
||||
|
||||
foreach ($columns as $key => $column){
|
||||
$columns[$key]['max_width'] = $pdf->GetStringWidth($column['header']);
|
||||
}
|
||||
|
||||
$totalPreis = 0.00;
|
||||
|
||||
$dbdata = [];
|
||||
|
||||
foreach ($turnerinnnenIds as $singleid){
|
||||
$newdbresult = db_select($mysqli, $tableTurnerinnen, 'name, vorname, programm, verein', 'id = ?', [$singleid]);
|
||||
if ($newdbresult && count($newdbresult) === 1){
|
||||
$dbdata[$singleid] = $newdbresult;
|
||||
$pdf->SetFont('', '', 10);
|
||||
$text = 'Startgebühr '.$newdbresult[0]['name'].' '.$newdbresult[0]['vorname'];
|
||||
|
||||
if ($pdf->GetStringWidth($text) > $columns['name']['max_width'] ?? 0){
|
||||
$columns['name']['max_width'] = $pdf->GetStringWidth($text);
|
||||
}
|
||||
if ($pdf->GetStringWidth($newdbresult[0]['programm']) > $columns['programm']['max_width'] ?? 0){
|
||||
$columns['programm']['max_width'] = $pdf->GetStringWidth($newdbresult[0]['programm']);
|
||||
}
|
||||
if ($pdf->GetStringWidth($newdbresult[0]['verein']) > $columns['verein']['max_width'] ?? 0){
|
||||
$columns['verein']['max_width'] = $pdf->GetStringWidth($newdbresult[0]['verein']);
|
||||
}
|
||||
|
||||
if (isset($newdbresult[0]['programm'])){
|
||||
$dbpreis = db_select($mysqli, $tableProgramme, 'preis', 'programm = ?', [$newdbresult[0]['programm']]);
|
||||
|
||||
if ($newdbresult && count($newdbresult) === 1 && isset($dbpreis[0]['preis'])){
|
||||
$preis = $dbpreis[0]['preis'];
|
||||
$totalPreis += floatval($dbpreis[0]['preis']);
|
||||
} else {
|
||||
$preis = 'ERROR';
|
||||
}
|
||||
|
||||
if ($pdf->GetStringWidth('CHF '.$preis) > $columns['preis']['max_width'] ?? 0){
|
||||
$columns['preis']['max_width'] = $pdf->GetStringWidth('CHF '.$preis);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($columns as $key => $column){
|
||||
$columns[$key]['max_width'] += 2; // Add some padding
|
||||
}
|
||||
|
||||
$maxWidth = 210 - 30; // A4 width minus margins
|
||||
$totalColumnWidth = 0;
|
||||
foreach ($columns as $column){
|
||||
$totalColumnWidth += $column['max_width'];
|
||||
}
|
||||
|
||||
if ($totalColumnWidth < $maxWidth){
|
||||
$scalingFactor = $maxWidth / $totalColumnWidth;
|
||||
foreach ($columns as $key => $column){
|
||||
$columns[$key]['max_width'] = $column['max_width'] * $scalingFactor;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($columns as $c) {
|
||||
$pdf->Cell($c['max_width'], 10, $c['header'], 0, 0, 'L');
|
||||
}
|
||||
$pdf->Ln();
|
||||
|
||||
$pdf->SetLineWidth(0.6);
|
||||
$pdf->Line(15, $pdf->GetY(), 210 - 15, $pdf->GetY());
|
||||
$pdf->SetLineWidth(0.2);
|
||||
|
||||
$pdf->headerBottomY = $pdf->GetY();
|
||||
|
||||
// --- Set top margin for table below title ---
|
||||
|
||||
// Mark first page done so Header() prints table headers on subsequent pages
|
||||
$pdf->firstPageDone = true;
|
||||
|
||||
$pdf->SetFont('GoogleSansFlex-Regular', '', 11);
|
||||
|
||||
$pdf->columns = $columns;
|
||||
|
||||
$margin_top = $pdf->headerBottomY;
|
||||
|
||||
$pdf->SetMargins(15, 45, 15); // +5 mm padding below header
|
||||
$pdf->SetY($margin_top); // Move cursor below header manually
|
||||
|
||||
foreach ($dbdata as $singleid => $newdbresult){
|
||||
$pdf->SetFont('', '', 10);
|
||||
|
||||
$text = 'Startgebühr '.$newdbresult[0]['name'].' '.$newdbresult[0]['vorname'];
|
||||
$pdf->Cell($columns['name']['max_width'], 10, $text, 0, 0, 'L');
|
||||
$pdf->Cell($columns['programm']['max_width'], 10, $newdbresult[0]['programm'], 0, 0, 'L');
|
||||
$pdf->Cell($columns['verein']['max_width'], 10, $newdbresult[0]['verein'], 0, 0, 'L');
|
||||
|
||||
$pdf->SetFillColor(100, 100, 100);
|
||||
|
||||
if (isset($newdbresult[0]['programm'])){
|
||||
$dbpreis = db_select($mysqli, $tableProgramme, 'preis', 'programm = ?', [$newdbresult[0]['programm']]);
|
||||
|
||||
if ($newdbresult && count($newdbresult) === 1 && isset($dbpreis[0]['preis'])){
|
||||
$preis = $dbpreis[0]['preis'];
|
||||
} else {
|
||||
$preis = 'ERROR';
|
||||
}
|
||||
$pdf->Cell($columns['preis']['max_width'], 10, 'CHF ' . $preis, 0, 1, 'C');
|
||||
}
|
||||
$pdf->SetDrawColor(100, 100, 100);
|
||||
$pdf->Line(15, $pdf->getY(), 210 - 15, $pdf->getY());
|
||||
$pdf->SetDrawColor(0, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
if (isset($_POST['postversand'])) {
|
||||
$pdf->SetFont('', '', 10);
|
||||
|
||||
$text = 'Postversand der Rechnung durch WKVS';
|
||||
$pdf->Cell($columns['name']['max_width'], 10, $text, 0, 0, 'L');
|
||||
$pdf->Cell($columns['programm']['max_width'], 10, '', 0, 0, 'L');
|
||||
$pdf->Cell($columns['verein']['max_width'], 10, '', 0, 0, 'L');
|
||||
|
||||
$pdf->SetFillColor(100, 100, 100);
|
||||
|
||||
$pdf->Cell($columns['preis']['max_width'], 10, 'CHF 2.50', 0, 1, 'C');
|
||||
|
||||
$pdf->SetDrawColor(100, 100, 100);
|
||||
$pdf->Line(15, $pdf->getY(), 210 - 15, $pdf->getY());
|
||||
$pdf->SetDrawColor(0, 0, 0);
|
||||
|
||||
$totalPreis += 2.5;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if ($totalPreis !== 0) {
|
||||
require __DIR__ . '/ajax-neu_qr_rechnung.php';
|
||||
}
|
||||
|
||||
$pdf->Ln(3);
|
||||
$pdf->SetFont('GoogleSansFlex9pt-Bold', '', 10);
|
||||
$pdf->Cell(100, 10, "Gesamt:", 0, 0, 'L');
|
||||
$pdf->SetX($columns['name']['max_width'] + $columns['programm']['max_width'] + $columns['verein']['max_width'] + 15);
|
||||
$pdf->Cell($columns['preis']['max_width'], 10, 'CHF ' . number_format($totalPreis, 2), 0, 1, 'C');
|
||||
$pdf->SetFont('GoogleSansFlex-Regular', '', 10);
|
||||
|
||||
if ($totalPreis !== 0) {
|
||||
$pdf->Ln(10);
|
||||
$pdf->SetTextColor(90, 103, 39);
|
||||
$pdf->MultiCell(0, 8, 'Diese Rechnung wurde als bezahlt eigetragen, da der Betrag 0 CHF beträgt', 0, 'L');
|
||||
$pdf->SetTextColor(0, 0, 0);
|
||||
} else {
|
||||
|
||||
// 3. Create a full payment part for TcPDF
|
||||
$output = new TcPdfOutput($qrBill, 'de', $pdf);
|
||||
|
||||
// 4. Optional, set layout options
|
||||
if (class_exists(\Sprain\SwissQrBill\PaymentPart\Output\DisplayOptions::class)) {
|
||||
$displayOptions = new \Sprain\SwissQrBill\PaymentPart\Output\DisplayOptions();
|
||||
$displayOptions
|
||||
->setPrintable(false) // true to remove lines for printing on a perforated stationery
|
||||
->setDisplayTextDownArrows(false) // true to show arrows next to separation text, if shown
|
||||
->setDisplayScissors(false) // true to show scissors instead of separation text
|
||||
->setPositionScissorsAtBottom(false) // true to place scissors at the bottom, if shown
|
||||
;
|
||||
|
||||
// 5. Generate the output, applying display options when supported
|
||||
if (method_exists($output, 'setDisplayOptions')) {
|
||||
$output->setDisplayOptions($displayOptions);
|
||||
}
|
||||
} else {
|
||||
// DisplayOptions class is not available in the installed package version.
|
||||
// We proceed without custom display options.
|
||||
}
|
||||
|
||||
// Generate the payment part (always call)
|
||||
|
||||
if ($pdf->getY() > 297 - 120) {
|
||||
$pdf->firstPageDone = false;
|
||||
$pdf->printfooter = false;
|
||||
$pdf->addPage();
|
||||
}
|
||||
$output->getPaymentPart();
|
||||
}
|
||||
|
||||
|
||||
if (isset($_SESSION['order_id'])) unset($_SESSION['order_id']);
|
||||
if (isset($_SESSION['order_preis'])) unset($_SESSION['order_preis']);
|
||||
|
||||
$filename = 'Rechnung Startgebuehren '.$wkName.' '.$current_year.' '.date('YmdHis').'.pdf';
|
||||
|
||||
$pdf->SetTitle($filename);
|
||||
|
||||
$savePath = $baseDir . '/../private-files/rechnungen/' . $orderId . '.pdf';
|
||||
|
||||
// Save PDF to disk
|
||||
$pdf->Output($savePath, 'F');
|
||||
|
||||
$sql = "UPDATE $tableOrders SET order_status = ? WHERE order_id = ?";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
$stmt->bind_param("ii", $orderStatus, $orderId);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
// 2. DELETE basket items
|
||||
db_delete($mysqli, $tableBasketItems, ['user_id' => intval($_SESSION['passcodetrainer_id'])]);
|
||||
|
||||
$mysqli->close();
|
||||
|
||||
// Send headers manually
|
||||
header('Content-Type: application/pdf');
|
||||
header('Content-Disposition: attachment; filename="' . $dirFileName . '"');
|
||||
header('Content-Length: ' . filesize($savePath));
|
||||
|
||||
// Send file contents
|
||||
readfile($savePath);
|
||||
exit;
|
||||
13
www/intern/scripts/wkvs/script.js
Normal file
13
www/intern/scripts/wkvs/script.js
Normal file
@@ -0,0 +1,13 @@
|
||||
const texts = document.querySelectorAll('.textWelcomeScreen');
|
||||
|
||||
texts.forEach(text => {
|
||||
const characters = text.textContent.split('');
|
||||
text.textContent = '';
|
||||
|
||||
characters.forEach((char, index) => {
|
||||
const span = document.createElement('span');
|
||||
span.textContent = char;
|
||||
span.style.animationDelay = `${index * 0.1}s`;
|
||||
text.appendChild(span);
|
||||
});
|
||||
});
|
||||
24
www/intern/scripts/wkvs/wkvs.html
Normal file
24
www/intern/scripts/wkvs/wkvs.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<link rel="stylesheet" href="/intern/css/wkvs.css">
|
||||
|
||||
<div class="welcomeScreen">
|
||||
<div class="innerWelcomeScreen">
|
||||
<p class="textWelcomeScreen title">WKVS</p>
|
||||
<p class="textWelcomeScreen text">Kunstturnen</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const texts = document.querySelectorAll('.textWelcomeScreen');
|
||||
|
||||
texts.forEach(text => {
|
||||
const characters = text.textContent.split('');
|
||||
text.textContent = '';
|
||||
|
||||
characters.forEach((char, index) => {
|
||||
const span = document.createElement('span');
|
||||
span.textContent = char;
|
||||
span.style.animationDelay = `${index * 0.1}s`;
|
||||
text.appendChild(span);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Reference in New Issue
Block a user