Semi-stable version with old variable names
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
<?php
|
||||
function generateIntersectCache($mysqli, $baseDir) {
|
||||
global $tableProgramme;
|
||||
global $tableGeraete;
|
||||
global $tableNotenBezeichnungen;
|
||||
global $tableRankLiveConfigs;
|
||||
global $tableVar;
|
||||
|
||||
// 1. Fetch all unique IDs you need to loop through
|
||||
$all_programms = array_column(db_select($mysqli, $tableProgramme, '`id`', '`aktiv` = ?', [1]) ?? [], 'id');
|
||||
$all_geraete = array_column(db_select($mysqli, $tableGeraete, 'id') ?? [], 'id');
|
||||
|
||||
// 2. Fetch the static DB configs ONCE before starting the massive loop
|
||||
$rang_note_id = db_get_variable($mysqli, $tableVar, ['rangNote']);
|
||||
|
||||
$json_geraet = db_get_var($mysqli, "SELECT `all_noten_json` FROM $tableRankLiveConfigs WHERE `type_slug` = ?", ["rankLive-geraet"]) ?: '';
|
||||
$json_overview = db_get_var($mysqli, "SELECT `all_noten_json` FROM $tableRankLiveConfigs WHERE `type_slug` = ?", ["rankLive-overview"]) ?: '';
|
||||
$noten_rank_live_geraet = json_decode($json_geraet, true) ?? [];
|
||||
$noten_rank_live_overview = json_decode($json_overview, true) ?? [];
|
||||
|
||||
$notenConfig_db = db_select($mysqli, $tableNotenBezeichnungen, '`berechnung_json`, `id`, `type`, `anzahl_laeufe_json`');
|
||||
$noten_config = array_column($notenConfig_db, null, 'id');
|
||||
$following_config_array = array_column($notenConfig_db, 'berechnung_json', 'id');
|
||||
$all_inputs_noten_ids = array_filter(array_column($notenConfig_db, 'type', 'id'), fn($type) => $type === 'input');
|
||||
|
||||
$masterCache = [];
|
||||
|
||||
// 2. Extract ALL possible unique IDs dynamically from your JSON configurations
|
||||
$max_runs = 1; // Default fallback to at least 1 run
|
||||
|
||||
foreach ($noten_config as $n_id => $data) {
|
||||
$config = json_decode($data['anzahl_laeufe_json'], true);
|
||||
foreach ($config as $geraetKey => $value) {
|
||||
if ($geraetKey === 'default') {
|
||||
$max_runs = max($max_runs, (int)$value);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
foreach ($value as $progKey => $runsCount) {
|
||||
$max_runs = max($max_runs, (int)$runsCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we have array lists instead of associative maps
|
||||
$all_programms = array_values($all_programms);
|
||||
$all_geraete = array_values($all_geraete);
|
||||
|
||||
// Generate standard run sequences (e.g., if max_runs is 2, creates [1, 2])
|
||||
$all_runs = range(1, $max_runs);
|
||||
|
||||
$masterCache = [];
|
||||
|
||||
// 3. The Grand Loop
|
||||
foreach ($all_programms as $programm_id) {
|
||||
|
||||
foreach ($all_geraete as $geraetId) {
|
||||
foreach ($all_runs as $initNoteRun) {
|
||||
|
||||
$all_needed_noten = [];
|
||||
|
||||
foreach ($noten_rank_live_geraet as $ind => $s_note) {
|
||||
|
||||
$n_id = $s_note['n_id'];
|
||||
|
||||
$anzahl_laeufe_json = $noten_config[$n_id]['anzahl_laeufe_json'] ?? '';
|
||||
|
||||
$anzahl_laeufe = json_decode($anzahl_laeufe_json, true);
|
||||
|
||||
$g_id = ($s_note['g_id'] === 'A') ? (int) $geraetId : (int) $s_note['g_id'];
|
||||
|
||||
$run = (int) $s_note['r'];
|
||||
|
||||
$runs = $anzahl_laeufe[$g_id][(int) $programm_id] ?? $anzahl_laeufe[$g_id]['all'] ?? $anzahl_laeufe['default'] ?? 0;
|
||||
|
||||
if (((int) $runs) < $run) {
|
||||
unset($noten_rank_live_geraet[$ind]);
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = "$n_id|$g_id|$run";
|
||||
|
||||
if (!isset($all_needed_noten[$key])) {
|
||||
$all_needed_noten[$key] = [
|
||||
"r" => $run,
|
||||
"g_id" => $g_id,
|
||||
"n_id" => $n_id
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($noten_rank_live_overview as $s_note) {
|
||||
|
||||
$n_id = $s_note['n_id'];
|
||||
$g_id = $s_note['g_id'];
|
||||
$run = $s_note['r'];
|
||||
|
||||
$key = "$n_id|$g_id|$run";
|
||||
|
||||
if (!isset($all_needed_noten[$key])) {
|
||||
$all_needed_noten[$key] = [
|
||||
"r" => $run,
|
||||
"g_id" => $g_id,
|
||||
"n_id" => $n_id
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$all_updating_noten = [];
|
||||
|
||||
foreach ($following_config_array as $this_note_id => $s_note_abhaenige_rechnungen_json) {
|
||||
$s_note_abhaenige_rechnungen = json_decode($s_note_abhaenige_rechnungen_json ?? '') ?? [];
|
||||
foreach ($s_note_abhaenige_rechnungen as $s_rechnung) {
|
||||
$this_note_geraet_id = $s_rechnung[1];
|
||||
|
||||
if ($this_note_geraet_id !== 'A' && (int) $this_note_geraet_id !== (int) $geraetId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$target_note_id = $s_rechnung[0];
|
||||
$target_run_raw = $s_rechnung[2][0] ?? 'A';
|
||||
$target_geraet_id_raw = $s_rechnung[2][1] ?? 'A';
|
||||
|
||||
$target_run = ($target_run_raw === 'A') ? $initNoteRun : (int) $target_run_raw;
|
||||
$target_geraet_id = ($target_geraet_id_raw === 'A') ? $geraetId : (int) $target_geraet_id_raw;
|
||||
|
||||
$key = "$target_note_id|$target_geraet_id|$target_run";
|
||||
|
||||
if (!isset($all_updating_noten[$key])) {
|
||||
$all_updating_noten[$key] = [
|
||||
"r" => $target_run,
|
||||
"g_id" => $target_geraet_id,
|
||||
"n_id" => $target_note_id
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($all_inputs_noten_ids as $n_id => $_) {
|
||||
|
||||
$anzahl_laeufe_json = $noten_config[$n_id]['anzahl_laeufe_json'] ?? '';
|
||||
|
||||
$anzahl_laeufe = json_decode($anzahl_laeufe_json, true);
|
||||
|
||||
$runs = $anzahl_laeufe[$geraetId][(int) $programm_id] ?? $anzahl_laeufe[$geraetId]['all'] ?? $anzahl_laeufe['default'] ?? 0;
|
||||
|
||||
if ($initNoteRun > $runs) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = "$n_id|$geraetId|$initNoteRun";
|
||||
|
||||
if (!isset($all_updating_noten[$key])) {
|
||||
$all_updating_noten[$key] = [
|
||||
"r" => $initNoteRun,
|
||||
"g_id" => $geraetId,
|
||||
"n_id" => $n_id
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$intersect_noten = array_intersect_key($all_updating_noten, $all_needed_noten);
|
||||
|
||||
$key = "$rang_note_id|0|1";
|
||||
|
||||
if (!isset($all_updating_noten[$key])) {
|
||||
$all_updating_noten[$key] = [
|
||||
"r" => 1,
|
||||
"g_id" => 0,
|
||||
"n_id" => $rang_note_id
|
||||
];
|
||||
}
|
||||
|
||||
$sql_where_array = [];
|
||||
$sql_where_values = [];
|
||||
|
||||
$i = 1;
|
||||
|
||||
foreach ($intersect_noten as $s_note) {
|
||||
$sql_where_values[] = $s_note['n_id'];
|
||||
$sql_where_values[] = $s_note['g_id'];
|
||||
$sql_where_values[] = $s_note['r'];
|
||||
|
||||
$sql_where_array[] = '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)';
|
||||
}
|
||||
|
||||
$sql_where_string = '';
|
||||
|
||||
if (!empty($sql_where_values)) {
|
||||
$sql_where_string = implode(' OR ', $sql_where_array);
|
||||
}
|
||||
|
||||
|
||||
if (!empty($intersect_noten)) {
|
||||
$masterCache[$programm_id][$geraetId][$initNoteRun] = ["SQL" => $sql_where_string, "values" => $sql_where_values, "intersect_noten" => $intersect_noten];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Save to file
|
||||
$fileContent = "<?php\nreturn " . var_export($masterCache, true) . ";";
|
||||
file_put_contents($baseDir . '/../scripts/cache/display-dependencies.php', $fileContent);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
function regenerate_noten_cache($mysqli, $tableNotenBezeichnungen, $baseDir) {
|
||||
if (!function_exists('db_select')) require $baseDir . '/../scripts/db/db-functions.php';
|
||||
|
||||
$notenRechnerCache = new NotenRechner();
|
||||
|
||||
$all = db_select($mysqli, $tableNotenBezeichnungen, "id, default_value, pro_geraet, geraete_json, anzahl_laeufe_json, berechnung, nullstellen, zeige_in_rank_live, display_string");
|
||||
|
||||
$ascArrayDefaultValues = array_column($all, 'default_value', 'id');
|
||||
$ascArrayProGeraet = array_column($all, 'pro_geraet', 'id');
|
||||
$ascArrayRechnungen = array_column($all, 'berechnung', 'id');
|
||||
$indexedNullstellen = array_column($all, 'nullstellen', 'id');
|
||||
$ascPrefixDisplay = array_column($all, 'display_string', 'id');
|
||||
|
||||
$ascArrayGeraeteJSON = array_column($all, 'geraete_json', 'id');
|
||||
foreach ($ascArrayGeraeteJSON as $key => $val) {
|
||||
$ascArrayGeraeteJSON[$key] = json_decode((string)$val, true);
|
||||
}
|
||||
|
||||
$ascArrayAnzahlLaeufeJSON = array_column($all, 'anzahl_laeufe_json', 'id');
|
||||
foreach ($ascArrayAnzahlLaeufeJSON as $key => $val) {
|
||||
$ascArrayAnzahlLaeufeJSON[$key] = json_decode((string)$val, true) ?? [];
|
||||
}
|
||||
|
||||
$export = "<?php\n\nreturn [\n";
|
||||
$export .= " 'default_values' => " . var_export($ascArrayDefaultValues, true) . ",\n";
|
||||
$export .= " 'pro_geraet' => " . var_export($ascArrayProGeraet, true) . ",\n";
|
||||
$export .= " 'geraete_json' => " . var_export($ascArrayGeraeteJSON, true) . ",\n";
|
||||
$export .= " 'anzahl_laeufe_json' => " . var_export($ascArrayAnzahlLaeufeJSON, true) . ",\n";
|
||||
$export .= " 'rechnungen' => " . var_export($ascArrayRechnungen, true) . ",\n";
|
||||
$export .= " 'nullstellen' => " . var_export($indexedNullstellen, true) . "\n";
|
||||
$export .= " ];\n";
|
||||
|
||||
file_put_contents($baseDir . '/../scripts/cache/noten-config-calculating-cache.php', $export);
|
||||
|
||||
$ascArrayStoreRuns = [];
|
||||
$ascArrayStoreGeraete = [];
|
||||
|
||||
foreach ($ascArrayRechnungen as $id => $calc) {
|
||||
$res = $notenRechnerCache->getStoreGeraetRun($calc);
|
||||
$ascArrayStoreRuns[$id] = $res['run_num'] ?? 'A';
|
||||
$ascArrayStoreGeraete[$id] = $res['geraet_id'] ?? 'A';
|
||||
}
|
||||
|
||||
$exportDisplay = "<?php\n\nreturn [\n";
|
||||
$exportDisplay .= " 'default_values' => " . var_export($ascArrayDefaultValues, true) . ",\n";
|
||||
$exportDisplay .= " 'pro_geraet' => " . var_export($ascArrayProGeraet, true) . ",\n";
|
||||
$exportDisplay .= " 'geraete_json' => " . var_export($ascArrayGeraeteJSON, true) . ",\n";
|
||||
$exportDisplay .= " 'anzahl_laeufe_json' => " . var_export($ascArrayAnzahlLaeufeJSON, true) . ",\n";
|
||||
$exportDisplay .= " 'nullstellen' => " . var_export($indexedNullstellen, true) . ",\n";
|
||||
$exportDisplay .= " 'display_string' => " . var_export($ascPrefixDisplay, true) . ",\n";
|
||||
$exportDisplay .= " 'store_run' => " . var_export($ascArrayStoreRuns, true) . ",\n";
|
||||
$exportDisplay .= " 'store_geraet' => " . var_export($ascArrayStoreGeraete, true) . "\n";
|
||||
$exportDisplay .= "];\n";
|
||||
|
||||
file_put_contents($baseDir . '/../scripts/cache/noten-config-display-cache.php', $exportDisplay);
|
||||
}
|
||||
+661
@@ -0,0 +1,661 @@
|
||||
<?php
|
||||
return array (
|
||||
4 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 1,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 1,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 1,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 70,
|
||||
4 => 1,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 1,
|
||||
11 => 2,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|1|2' =>
|
||||
array (
|
||||
'r' => 2,
|
||||
'g_id' => 1,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|1|2' =>
|
||||
array (
|
||||
'r' => 2,
|
||||
'g_id' => 1,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 2,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 2,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 2,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 70,
|
||||
1 => 2,
|
||||
2 => 1,
|
||||
3 => 80,
|
||||
4 => 0,
|
||||
5 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'70|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 3,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 3,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 3,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 70,
|
||||
1 => 3,
|
||||
2 => 1,
|
||||
3 => 80,
|
||||
4 => 0,
|
||||
5 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'70|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 4,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 4,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 4,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 70,
|
||||
1 => 4,
|
||||
2 => 1,
|
||||
3 => 80,
|
||||
4 => 0,
|
||||
5 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'70|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
13 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 1,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 1,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 1,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 70,
|
||||
4 => 1,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 1,
|
||||
11 => 2,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|1|2' =>
|
||||
array (
|
||||
'r' => 2,
|
||||
'g_id' => 1,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|1|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 1,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|1|2' =>
|
||||
array (
|
||||
'r' => 2,
|
||||
'g_id' => 1,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 2,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 2,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 2,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 70,
|
||||
1 => 2,
|
||||
2 => 1,
|
||||
3 => 80,
|
||||
4 => 0,
|
||||
5 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'70|2|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 2,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
3 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 3,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 3,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 3,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 70,
|
||||
1 => 3,
|
||||
2 => 1,
|
||||
3 => 80,
|
||||
4 => 0,
|
||||
5 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'70|3|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 3,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
4 =>
|
||||
array (
|
||||
1 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 60,
|
||||
1 => 4,
|
||||
2 => 1,
|
||||
3 => 70,
|
||||
4 => 4,
|
||||
5 => 1,
|
||||
6 => 80,
|
||||
7 => 0,
|
||||
8 => 1,
|
||||
9 => 40,
|
||||
10 => 4,
|
||||
11 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'60|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 60,
|
||||
),
|
||||
'70|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
'40|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 40,
|
||||
),
|
||||
),
|
||||
),
|
||||
2 =>
|
||||
array (
|
||||
'SQL' => '(`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?) OR (`note_bezeichnung_id` = ? AND `geraet_id` = ? AND `run_number` = ?)',
|
||||
'values' =>
|
||||
array (
|
||||
0 => 70,
|
||||
1 => 4,
|
||||
2 => 1,
|
||||
3 => 80,
|
||||
4 => 0,
|
||||
5 => 1,
|
||||
),
|
||||
'intersect_noten' =>
|
||||
array (
|
||||
'70|4|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 4,
|
||||
'n_id' => 70,
|
||||
),
|
||||
'80|0|1' =>
|
||||
array (
|
||||
'r' => 1,
|
||||
'g_id' => 0,
|
||||
'n_id' => 80,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
+133
@@ -0,0 +1,133 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'default_values' => array (
|
||||
10 => 0.0,
|
||||
11 => 0.0,
|
||||
20 => 0.0,
|
||||
40 => 0.0,
|
||||
50 => 0.0,
|
||||
60 => 0.0,
|
||||
70 => 0.0,
|
||||
80 => 0.0,
|
||||
),
|
||||
'pro_geraet' => array (
|
||||
10 => 1,
|
||||
11 => 1,
|
||||
20 => 1,
|
||||
40 => 1,
|
||||
50 => 1,
|
||||
60 => 1,
|
||||
70 => 1,
|
||||
80 => 0,
|
||||
),
|
||||
'geraete_json' => array (
|
||||
10 =>
|
||||
array (
|
||||
),
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
20 =>
|
||||
array (
|
||||
),
|
||||
40 =>
|
||||
array (
|
||||
),
|
||||
50 =>
|
||||
array (
|
||||
),
|
||||
60 =>
|
||||
array (
|
||||
),
|
||||
70 =>
|
||||
array (
|
||||
),
|
||||
80 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
),
|
||||
'anzahl_laeufe_json' => array (
|
||||
10 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
11 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
20 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
40 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
50 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
60 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
70 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
),
|
||||
80 =>
|
||||
array (
|
||||
'default' => 0,
|
||||
0 =>
|
||||
array (
|
||||
'all' => 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
'rechnungen' => array (
|
||||
10 => '',
|
||||
11 => '',
|
||||
20 => '({10[S]} + {11[S]}) / 2->RSGS',
|
||||
40 => '',
|
||||
50 => '',
|
||||
60 => '10 - {20[S]} + {40[S]} - {50[S]}->RSGS',
|
||||
70 => 'AVGR({60[S]})->R1GS',
|
||||
80 => '{70[1]} + {70[2]} + {70[3]} + {70[4]}->R1G0',
|
||||
),
|
||||
'nullstellen' => array (
|
||||
10 => 3,
|
||||
11 => 3,
|
||||
20 => 3,
|
||||
40 => 2,
|
||||
50 => 2,
|
||||
60 => 2,
|
||||
70 => 2,
|
||||
80 => 2,
|
||||
)
|
||||
];
|
||||
+163
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'default_values' => array (
|
||||
10 => 0.0,
|
||||
11 => 0.0,
|
||||
20 => 0.0,
|
||||
40 => 0.0,
|
||||
50 => 0.0,
|
||||
60 => 0.0,
|
||||
70 => 0.0,
|
||||
80 => 0.0,
|
||||
),
|
||||
'pro_geraet' => array (
|
||||
10 => 1,
|
||||
11 => 1,
|
||||
20 => 1,
|
||||
40 => 1,
|
||||
50 => 1,
|
||||
60 => 1,
|
||||
70 => 1,
|
||||
80 => 0,
|
||||
),
|
||||
'geraete_json' => array (
|
||||
10 =>
|
||||
array (
|
||||
),
|
||||
11 =>
|
||||
array (
|
||||
),
|
||||
20 =>
|
||||
array (
|
||||
),
|
||||
40 =>
|
||||
array (
|
||||
),
|
||||
50 =>
|
||||
array (
|
||||
),
|
||||
60 =>
|
||||
array (
|
||||
),
|
||||
70 =>
|
||||
array (
|
||||
),
|
||||
80 =>
|
||||
array (
|
||||
0 => 0,
|
||||
),
|
||||
),
|
||||
'anzahl_laeufe_json' => array (
|
||||
10 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
11 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
20 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
40 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
50 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
60 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
1 =>
|
||||
array (
|
||||
'all' => 2,
|
||||
),
|
||||
),
|
||||
70 =>
|
||||
array (
|
||||
'default' => 1,
|
||||
),
|
||||
80 =>
|
||||
array (
|
||||
'default' => 0,
|
||||
0 =>
|
||||
array (
|
||||
'all' => 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
'nullstellen' => array (
|
||||
10 => 3,
|
||||
11 => 3,
|
||||
20 => 3,
|
||||
40 => 2,
|
||||
50 => 2,
|
||||
60 => 2,
|
||||
70 => 2,
|
||||
80 => 2,
|
||||
),
|
||||
'zeige_in_rank_live' => array (
|
||||
10 => 1,
|
||||
11 => 1,
|
||||
20 => 1,
|
||||
40 => 1,
|
||||
50 => 1,
|
||||
60 => 1,
|
||||
70 => 1,
|
||||
80 => 1,
|
||||
),
|
||||
'display_string' => array (
|
||||
10 => '${note}',
|
||||
11 => '${note}',
|
||||
20 => '${note}',
|
||||
40 => 'D ${note}',
|
||||
50 => '${note}',
|
||||
60 => '${note}',
|
||||
70 => '${note}',
|
||||
80 => '${note}',
|
||||
),
|
||||
'store_run' => array (
|
||||
10 => 'A',
|
||||
11 => 'A',
|
||||
20 => 'A',
|
||||
40 => 'A',
|
||||
50 => 'A',
|
||||
60 => 'A',
|
||||
70 => 1,
|
||||
80 => 1,
|
||||
),
|
||||
'store_geraet' => array (
|
||||
10 => 'A',
|
||||
11 => 'A',
|
||||
20 => 'A',
|
||||
40 => 'A',
|
||||
50 => 'A',
|
||||
60 => 'A',
|
||||
70 => 'A',
|
||||
80 => 0,
|
||||
)
|
||||
];
|
||||
@@ -1,170 +0,0 @@
|
||||
<?php
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
require __DIR__ . '/../../composer/vendor/autoload.php';
|
||||
|
||||
$envFile = realpath(__DIR__ . '/../../config/.env.db');
|
||||
|
||||
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.db');
|
||||
|
||||
$dotenv->load();
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Dotenv error: " . $e->getMessage()
|
||||
]);
|
||||
}
|
||||
|
||||
if (!isset($_ENV['DB_HOST']) || !isset($_ENV['DB_NAME']) || !isset($_ENV['DB_USER']) || !isset($_ENV['DB_PASSWORD'])){
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'corrupt cofig file'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$mysqli = @new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
|
||||
if ($mysqli->connect_error) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "DB connection failed"
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$mysqli->set_charset("utf8");
|
||||
|
||||
require __DIR__ . "/db-tables.php";
|
||||
|
||||
$tables = [$tableTurnerinnen, $tableOrders, $tableBasketItems, $tableKrProtokoll];
|
||||
$cleartablearray = [$tableOrders, $tableBasketItems, $tableKrProtokoll];
|
||||
|
||||
require __DIR__ . "/../../resultate/newjson.php";
|
||||
|
||||
// Columns to set to 0
|
||||
$columns0 = [
|
||||
'd-note balken', 'd-note boden',
|
||||
'd-note sprung', 'd-note barren',
|
||||
'e1 note sprung','e2 note sprung','e note sprung','neutrale abzuege sprung',
|
||||
'e1 note barren','e2 note barren','e note barren','neutrale abzuege barren',
|
||||
'e1 note balken','e2 note balken','e note balken','neutrale abzuege balken',
|
||||
'e1 note boden','e2 note boden','e note boden','neutrale abzuege boden',
|
||||
'bezahlt', 'bezahltoverride', 'rang', 'abteilung', 'startgeraet', 'anzabteilungen', 'startindex', 'bodenmusik'
|
||||
];
|
||||
|
||||
$dir = __DIR__ . '/../../../test-wkvs/dbbackups';
|
||||
|
||||
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
$newdir = $dir ."/". date('Ymd_His');
|
||||
|
||||
if (!is_dir($newdir)) {
|
||||
mkdir($newdir, 0755, true);
|
||||
}
|
||||
|
||||
foreach ($tables as $t){
|
||||
$backupFile = $t . '_backup' . '.sql';
|
||||
$filename = $newdir . '/' . $backupFile;
|
||||
|
||||
$handle = fopen($filename, 'w');
|
||||
if ($handle === false) {
|
||||
die("Cannot open file: $filename");
|
||||
}
|
||||
|
||||
|
||||
$res = $mysqli->query("SHOW CREATE TABLE `$t`");
|
||||
$row = $res->fetch_assoc();
|
||||
fwrite($handle, $row['Create Table'] . ";\n\n");
|
||||
|
||||
|
||||
$res = $mysqli->query("SELECT * FROM `$t`");
|
||||
while ($row = $res->fetch_assoc()) {
|
||||
$columns = array_map(function($col){ return "`$col`"; }, array_keys($row));
|
||||
$values = array_map(function($val) use ($mysqli) { return "'" . $mysqli->real_escape_string($val) . "'"; }, array_values($row));
|
||||
fwrite($handle, "INSERT INTO `$t` (" . implode(", ", $columns) . ") VALUES (" . implode(", ", $values) . ");\n");
|
||||
}
|
||||
|
||||
fclose($handle);
|
||||
}
|
||||
|
||||
// Columns to set to 10
|
||||
$columns10 = [
|
||||
'note balken', 'note boden',
|
||||
'note sprung', 'note barren'
|
||||
];
|
||||
|
||||
$set = [];
|
||||
$params = [];
|
||||
$types = '';
|
||||
|
||||
// Add 0 columns
|
||||
foreach ($columns0 as $col) {
|
||||
$set[] = "`$col` = ?";
|
||||
$params[] = '0';
|
||||
$types .= 's';
|
||||
}
|
||||
|
||||
// Add 10 columns
|
||||
foreach ($columns10 as $col) {
|
||||
$set[] = "`$col` = ?";
|
||||
$params[] = '10';
|
||||
$types .= 's';
|
||||
}
|
||||
|
||||
// Add gesammtpunktzahl column
|
||||
$set[] = "`gesamtpunktzahl` = ?";
|
||||
$params[] = '40';
|
||||
$types .= 's';
|
||||
|
||||
// Build SQL
|
||||
$sql = "UPDATE turnerinnen SET " . implode(", ", $set);
|
||||
|
||||
// Prepare
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
if ($stmt === false) {
|
||||
die("Prepare failed: " . $mysqli->error);
|
||||
}
|
||||
|
||||
// Bind parameters dynamically
|
||||
$bind_names[] = $types;
|
||||
for ($i = 0; $i < count($params); $i++) {
|
||||
$bind_names[] = &$params[$i]; // reference required
|
||||
}
|
||||
call_user_func_array([$stmt, 'bind_param'], $bind_names);
|
||||
|
||||
// Execute
|
||||
if (!$stmt->execute()) {
|
||||
echo "Error: " . $stmt->error;
|
||||
}
|
||||
// Close
|
||||
$stmt->close();
|
||||
|
||||
foreach ($cleartablearray as $t) {
|
||||
$stmt = $mysqli->prepare("DELETE FROM ".$t);
|
||||
if (!$stmt->execute()) {
|
||||
echo "Error: " . $stmt->error;
|
||||
}
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
//
|
||||
$mysqli->close();
|
||||
?>
|
||||
@@ -130,3 +130,56 @@ function db_get_var($mysqli, $sql, $params = []) {
|
||||
$stmt->close();
|
||||
return $value;
|
||||
}
|
||||
|
||||
function db_get_variable($mysqli, $tableVar, $params = []) {
|
||||
if (count($params) !== 1) return null;
|
||||
$stmt = $mysqli->prepare("SELECT `value` FROM $tableVar WHERE `name` = ?");
|
||||
$stmt->bind_param("s", ...$params);
|
||||
$stmt->execute();
|
||||
$stmt->bind_result($value);
|
||||
$stmt->fetch();
|
||||
$stmt->close();
|
||||
return $value;
|
||||
}
|
||||
|
||||
function db_update_variable($mysqli, $tableVar, $params = ['name', 'value']) {
|
||||
if (count($params) !== 2) return false;
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableVar (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
$stmt->bind_param("ss", ...$params);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
return true;
|
||||
}
|
||||
|
||||
function db_check_var(mysqli $mysqli, string $table, string $where, array $params = []) : bool {
|
||||
|
||||
$table = preg_replace('/[^a-zA-Z0-9_]/', '', $table);
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT 1 FROM `" . $table . "` WHERE " . $where);
|
||||
if (!$stmt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!empty($params)) {
|
||||
$types = '';
|
||||
foreach ($params as $param) {
|
||||
if (is_int($param)) {
|
||||
$types .= 'i';
|
||||
} elseif (is_float($param)) {
|
||||
$types .= 'd';
|
||||
} else {
|
||||
$types .= 's';
|
||||
}
|
||||
}
|
||||
$stmt->bind_param($types, ...$params);
|
||||
}
|
||||
|
||||
$stmt->execute();
|
||||
|
||||
$stmt->store_result();
|
||||
$exists = $stmt->num_rows > 0;
|
||||
|
||||
$stmt->close();
|
||||
|
||||
return $exists;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ $prefix = $_ENV['DB_PREFIX'] ?? '';
|
||||
|
||||
|
||||
$tableDefinitions = [
|
||||
'Turnerinnen' => 'DB_TABLE_TURNERINNEN',
|
||||
'Teilnehmende' => 'DB_TABLE_TEILNEHMENDE',
|
||||
'Orders' => 'DB_TABLE_ORDERS',
|
||||
'BasketItems' => 'DB_TABLE_BASKET_ITEMS',
|
||||
'Var' => 'DB_TABLE_VARIABLES',
|
||||
@@ -44,11 +44,17 @@ $tableDefinitions = [
|
||||
'InternUsers' => 'DB_TABLE_INTERN_USERS',
|
||||
'Vereine' => 'DB_TABLE_VEREINE',
|
||||
'Abt' => 'DB_TABLE_ABTEILUNGEN',
|
||||
'TurnerinnenAbt' => 'DB_TABLE_TURNERINNEN_ABTEILUNGEN',
|
||||
'TeilnehmendeAbt' => 'DB_TABLE_TEILNEHMENDE_ABTEILUNGEN',
|
||||
'Geraete' => 'DB_TABLE_GERAETE',
|
||||
'Audiofiles' => 'DB_TABLE_AUDIOFILES',
|
||||
'TeilnehmendeAudiofiles' => 'DB_TABLE_TEILNEHMENDE_AUDIOFILES',
|
||||
'Noten' => 'DB_TABLE_NOTEN',
|
||||
'NotenBezeichnungen' => 'DB_TABLE_NOTEN_BEZEICHNUNGEN'
|
||||
'NotenChanges' => 'DB_TABLE_NOTEN_CHANGES',
|
||||
'NotenBezeichnungen' => 'DB_TABLE_NOTEN_BEZEICHNUNGEN',
|
||||
'OrdersLog' => 'DB_TABLE_ORDERS_LOG',
|
||||
'ZeitplanTypes' => 'DB_TABLE_ZEITPLAN_TYPES',
|
||||
'AbtZeiten' => 'DB_TABLE_ABTEILUNGEN_ZEITEN',
|
||||
'RankLiveConfigs' => 'DB_TABLE_RANKLIVE_CONFIGS'
|
||||
];
|
||||
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ try {
|
||||
]);
|
||||
}
|
||||
|
||||
if (!isset($_ENV['DB_HOST']) || !isset($_ENV['DB_NAME']) || !isset($_ENV['DB_GUEST_USER']) || !isset($_ENV['DB_GUEST_PASSWORD'])){
|
||||
if (!isset($_ENV['DB_HOST']) || !isset($_ENV['DB_NAME']) || !isset($_ENV['DB_GUEST_USER']) || !isset($_ENV['DB_GUEST_PASSWORD']) || !isset($_ENV['DB_PORT'])){
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'corrupt cofig file'
|
||||
@@ -37,7 +37,7 @@ if (!isset($_ENV['DB_HOST']) || !isset($_ENV['DB_NAME']) || !isset($_ENV['DB_GUE
|
||||
exit;
|
||||
}
|
||||
|
||||
$guest = @new mysqli($_ENV['DB_HOST'], $_ENV['DB_GUEST_USER'], $_ENV['DB_GUEST_PASSWORD'], $_ENV['DB_NAME']);
|
||||
$guest = @new mysqli($_ENV['DB_HOST'], $_ENV['DB_GUEST_USER'], $_ENV['DB_GUEST_PASSWORD'], $_ENV['DB_NAME'], $_ENV['DB_PORT']);
|
||||
if ($guest->connect_error) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
|
||||
@@ -56,7 +56,7 @@ try {
|
||||
]);
|
||||
}
|
||||
|
||||
if (!isset($_ENV['DB_HOST']) || !isset($_ENV['DB_NAME']) || !isset($_ENV['DB_USER']) || !isset($_ENV['DB_PASSWORD'])){
|
||||
if (!isset($_ENV['DB_HOST']) || !isset($_ENV['DB_NAME']) || !isset($_ENV['DB_USER']) || !isset($_ENV['DB_PASSWORD']) || !isset($_ENV['DB_PORT'])){
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'corrupt cofig file'
|
||||
@@ -64,7 +64,7 @@ if (!isset($_ENV['DB_HOST']) || !isset($_ENV['DB_NAME']) || !isset($_ENV['DB_USE
|
||||
exit;
|
||||
}
|
||||
|
||||
$mysqli = @new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME']);
|
||||
$mysqli = @new mysqli($_ENV['DB_HOST'], $_ENV['DB_USER'], $_ENV['DB_PASSWORD'], $_ENV['DB_NAME'], $_ENV['DB_PORT']);
|
||||
if ($mysqli->connect_error) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
function parse_input_to_delete() {
|
||||
global $_DELETE;
|
||||
$_DELETE = [];
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'DELETE') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$rawInput = file_get_contents('php://input');
|
||||
|
||||
$contentType = $_SERVER['CONTENT_TYPE'] ?? '';
|
||||
if (stripos($contentType, 'application/json') !== false) {
|
||||
$_DELETE = json_decode($rawInput, true) ?? [];
|
||||
} else {
|
||||
parse_str($rawInput, $_DELETE);
|
||||
}
|
||||
}
|
||||
@@ -10,11 +10,11 @@ if ($userid > 0) {
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result) {
|
||||
$dbarray = $result->fetch_assoc(); // $programme is an array
|
||||
$dbarray = $result->fetch_assoc();
|
||||
}
|
||||
|
||||
$freigabe_json = $dbarray['freigabe'];
|
||||
$username = $dbarray['username'];
|
||||
$freigabe_json = $dbarray['freigabe'] ?? '';
|
||||
$username = $dbarray['username'] ?? '';
|
||||
|
||||
$stmt->close();
|
||||
|
||||
@@ -24,27 +24,26 @@ if ($userid > 0) {
|
||||
$arrayfreigaben = $arrayfreigaben['freigabenKampfrichter'] ?? [];
|
||||
}
|
||||
}
|
||||
if (!empty($arrayfreigaben)) {
|
||||
|
||||
$key = array_search('admin', $arrayfreigaben, true);
|
||||
if ($key !== false) {
|
||||
unset($arrayfreigaben[$key]);
|
||||
array_unshift($arrayfreigaben, 'admin');
|
||||
$arrayfreigaben = array_values($arrayfreigaben);
|
||||
}
|
||||
|
||||
$selectedfreigabe = $_SESSION['selectedFreigabeKampfrichter'] ?? $arrayfreigaben[0];
|
||||
|
||||
if (!in_array($selectedfreigabe, $arrayfreigaben, true)) {
|
||||
$selectedfreigabe = $arrayfreigaben[0];
|
||||
}
|
||||
|
||||
$_SESSION['selectedFreigabeKampfrichter'] = $selectedfreigabe;
|
||||
} else {
|
||||
if (empty($arrayfreigaben)) {
|
||||
echo 'Keine gültigen Freigaben! Sie wurden abgemeldet.';
|
||||
$_SESSION['access_granted_kampfrichter'] = false;
|
||||
$_SESSION['logoDisplay'] = true;
|
||||
exit;
|
||||
}
|
||||
|
||||
$selecteduser = $selectedfreigabe;
|
||||
$key = array_search("A", $arrayfreigaben, true);
|
||||
if ($key !== false) {
|
||||
unset($arrayfreigaben[$key]);
|
||||
array_unshift($arrayfreigaben, "A");
|
||||
$arrayfreigaben = array_values($arrayfreigaben);
|
||||
}
|
||||
|
||||
$selectedFreigabeId = $_SESSION['selectedFreigabeIdKampfrichter'] ?? $arrayfreigaben[0];
|
||||
|
||||
if (!in_array($selectedFreigabeId, $arrayfreigaben, true)) {
|
||||
$selectedFreigabeId = $arrayfreigaben[0];
|
||||
}
|
||||
|
||||
$_SESSION['selectedFreigabeIdKampfrichter'] = $selectedFreigabeId;
|
||||
|
||||
$isAdmin = $selectedFreigabeId === 'A';
|
||||
|
||||
@@ -4,44 +4,57 @@
|
||||
$form_message = $_SESSION['form_message'] ?? '';
|
||||
unset($_SESSION['form_message']);
|
||||
|
||||
if ((isset($_POST['prev_abt'])) && !empty($_POST['prev_abt_submit'])) {
|
||||
if (isset($_POST['prev_abt_submit'])) {
|
||||
verify_csrf();
|
||||
$value = $aktabt;
|
||||
if ($value > 1){
|
||||
$value -= 1;
|
||||
$name = 'wk_panel_current_abt';
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableVar (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUE(`value`)");
|
||||
|
||||
$stmt->bind_param("ss", $name, $value);
|
||||
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
db_update_variable($mysqli, $tableVar, ['wk_panel_current_abt', $value]);
|
||||
}
|
||||
header("Location: /intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
|
||||
if ((isset($_POST['next_abt'])) && !empty($_POST['next_abt_submit'])) {
|
||||
if (isset($_POST['next_abt_submit'])) {
|
||||
verify_csrf();
|
||||
$value = $aktabt;
|
||||
$maxvalue = db_get_var($mysqli, "SELECT name FROM $tableAbt ORDER BY name DESC LIMIT 1");
|
||||
$maxvalue = (int) (db_get_var($mysqli, "SELECT name FROM $tableAbt ORDER BY name DESC LIMIT 1") ?? 1);
|
||||
|
||||
if ($value < $maxvalue){
|
||||
$value += 1;
|
||||
$name = 'wk_panel_current_abt';
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $tableVar (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUE(`value`)");
|
||||
|
||||
$stmt->bind_param("ss", $name, $value);
|
||||
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
db_update_variable($mysqli, $tableVar, ['wk_panel_current_abt', $value]);
|
||||
}
|
||||
header("Location: /intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['prev_subabt_admin_submit']) && $isAdmin) {
|
||||
verify_csrf();
|
||||
$value = $akt_subabt_admin;
|
||||
if ($value > 1){
|
||||
$value -= 1;
|
||||
db_update_variable($mysqli, $tableVar, ['wk_panel_current_subabt_admin', $value]);
|
||||
$_SESSION['ws_Message_json'] = json_encode(['type' => 'UPDATE_RANKLIVE_C_SUBABT', 'payload' => []]);
|
||||
}
|
||||
header("Location: /intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['next_subabt_admin_submit']) && $isAdmin) {
|
||||
verify_csrf();
|
||||
$value = $akt_subabt_admin;
|
||||
$max_value_admin_subabt = count($disciplines);
|
||||
|
||||
if ($value < $max_value_admin_subabt){
|
||||
$value += 1;
|
||||
db_update_variable($mysqli, $tableVar, ['wk_panel_current_subabt_admin', $value]);
|
||||
$_SESSION['ws_Message_json'] = json_encode(['type' => 'UPDATE_RANKLIVE_C_SUBABT', 'payload' => []]);
|
||||
}
|
||||
|
||||
header("Location: /intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
if (!isset($_SESSION['currentsubabt'])){
|
||||
$_SESSION['currentsubabt'] = 1;
|
||||
@@ -56,7 +69,7 @@ if ($_SESSION['last_abt'] !== $aktabt){
|
||||
$_SESSION['last_abt'] = $aktabt;
|
||||
}
|
||||
|
||||
if ((isset($_POST['prev_subabt'])) && !empty($_POST['prev_subabt_submit'])) {
|
||||
if (isset($_POST['prev_subabt_submit'])) {
|
||||
verify_csrf();
|
||||
$value = $_SESSION['currentsubabt'];
|
||||
if ($value > 1){
|
||||
@@ -68,10 +81,10 @@ if ((isset($_POST['prev_subabt'])) && !empty($_POST['prev_subabt_submit'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ((isset($_POST['next_subabt'])) && !empty($_POST['next_subabt_submit'])) {
|
||||
if (isset($_POST['next_subabt_submit'])) {
|
||||
verify_csrf();
|
||||
$value = $_SESSION['currentsubabt'];
|
||||
if ($value < $maxsubabt){
|
||||
if ($value < $max_subabt){
|
||||
$_SESSION['currentsubabt']++;
|
||||
$_SESSION['currentEditId'] = false;
|
||||
$_SESSION['last_abt'] = $aktabt;
|
||||
@@ -80,12 +93,28 @@ if ((isset($_POST['next_subabt'])) && !empty($_POST['next_subabt_submit'])) {
|
||||
exit;
|
||||
}
|
||||
|
||||
if ( isset($_POST['togle_advanced_mode_admin']) && !empty($_POST['togle_advanced_mode_admin_submit']) && !empty($_POST['csrf_token'])) {
|
||||
if (isset($_POST['prog_view_admin_submit'])) {
|
||||
verify_csrf();
|
||||
$current_value = $focus_view_admin;
|
||||
$new_value = !$current_value;
|
||||
|
||||
$_SESSION['abtViewAdmin'] = $new_value;
|
||||
$_SESSION['view_type_admin'] = 'prog';
|
||||
|
||||
header("Location: /intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['abt_view_admin_submit'])) {
|
||||
verify_csrf();
|
||||
|
||||
$_SESSION['view_type_admin'] = 'abt';
|
||||
|
||||
header("Location: /intern/kampfrichter");
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['live_view_admin_submit'])) {
|
||||
verify_csrf();
|
||||
|
||||
$_SESSION['view_type_admin'] = 'live';
|
||||
|
||||
header("Location: /intern/kampfrichter");
|
||||
exit;
|
||||
|
||||
+78
-174
@@ -1,5 +1,22 @@
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../rate-limiter/rate-limiter.php';
|
||||
|
||||
$limiter = new TokenBucket(
|
||||
redis: $redis,
|
||||
capacity: 30,
|
||||
refillRate: 2,
|
||||
refillInterval: 5.0
|
||||
);
|
||||
|
||||
$result = $limiter->allow('RATE_LIMITER:TYPE:login:IP:'. $_SERVER['REMOTE_ADDR']);
|
||||
|
||||
if (!$result['allowed']) {
|
||||
http_response_code(429);
|
||||
include __DIR__ . "/../../www/error-pages/429.html";
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once __DIR__ . '/../session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
@@ -83,187 +100,74 @@ if ($_SESSION['lockout_time_'. $logintype] > time()) {
|
||||
}
|
||||
}
|
||||
|
||||
$array_logintitles = [
|
||||
'wk_leitung' => 'Wettkampfleitung',
|
||||
'trainer' => 'Trainer',
|
||||
'kampfrichter' => 'Kampfrichter'
|
||||
]
|
||||
?>
|
||||
<section class="page-secure-login">
|
||||
<div class="bg-picture-secure-login">
|
||||
<img src="/intern/img/login/bg<?= ucfirst($logintype) ?>.webp">
|
||||
</div>
|
||||
<div class="bg-secure-login">
|
||||
<div class="bg-secure-login-form">
|
||||
<?php
|
||||
if (str_contains($logintype, '_')) {
|
||||
$titlelogintype = str_replace('_', '-', $logintype);
|
||||
} else {
|
||||
$titlelogintype = $logintype . 'panel';
|
||||
}
|
||||
?>
|
||||
<h1>Anmeldung<br><?= ucfirst($titlelogintype) ?></h1>
|
||||
<p style="font-weight:400; line-height: 1.5; margin-bottom: 50px;">Bitte verwenden Sie hier Ihren
|
||||
individuellen Zugang
|
||||
</p>
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
|
||||
<form method="post">
|
||||
<label for="access_username">Benutzername eingeben</label><br>
|
||||
<input type="text" id="access_username" name="access_username" required placeholder="Benutzername"><br>
|
||||
<label for="password">Passwort eingeben</label><br>
|
||||
<div id="div_showpw">
|
||||
<input type="password" name="access_passcode" id="access_passcode" placeholder="Passwort" required>
|
||||
<button type="button" id="togglePassword">
|
||||
<svg id="eyeIcon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<input type="submit" name="<?= $logintype ?>_login_submit" value="Einloggen">
|
||||
</form>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Login <?= $array_logintitles[$logintype] ?></title>
|
||||
<link rel="icon" type="png" href="/intern/img/icon.png">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="/intern/css/login.css">
|
||||
<link href="/files/fonts/fonts.css" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/intern/css/user.css">
|
||||
|
||||
<?php if ($error !== ''): ?>
|
||||
<p style="color:red;"><?php echo $error; ?></p>
|
||||
<?php endif; ?>
|
||||
</head>
|
||||
|
||||
<body class="login">
|
||||
<section class="page-secure-login">
|
||||
<div class="bg-picture-secure-login">
|
||||
<img src="/intern/img/login/bg<?= ucfirst($logintype) ?>.webp">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div class="bg-secure-login">
|
||||
<div class="bg-secure-login-form">
|
||||
<h1>Anmeldung<br><?= $array_logintitles[$logintype] ?? "" ?></h1>
|
||||
|
||||
<a class="seclog_home_link" href="/"><img src="/intern/img/logo-normal.png" width="64" height="64"></a>
|
||||
<form method="post">
|
||||
<label for="access_username">Benutzername eingeben</label><br>
|
||||
<input type="text" id="access_username" name="access_username" required placeholder="Benutzername"><br>
|
||||
<label for="password">Passwort eingeben</label><br>
|
||||
<div id="div_showpw">
|
||||
<input type="password" name="access_passcode" id="access_passcode" placeholder="Passwort" required>
|
||||
<button type="button" id="togglePassword">
|
||||
<svg id="eyeIcon" xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/>
|
||||
<circle cx="12" cy="12" r="3"/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<input type="submit" name="<?= $logintype ?>_login_submit" value="Einloggen">
|
||||
</form>
|
||||
|
||||
<style>
|
||||
body{
|
||||
overflow: hidden;
|
||||
}
|
||||
.page-secure-login{
|
||||
display: flex;
|
||||
}
|
||||
.bg-picture-secure-login{
|
||||
width: calc(100vw - 450px);
|
||||
height: 100vh;
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
}
|
||||
.bg-picture-secure-login img{
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
object-fit: cover;
|
||||
}
|
||||
.bg-secure-login{
|
||||
display: flex;
|
||||
width: 100vw;
|
||||
max-width: 450px;
|
||||
height: 100vh;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
top: 0px;
|
||||
align-items: center;
|
||||
padding: 30px;
|
||||
}
|
||||
.bg-secure-login-form > h1{
|
||||
color: #000 !important;
|
||||
font-size: 32px;
|
||||
}
|
||||
.bg-secure-login-form input[type=password], .bg-secure-login-form input[type=text]{
|
||||
padding: 5px;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
border-top: none !important;
|
||||
border-left: none !important;
|
||||
border-right: none !important;
|
||||
font-size: 16px;
|
||||
border-bottom: 1px solid #000 !important;
|
||||
border-radius: 0px !important;
|
||||
}
|
||||
#access_username {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
<?php if ($error !== ''): ?>
|
||||
<p style="color:red;"><?php echo $error; ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
.bg-secure-login-form input[type=password]:focus, .bg-secure-login-form input[type=text]:focus{
|
||||
outline: none;
|
||||
border-bottom: 1px solid #000 !important;
|
||||
}
|
||||
<a class="seclog_home_link" href="/"><img src="/intern/img/logo-normal.png"></a>
|
||||
|
||||
.bg-secure-login-form input[type=password]::placeholder, .bg-secure-login-form input[type=text]::placeholder {
|
||||
color: #ccc !important;
|
||||
}
|
||||
<script>
|
||||
const passwordInput = document.getElementById('access_passcode');
|
||||
const toggleButton = document.getElementById('togglePassword');
|
||||
const eyeIcon = document.getElementById('eyeIcon');
|
||||
|
||||
.bg-secure-login-form input[type=submit]{
|
||||
background-color: #fff !important;
|
||||
padding: 10px 20px !important;
|
||||
margin-top: 25px !important;
|
||||
border: 1px solid #000 !important;
|
||||
color: #000 !important;
|
||||
transition: all 0.3s ease-out !important;
|
||||
border-radius: 0px !important;
|
||||
}
|
||||
toggleButton.addEventListener('click', () => {
|
||||
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||
passwordInput.setAttribute('type', type);
|
||||
|
||||
body{
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.bg-secure-login-form input[type=submit]:hover{
|
||||
background-color: #000 !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.bg-secure-login-form > p{
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.seclog_home_link{
|
||||
position: fixed;
|
||||
z-index: 1000;
|
||||
top: 30px;
|
||||
right: 30px;
|
||||
}
|
||||
#div_showpw, #access_username {
|
||||
margin-top: 10px;
|
||||
}
|
||||
#togglePassword {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
#togglePassword:hover {
|
||||
transform: translateY(-50%) scale(1.15);
|
||||
}
|
||||
|
||||
#div_showpw{
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
max-width: 300px;
|
||||
}
|
||||
input:-webkit-autofill,
|
||||
input:-webkit-autofill:hover,
|
||||
input:-webkit-autofill:focus,
|
||||
input:-webkit-autofill:active {
|
||||
-webkit-box-shadow: 0 0 0 1000px #ffffff inset !important;
|
||||
box-shadow: 0 0 0 1000px #ffffff inset !important;
|
||||
-webkit-text-fill-color: #000000 !important;
|
||||
transition: background-color 5000s ease-in-out 0s;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
const passwordInput = document.getElementById('access_passcode');
|
||||
const toggleButton = document.getElementById('togglePassword');
|
||||
const eyeIcon = document.getElementById('eyeIcon');
|
||||
|
||||
toggleButton.addEventListener('click', () => {
|
||||
const type = passwordInput.getAttribute('type') === 'password' ? 'text' : 'password';
|
||||
passwordInput.setAttribute('type', type);
|
||||
|
||||
// Swap between eye and eye-with-line
|
||||
if (type === 'password') {
|
||||
// Eye (show)
|
||||
eyeIcon.innerHTML = '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';
|
||||
} else {
|
||||
// Eye with slash (hide)
|
||||
eyeIcon.innerHTML = '<path d="M17.94 17.94L6.06 6.06"/><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
if (type === 'password') {
|
||||
eyeIcon.innerHTML = '<path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';
|
||||
} else {
|
||||
eyeIcon.innerHTML = '<path d="M17.94 17.94L6.06 6.06"/><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>';
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use PHPMailer\PHPMailer\Exception;
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
require __DIR__ . '/../../composer/vendor/autoload.php';
|
||||
|
||||
$envFile = realpath(__DIR__ . '/../../config/.env.mail');
|
||||
|
||||
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.mail');
|
||||
|
||||
$dotenv->load();
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Dotenv error"
|
||||
]);
|
||||
}
|
||||
|
||||
function newMailer() {
|
||||
global $mailer;
|
||||
|
||||
if (isset($mailer) && $mailer instanceof PHPMailer) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$mailer = new PHPMailer(true);
|
||||
|
||||
$mailer->isSMTP();
|
||||
$mailer->CharSet = 'UTF-8';
|
||||
$mailer->Host = $_ENV['MAIL_SERVER'];
|
||||
$mailer->SMTPAuth = true;
|
||||
$mailer->Username = $_ENV['MAIL_USER'];
|
||||
$mailer->Password = $_ENV['MAIL_USER_PASSWORD'];
|
||||
|
||||
$port = (int)$_ENV['MAIL_PORT'];
|
||||
if ($port === 465) {
|
||||
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
|
||||
} else {
|
||||
$mailer->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
|
||||
$mailer->Port = 587;
|
||||
}
|
||||
|
||||
$mailer->Port = $port;
|
||||
|
||||
$mailer->setFrom($_ENV['MAIL_USER'], 'WKVS');
|
||||
|
||||
} catch (Exception $e) {
|
||||
throw new Exception("Konfigurationsfehler des Automailers: " . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
function sendMail(string $content = '', string $subject = '', array $recipients = []) {
|
||||
global $mailer;
|
||||
|
||||
if (empty($recipients)) {
|
||||
throw new Exception("Keine Empfänger angegeben");
|
||||
}
|
||||
|
||||
if (!isset($mailer) || !($mailer instanceof PHPMailer)) {
|
||||
try {
|
||||
newMailer();
|
||||
} catch (Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ($recipients as $email => $name) {
|
||||
$mailer->addAddress($email, $name);
|
||||
}
|
||||
|
||||
$mailer->isHTML(true);
|
||||
$mailer->Subject = $subject;
|
||||
$mailer->Body = $content;
|
||||
$mailer->AltBody = strip_tags($content);
|
||||
|
||||
if (!$mailer->send()) {
|
||||
throw new Exception("Sendefehler " . $mailer->ErrorInfo);
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (Exception $e) {
|
||||
error_log("Kritischer Sendefehler: " . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
@@ -0,0 +1,218 @@
|
||||
<?php
|
||||
|
||||
use Predis\Client as PredisClient;
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
require __DIR__ . '/../../composer/vendor/autoload.php';
|
||||
|
||||
$envFile = realpath(__DIR__ . '/../../config/.env.redis');
|
||||
|
||||
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.redis');
|
||||
|
||||
$dotenv->load();
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Dotenv error"
|
||||
]);
|
||||
}
|
||||
|
||||
// Create a Redis connection
|
||||
$redis = new PredisClient([
|
||||
'scheme' => 'tcp',
|
||||
'host' => $_ENV['REDDIS_HOST'],
|
||||
'port' => $_ENV['REDDIS_PORT'],
|
||||
'password' => $_ENV['REDDIS_PASSWORD']
|
||||
]);
|
||||
|
||||
/**
|
||||
* Token Bucket Rate Limiter
|
||||
*
|
||||
* A Redis-based token bucket rate limiter implementation using Lua scripts
|
||||
* for atomic operations.
|
||||
*
|
||||
* The token bucket algorithm allows requests at a controlled rate by maintaining
|
||||
* a bucket of tokens that refills over time. Each request consumes a token, and
|
||||
* requests are denied when the bucket is empty.
|
||||
*
|
||||
* Requires: predis/predis
|
||||
*/
|
||||
|
||||
/**
|
||||
* Token bucket rate limiter using Redis for distributed rate limiting.
|
||||
*
|
||||
* The token bucket maintains a fixed capacity of tokens that refill at a
|
||||
* constant rate. Each request consumes one token. When the bucket is empty,
|
||||
* requests are denied until tokens refill.
|
||||
*
|
||||
* Example:
|
||||
* $redis = new Predis\Client(['host' => '127.0.0.1', 'port' => 6379]);
|
||||
* $limiter = new TokenBucket(10, 1, 1.0, $redis);
|
||||
* $result = $limiter->allow('user:123');
|
||||
* if ($result['allowed']) {
|
||||
* echo "Request allowed. {$result['remaining']} tokens remaining.";
|
||||
* } else {
|
||||
* echo "Request denied. Rate limit exceeded.";
|
||||
* }
|
||||
*/
|
||||
class TokenBucket
|
||||
{
|
||||
/** @var string Lua script for atomic token bucket operations */
|
||||
private const LUA_SCRIPT = <<<'LUA'
|
||||
local key = KEYS[1]
|
||||
local capacity = tonumber(ARGV[1])
|
||||
local refill_rate = tonumber(ARGV[2])
|
||||
local refill_interval = tonumber(ARGV[3])
|
||||
local now = tonumber(ARGV[4])
|
||||
|
||||
-- Get current state or initialize
|
||||
local bucket = redis.call('HMGET', key, 'tokens', 'last_refill')
|
||||
local tokens = tonumber(bucket[1])
|
||||
local last_refill = tonumber(bucket[2])
|
||||
|
||||
-- Initialize if this is the first request
|
||||
if tokens == nil then
|
||||
tokens = capacity
|
||||
last_refill = now
|
||||
end
|
||||
|
||||
-- Calculate token refill
|
||||
local time_passed = now - last_refill
|
||||
local refills = math.floor(time_passed / refill_interval)
|
||||
|
||||
if refills > 0 then
|
||||
tokens = math.min(capacity, tokens + (refills * refill_rate))
|
||||
last_refill = last_refill + (refills * refill_interval)
|
||||
end
|
||||
|
||||
-- Try to consume a token
|
||||
local allowed = 0
|
||||
if tokens >= 1 then
|
||||
tokens = tokens - 1
|
||||
allowed = 1
|
||||
end
|
||||
|
||||
-- Update state
|
||||
redis.call('HSET', key, 'tokens', tokens, 'last_refill', last_refill)
|
||||
|
||||
-- Delete the key after one hour
|
||||
redis.call('EXPIRE', key, 3600)
|
||||
|
||||
-- Return result: allowed (1 or 0) and remaining tokens
|
||||
return {allowed, tokens}
|
||||
LUA;
|
||||
|
||||
/** @var PredisClient */
|
||||
private $redis;
|
||||
|
||||
/** @var int */
|
||||
private $capacity;
|
||||
|
||||
/** @var float */
|
||||
private $refillRate;
|
||||
|
||||
/** @var float */
|
||||
private $refillInterval;
|
||||
|
||||
/** @var string */
|
||||
private $scriptSha;
|
||||
|
||||
/** @var bool */
|
||||
private $scriptLoaded = false;
|
||||
|
||||
/**
|
||||
* Initialize the token bucket rate limiter.
|
||||
*
|
||||
* @param int $capacity Maximum number of tokens in the bucket (default: 10)
|
||||
* @param float $refillRate Number of tokens added per refill interval (default: 1.0)
|
||||
* @param float $refillInterval Time in seconds between refills (default: 1.0)
|
||||
* @param PredisClient|null $redis Predis client instance. If null, creates a default client.
|
||||
*/
|
||||
public function __construct(
|
||||
int $capacity = 10,
|
||||
float $refillRate = 1.0,
|
||||
float $refillInterval = 1.0,
|
||||
?PredisClient $redis = null
|
||||
) {
|
||||
$this->capacity = $capacity;
|
||||
$this->refillRate = $refillRate;
|
||||
$this->refillInterval = $refillInterval;
|
||||
$this->redis = $redis ?? new PredisClient([
|
||||
'host' => '127.0.0.1',
|
||||
'port' => 6379,
|
||||
]);
|
||||
$this->scriptSha = sha1(self::LUA_SCRIPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the Lua script is loaded into Redis.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function ensureScriptLoaded(): void
|
||||
{
|
||||
if (!$this->scriptLoaded) {
|
||||
try {
|
||||
$this->scriptSha = $this->redis->script('LOAD', self::LUA_SCRIPT);
|
||||
$this->scriptLoaded = true;
|
||||
} catch (\Exception $e) {
|
||||
// If loading fails, we'll fall back to EVAL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a request should be allowed for the given key.
|
||||
*
|
||||
* @param string $key The rate limit key (e.g., 'user:123', 'api:endpoint:xyz')
|
||||
*
|
||||
* @return array{allowed: bool, remaining: float} An associative array with:
|
||||
* - 'allowed': true if the request is allowed, false otherwise
|
||||
* - 'remaining': number of tokens remaining in the bucket
|
||||
*
|
||||
* Example:
|
||||
* $result = $limiter->allow('user:123');
|
||||
* echo "Allowed: " . ($result['allowed'] ? 'yes' : 'no');
|
||||
* echo "Remaining: {$result['remaining']}";
|
||||
*/
|
||||
public function allow(string $key): array
|
||||
{
|
||||
$this->ensureScriptLoaded();
|
||||
|
||||
$now = microtime(true);
|
||||
$args = [
|
||||
$this->capacity,
|
||||
$this->refillRate,
|
||||
$this->refillInterval,
|
||||
$now,
|
||||
];
|
||||
|
||||
try {
|
||||
// Try EVALSHA first (faster if script is cached)
|
||||
$result = $this->redis->evalsha($this->scriptSha, 1, $key, ...$args);
|
||||
} catch (\Exception $e) {
|
||||
// Script not in cache, use EVAL and reload
|
||||
$result = $this->redis->eval(self::LUA_SCRIPT, 1, $key, ...$args);
|
||||
$this->scriptLoaded = false;
|
||||
}
|
||||
|
||||
return [
|
||||
'allowed' => (bool) $result[0],
|
||||
'remaining' => (float) $result[1],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,22 +48,41 @@ function verify_csrf() {
|
||||
die("Access Denied: Invalid CSRF Token.");
|
||||
}
|
||||
} else {
|
||||
http_response_code(403);
|
||||
http_response_code(405);
|
||||
die("Access Denied: Invalid Request Type.");
|
||||
}
|
||||
}
|
||||
|
||||
function verify_delete_csrf($_DELETE) {
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'DELETE') {
|
||||
$token = $_DELETE['csrf_token'] ?? '';
|
||||
if (!hash_equals($_SESSION['csrf_token'], $token)) {
|
||||
http_response_code(403);
|
||||
die("Access Denied: Invalid CSRF Token.");
|
||||
}
|
||||
} else {
|
||||
http_response_code(405);
|
||||
die("Access Denied: Invalid Request Type.");
|
||||
}
|
||||
}
|
||||
|
||||
$allowedUserTypes = ['trainer', 'kampfrichter', 'wk_leitung'];
|
||||
|
||||
function check_user_permission(string $type, bool $return = false) {
|
||||
function check_user_permission(string $type, bool $return = false, bool $display = false) {
|
||||
global $allowedUserTypes;
|
||||
|
||||
if (!in_array($type, $allowedUserTypes, true)) {
|
||||
if ($return) {
|
||||
return false;
|
||||
} else {
|
||||
http_response_code(403);
|
||||
die("Invalid User Type Configuration");
|
||||
if ($display) {
|
||||
http_response_code(403);
|
||||
include __DIR__ . "/../www/error-pages/403.html";
|
||||
exit;
|
||||
} else {
|
||||
http_response_code(403);
|
||||
die("Invalid User Type Configuration");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +96,14 @@ function check_user_permission(string $type, bool $return = false) {
|
||||
if ($return) {
|
||||
return false;
|
||||
} else {
|
||||
http_response_code(403);
|
||||
die("Access Denied");
|
||||
if ($display) {
|
||||
http_response_code(403);
|
||||
include __DIR__ . "/../www/error-pages/403.html";
|
||||
exit;
|
||||
} else {
|
||||
http_response_code(403);
|
||||
die("Access Denied");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
<?php
|
||||
/**
|
||||
* Shared Sidebar Navigation
|
||||
*
|
||||
* Include this file after <body> on any intern page.
|
||||
* Set $currentPage before including, e.g.:
|
||||
* $currentPage = 'trainer';
|
||||
* require $baseDir . '/../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>',
|
||||
'rankLive' => '<svg viewBox="0 0 24 24"><path d="M12 4h6a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h6"/><line x1="9" y1="9" x2="15" y2="9"/><line x1="9" y1="13" x2="15" y2="13"/><line x1="9" y1="17" x2="15" y2="17"/></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['user_id_kampfrichter']);
|
||||
elseif ($currentPage === 'kampfrichter' && checkIfUserHasSessionId('trainer')):
|
||||
$userDispId = intval($_SESSION['user_id_trainer']);
|
||||
elseif ($isWKL && checkIfUserHasSessionId('wk_leitung')):
|
||||
$userDispId = intval($_SESSION['user_id_wk_leitung']);
|
||||
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' => 'rankLive', 'label' => 'Rank Live', 'url' => '/intern/wk-leitung/rank-live', 'freigaben' => false];
|
||||
$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['user_id_'.$type]) && intval(['user_id_'.$type]) > 0) { return true; }
|
||||
else { return false; }
|
||||
}
|
||||
|
||||
// if (!isset($indexedNotenNames)) { $indexedNotenNames = []; }
|
||||
|
||||
function sidebarRender(string $mode) {
|
||||
global $isWKL, $isTrainer, $isKampfrichter, $links, $currentPage, $icons, $renderMenu, $username, $freigabenSidebar, $indexedArrayGeraete;
|
||||
|
||||
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 = ($currentPage === 'kampfrichter') ? $_SESSION['selectedFreigabeIdKampfrichter'] : $_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="selectTriggerSidebar" aria-expanded="false">
|
||||
<span class="selectLabel">
|
||||
<?= htmlspecialchars(($currentPage === 'kampfrichter') ? (($selectedFreigabe !== 'A') ? $indexedArrayGeraete[$selectedFreigabe] ?? $selectedFreigabe : 'Admin') : $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="selectOptionsSidebar">
|
||||
<?php foreach ($freigabenSidebar[$freigbenArrayName] as $f) :?>
|
||||
<?php $selected = ($f === $selectedFreigabe) ? 'selected' : '' ?>
|
||||
<li data-value="<?= htmlspecialchars($f) ?>" class="<?= $selected ?>"><?= htmlspecialchars(($currentPage === 'kampfrichter') ? (($f !== 'A') ? $indexedArrayGeraete[$f] ?? $f : 'Admin') : $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>
|
||||
|
||||
window.CSRF_TOKEN = "<?= $csrf_token ?? $_SESSION['csrf_token'] ?? '' ?>";
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,10 +33,20 @@ class NotenRechner {
|
||||
|
||||
private function santinzeString(string $string) : string
|
||||
{
|
||||
$replacePattern = '/[^a-zA-Z0-9(){}+*\/.\-\[\]]/';
|
||||
$replacePatterns = [
|
||||
'/->R\w+/', // 1. Removes ->R followed by digits
|
||||
'/[^a-zA-Z0-9(){}+*\/.[\]\-]/' // 2. Fixed syntax: Allowed characters list
|
||||
];
|
||||
return preg_replace($replacePatterns,'', $string);
|
||||
}
|
||||
|
||||
private function sanitizeStringWithRun(string $string) : string
|
||||
{
|
||||
$replacePattern = '/[^a-zA-Z0-9(){}+*\/.\-\[\]>]/';
|
||||
return preg_replace($replacePattern, "", $string);
|
||||
}
|
||||
|
||||
|
||||
public function getBenoetigteIds(string $schemaRaw)
|
||||
{
|
||||
$schema = $this->santinzeString($schemaRaw);
|
||||
@@ -78,29 +88,67 @@ class NotenRechner {
|
||||
|
||||
}
|
||||
|
||||
|
||||
private function insertValues(string $schemaRaw, array $valuesArray = [])
|
||||
public function getBenoetigteIdsComplexWithRun(string $schemaRaw)
|
||||
{
|
||||
$schema = $this->santinzeString($schemaRaw);
|
||||
$schema = $this->sanitizeStringWithRun($schemaRaw);
|
||||
$indexedMatches = [];
|
||||
|
||||
$idsNeeded = $this->getBenoetigteIds($schemaRaw);
|
||||
$missingIds = array_diff($idsNeeded, array_keys($valuesArray));
|
||||
|
||||
if (!empty($missingIds)) {
|
||||
return ['success' => false, 'value' => 'Fehlende IDs'];
|
||||
}
|
||||
|
||||
try {
|
||||
$returnStr = preg_replace_callback('/\{(\d+)\}/', function($m) use ($valuesArray) {
|
||||
return $valuesArray[$m[1]];
|
||||
}, $schema);
|
||||
return ['success' => true, 'value' => $returnStr];
|
||||
} catch (\Exception $e) {
|
||||
return ['success' => false, 'value' => 'Problem beim Einsetzen der Werte'];
|
||||
// Pattern breakdown:
|
||||
// \{(\d+) -> Match { and capture the first number (Note ID)
|
||||
// (?:\[(\w*)\])? -> OPTIONALLY match [ and capture alphanumeric content inside (Apparatus ID)
|
||||
// (?:\[(\d+)\])? -> OPTIONALLY match [ and capture number inside (Run Number)
|
||||
// \} -> Match the closing }
|
||||
if (preg_match_all('/\{(\d+)(?:\[(\w*)\])?(?:\[(\d+)\])?\}/', $schema, $matches, PREG_SET_ORDER)) {
|
||||
|
||||
foreach ($matches as $match) {
|
||||
$noteId = $match[1];
|
||||
|
||||
$rawGeraet = $match[2] ?? 'S';
|
||||
$geraetId = ($rawGeraet === 'S' || $rawGeraet === '') ? 'A' : $rawGeraet;
|
||||
|
||||
$runNumber = isset($match[3]) ? (int)$match[3] : 1;
|
||||
|
||||
$indexedMatches[] = [
|
||||
'noteId' => $noteId,
|
||||
'geraetId' => $geraetId,
|
||||
'run' => $runNumber
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$arrayRes = $this->getStoreGeraetRun($schemaRaw);
|
||||
|
||||
$indexedMatches['targetRun'] = $arrayRes['run_num'] ?? 'A';
|
||||
$indexedMatches['targetGeraet'] = $arrayRes['geraet_id'] ?? 'A';
|
||||
|
||||
return $indexedMatches;
|
||||
|
||||
}
|
||||
|
||||
private function insertValuesComplex(string $schemaRaw, array $valuesArray, int $currentId, int $runNumber)
|
||||
public function getStoreGeraetRun(string $schemaRaw): array
|
||||
{
|
||||
$schema = $this->sanitizeStringWithRun($schemaRaw);
|
||||
|
||||
$pattern = '/->R(?<run_num>\d+|S)(?:G(?<geraet_id>\d+|S))?/';
|
||||
|
||||
if (preg_match($pattern, $schema, $matchesTagetRun)) {
|
||||
|
||||
$run = $matchesTagetRun['run_num'] ?? 'S';
|
||||
$geraet = $matchesTagetRun['geraet_id'] ?? 'S';
|
||||
|
||||
return [
|
||||
'run_num' => $run === 'S' ? 'A' : (int)$run,
|
||||
'geraet_id' => $geraet === 'S' ? 'A' : (int)$geraet,
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
'run_num' => 'A',
|
||||
'geraet_id' => 'A'
|
||||
];
|
||||
}
|
||||
|
||||
private function insertValuesComplex(string $schemaRaw, array $valuesArray, int $currentId, int $runNumber, bool $avr = false)
|
||||
{
|
||||
$schema = $this->santinzeString($schemaRaw);
|
||||
$idsNeededArray = $this->getBenoetigteIdsComplex($schemaRaw);
|
||||
@@ -110,22 +158,26 @@ class NotenRechner {
|
||||
$noteId = $sina['noteId'];
|
||||
$geraetIdSearch = ($sina['geraetId'] === 'A') ? $currentId : $sina['geraetId'];
|
||||
|
||||
if (!isset($valuesArray[$geraetIdSearch][$noteId][$runNumber])) {
|
||||
if (!isset($valuesArray[$geraetIdSearch][$noteId][$runNumber]["value"])) {
|
||||
return ['success' => false, 'value' => "Fehlende Daten für Gerät $geraetIdSearch, Note $noteId, Lauf $runNumber"];
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$returnStr = preg_replace_callback('/\{(\d+)(?:\[(\w*)\])?(?:\[(\d+)\])?\}/', function($m) use ($valuesArray, $currentId, $runNumber) {
|
||||
$returnStr = preg_replace_callback('/\{(\d+)(?:\[(\w*)\])?(?:\[(\d+)\])?\}/', function($m) use ($valuesArray, $currentId, $runNumber, $avr) {
|
||||
$noteId = $m[1];
|
||||
|
||||
// Get value inside brackets, default to 'S' if none exists
|
||||
$rawGeraet = $m[2] ?? 'S';
|
||||
$geraetId = ($rawGeraet === 'S' || $rawGeraet === '') ? $currentId : $rawGeraet;
|
||||
|
||||
// Return value from [Device][Note][Run]
|
||||
return $valuesArray[$geraetId][$noteId][$runNumber] ?? 0;
|
||||
|
||||
if ($avr && $valuesArray[$geraetId][$noteId][$runNumber]["type"] === 'default_value') {
|
||||
return 'default_value_skip';
|
||||
} else {
|
||||
// Return value from [Device][Note][Run]
|
||||
return $valuesArray[$geraetId][$noteId][$runNumber]["value"] ?? 0;
|
||||
}
|
||||
|
||||
}, $schema);
|
||||
|
||||
return ['success' => true, 'value' => $returnStr];
|
||||
@@ -144,27 +196,15 @@ class NotenRechner {
|
||||
$result = $this->rechner->calculate($rechnung);
|
||||
return ['success' => true, 'value' => floatval($result)];
|
||||
} catch (\ChrisKonnertz\StringCalc\Exceptions\StringCalcException $e) {
|
||||
return ['success' => false, 'value' => 'Problem bei der Berechnung: Ungültige Syntax'];
|
||||
return ['success' => false, 'value' => 'Problem bei der Berechnung: Ungültige Syntax '. $rechnung];
|
||||
} catch (\Exception $e) {
|
||||
return ['success' => false, 'value' => 'Problem bei der Berechnung'];
|
||||
}
|
||||
}
|
||||
|
||||
public function berechneString(string $schemaRaw, array $valuesArray = []) {
|
||||
public function berechneStringComplex(string $schemaRaw, array $valuesArray = [], int $geraetId = -1, int $run_number = 0) {
|
||||
if ($schemaRaw === '') { return ['success' => false, 'value' => 'Leeres Schema']; }
|
||||
|
||||
$rechnungArray = $this->insertValues($schemaRaw, $valuesArray);
|
||||
|
||||
if (!isset($rechnungArray['success']) || !isset($rechnungArray['value']) || !$rechnungArray['success']) {
|
||||
return ['success' => false, 'value' => $rechnungArray['value'] ?? 'Fehler beim Einsetzen der Werte oder Werte fehlen'];
|
||||
}
|
||||
|
||||
return $this->calculate($rechnungArray['value']);
|
||||
}
|
||||
|
||||
public function berechneStringComplex(string $schemaRaw, array $valuesArray = [], int $geraetId = 0, int $run_number = 0) {
|
||||
if ($schemaRaw === '') { return ['success' => false, 'value' => 'Leeres Schema']; }
|
||||
if ($geraetId === 0) { return ['success' => false, 'value' => 'Keine Geraet Id angegeben.']; }
|
||||
if ($geraetId < 0) { return ['success' => false, 'value' => 'Keine Geraet Id angegeben.']; }
|
||||
if ($run_number === 0) { return ['success' => false, 'value' => 'Keine Run_Number angegeben.']; }
|
||||
|
||||
$rechnungArray = $this->insertValuesComplex($schemaRaw, $valuesArray, $geraetId, $run_number);
|
||||
@@ -176,9 +216,9 @@ class NotenRechner {
|
||||
return $this->calculate($rechnungArray['value']);
|
||||
}
|
||||
|
||||
public function berechneStringComplexRun(string $schemaRaw, array $valuesArray = [], int $geraetId = 0, int $programm = 0, array $arrayRuns = []) {
|
||||
public function berechneStringComplexRun(string $schemaRaw, array $valuesArray = [], int $geraetId = -1, int $programm = 0, array $arrayRuns = []) {
|
||||
if ($schemaRaw === '') { return ['success' => false, 'value' => 'Leeres Schema']; }
|
||||
if ($geraetId === 0) { return ['success' => false, 'value' => 'Keine Geraet Id angegeben.']; }
|
||||
if ($geraetId < 0) { return ['success' => false, 'value' => 'Keine Geraet Id angegeben.']; }
|
||||
if ($programm === 0) { return ['success' => false, 'value' => 'Kein Programm angegeben.']; }
|
||||
if ($arrayRuns === []) { return ['success' => false, 'value' => 'Leeres Array Runs Noten.']; }
|
||||
|
||||
@@ -213,9 +253,7 @@ class NotenRechner {
|
||||
|
||||
foreach ($ids as $sid) {
|
||||
$geraetId = ($sid['geraetId'] === 'A') ? $currentId : $sid['geraetId'];
|
||||
$runCountN = $arrayRuns[$sid['noteId']][$geraetId][$programm] ?? $arrayRuns["default"] ?? 1;
|
||||
|
||||
//var_dump($arrayRuns[$sid['noteId']][$geraetId][$programm]);
|
||||
$runCountN = $arrayRuns[$sid['noteId']][$geraetId][$programm] ?? $arrayRuns[$sid['noteId']][$geraetId]["all"] ?? $arrayRuns["default"] ?? 1;
|
||||
|
||||
if ($runCount !== $runCountN && $runCount !== 0) { return; }
|
||||
$runCount = $runCountN;
|
||||
@@ -225,21 +263,26 @@ class NotenRechner {
|
||||
switch ($name) {
|
||||
case "AVGR":
|
||||
case "SUMR":
|
||||
$nulls = 0;
|
||||
|
||||
for ($r = 1; $r <= $runCount; $r++) {
|
||||
|
||||
$res = $this->insertValuesComplex($content, $valuesArray, $currentId, $r);
|
||||
|
||||
// FIXED: Only bail if success is false
|
||||
$res = $this->insertValuesComplex($content, $valuesArray, $currentId, $r, true);
|
||||
|
||||
if (!$res['success']) {
|
||||
return "0"; // Or handle error as needed
|
||||
return "0";
|
||||
} elseif ($res['value'] === 'default_value_skip') {
|
||||
$nulls++;
|
||||
} else {
|
||||
$parts[] = "(" . $res['value'] . ")";
|
||||
}
|
||||
$parts[] = "(" . $res['value'] . ")";
|
||||
}
|
||||
|
||||
$innerMath = implode(" + ", $parts);
|
||||
$string = ($name === "AVGR") ? "(($innerMath) / $runCount)" : "($innerMath)";
|
||||
$div_count = $runCount - $nulls;
|
||||
if ($div_count === 0 || count($parts) < 1) return "0";
|
||||
$string = ($name === "AVGR") ? "(($innerMath) / $div_count)" : "($innerMath)";
|
||||
|
||||
//var_dump($string);
|
||||
break;
|
||||
|
||||
case "MAXR":
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
<?php
|
||||
|
||||
require $baseDir . '/../composer/vendor/autoload.php';
|
||||
|
||||
use Shuchkin\SimpleXLSX;
|
||||
|
||||
if (isset($_POST['apply_bulk_action']) ) {
|
||||
if (isset($_POST['apply_bulk_action'])) {
|
||||
verify_csrf();
|
||||
if ( empty($_POST['turnerin_ids']) || !is_array($_POST['turnerin_ids']) ) {
|
||||
$_SESSION['form_message'] = 'Keine Turnerinnen für die Aktion ausgewählt.';
|
||||
if (empty($_POST['turnerin_ids']) || !is_array($_POST['turnerin_ids'])) {
|
||||
$_SESSION['form_message'] = 'Keine ' . $personMehrzahl . ' für die Aktion ausgewählt.';
|
||||
$_SESSION['form_message_type'] = 0;
|
||||
} elseif (!isset($_POST['bulk_action_programm']) && !isset($_POST['bulk_action_bezahlt'])) {
|
||||
$_SESSION['form_message'] = 'Kein Programm für die Massenänderung ausgewählt.';
|
||||
@@ -36,7 +32,7 @@ if (isset($_POST['apply_bulk_action']) ) {
|
||||
|
||||
if (in_array($bezahlt_update, ['0', '3', '4', '5'], true)) {
|
||||
$set_clauses[] = 'bezahltoverride = ?';
|
||||
$params[] = (int)$bezahlt_update;
|
||||
$params[] = (int) $bezahlt_update;
|
||||
$types .= 'i';
|
||||
}
|
||||
|
||||
@@ -53,7 +49,7 @@ if (isset($_POST['apply_bulk_action']) ) {
|
||||
|
||||
/* WHERE id IN (?, ?, ...) */
|
||||
$placeholders = implode(',', array_fill(0, count($ids_to_update), '?'));
|
||||
$sql = "UPDATE $tableTurnerinnen SET " . implode(', ', $set_clauses) . " WHERE id IN ($placeholders)";
|
||||
$sql = "UPDATE $tableTeilnehmende SET " . implode(', ', $set_clauses) . " WHERE id IN ($placeholders)";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
@@ -86,17 +82,17 @@ if (isset($_POST['apply_bulk_action']) ) {
|
||||
}
|
||||
|
||||
header('Location: ' . $_SERVER['REQUEST_URI']);
|
||||
exit;
|
||||
exit;
|
||||
}
|
||||
|
||||
if (isset($_POST['delete_id'])) {
|
||||
verify_csrf();
|
||||
$delete_id = intval($_POST['delete_id']);
|
||||
|
||||
$stmt = $mysqli->prepare("DELETE FROM $tableTurnerinnen where id = ?");
|
||||
$stmt = $mysqli->prepare("DELETE FROM $tableTeilnehmendee where id = ?");
|
||||
|
||||
$stmt->bind_param('i', $delete_id);
|
||||
|
||||
|
||||
if ($stmt->execute()) {
|
||||
$_SESSION['form_message'] = 'Eintrag erfolgreich gelöscht.';
|
||||
$_SESSION['form_message_type'] = 1;
|
||||
@@ -105,211 +101,80 @@ if (isset($_POST['delete_id'])) {
|
||||
$_SESSION['form_message_type'] = 0;
|
||||
}
|
||||
|
||||
header("Location: ". $_SERVER['REQUEST_URI']);
|
||||
header("Location: " . $_SERVER['REQUEST_URI']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['xlsx_file'])) {
|
||||
verify_csrf();
|
||||
|
||||
if ($_FILES['xlsx_file']['error'] === UPLOAD_ERR_OK) {
|
||||
|
||||
$tmpName = $_FILES['xlsx_file']['tmp_name'];
|
||||
|
||||
if (class_exists('Shuchkin\\SimpleXLSX') && $xlsx = SimpleXLSX::parse($tmpName)) {
|
||||
|
||||
$rows = $xlsx->rows();
|
||||
|
||||
$vereine_rows = db_select($mysqli, $tableVereine, 'verein', '', [], 'verein ASC');
|
||||
$vereine = array_column($vereine_rows, 'verein');
|
||||
|
||||
if (count($rows) < 2) {
|
||||
$excelMessage = '❌ Excel must have headers and at least one data row.';
|
||||
} else {
|
||||
$headers = array_map('trim', $rows[0]);
|
||||
unset($rows[0]);
|
||||
|
||||
$columnMap = [
|
||||
'Nachname' => 'name',
|
||||
'Vorname' => 'vorname',
|
||||
'Geburtsdatum' => 'geburtsdatum',
|
||||
'Programm' => 'programm'
|
||||
];
|
||||
|
||||
|
||||
if ($selectedverein === 'admin') {
|
||||
$columnMap['Verein'] = 'verein';
|
||||
}
|
||||
|
||||
|
||||
$columnIndexes = [];
|
||||
foreach ($columnMap as $excelHeader => $dbColumn) {
|
||||
$index = array_search($excelHeader, $headers);
|
||||
if ($index === false) {
|
||||
$excelMessage = "❌ Column '$excelHeader' not found in Excel.";
|
||||
break;
|
||||
}
|
||||
$columnIndexes[$dbColumn] = $index;
|
||||
}
|
||||
|
||||
if (empty($excelMessage)) {
|
||||
$inserted = 0;
|
||||
|
||||
foreach ($rows as $row) {
|
||||
if (!array_filter($row)) continue;
|
||||
|
||||
$data = [];
|
||||
foreach ($columnIndexes as $dbCol => $i) {
|
||||
$data[$dbCol] = isset($row[$i]) ? trim($row[$i]) : null;
|
||||
}
|
||||
|
||||
if ($selectedverein !== 'admin'){
|
||||
$data['verein'] = $selectedverein;
|
||||
} else {
|
||||
|
||||
if (!in_array($data['verein'], $vereine, true)) {
|
||||
$excelMessage = "❌ admin: {$data['verein']} not valid";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$raw = trim($data['geburtsdatum']);
|
||||
|
||||
// Try DD.MM.YYYY first
|
||||
$temp = DateTime::createFromFormat('d.m.Y', $raw);
|
||||
|
||||
if ($temp && $temp->format('d.m.Y') === $raw) {
|
||||
$data['geburtsdatum'] = $temp->format('Y-m-d');
|
||||
} else {
|
||||
// Fallback: if it's already YYYY-MM-DD or YYYY-MM-DD HH:MM:SS
|
||||
$data['geburtsdatum'] = substr($raw, 0, 10); // take first 10 chars
|
||||
}
|
||||
|
||||
|
||||
if (!(in_array($data['programm'], $programmes)) && is_array($programmes)){
|
||||
$_SESSION['form_message'] = "❌ Programm '{$data['programm']}' nicht valide bei Turnerin ".$data['name']." ".$data['vorname'].". Alle Turnereinnen nach ".$data['name']." ".$data['vorname']." wurden nicht geladen.";
|
||||
$_SESSION['form_message_type'] = 0;
|
||||
header('Location: '. $_SERVER['REQUEST_URI']); // Redirect to same page
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!empty($tableTurnerinnen)) {
|
||||
$columns = array_keys($data);
|
||||
|
||||
$set = implode(
|
||||
', ',
|
||||
array_map(fn($col) => "$col = ?", $columns)
|
||||
);
|
||||
|
||||
$sql = "INSERT INTO $tableTurnerinnen SET $set";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
$types = str_repeat('s', count($data));
|
||||
$values = array_values($data);
|
||||
|
||||
$stmt->bind_param($types, ...$values);
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
echo 'DB error: ' . $stmt->error;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$inserted++;
|
||||
}
|
||||
}
|
||||
|
||||
$_SESSION['form_message'] = "✅ Erfolgreich $inserted Turnerinnen via Excel geladen.";
|
||||
$_SESSION['form_message_type'] = 1;
|
||||
header("Location: ". $_SERVER['REQUEST_URI']); // Redirect to same page
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$parseError = SimpleXLSX::parseError();
|
||||
$excelMessage = '❌ Failed to parse Excel file: ' . $parseError;
|
||||
}
|
||||
|
||||
} else {
|
||||
$excelMessage = '❌ File upload error.';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$edit_row = null;
|
||||
if ($access_granted_trainer && isset($_GET['edit_id']) && is_numeric($_GET['edit_id']) && !isset($_POST['submit_turnerinnen_form'])) {
|
||||
$edit_id = intval($_GET['edit_id']);
|
||||
$edit_rows = db_select($mysqli, $tableTurnerinnen, "*", 'id = ?', [$edit_id]);
|
||||
if (!isset($edit_rows) || !is_array($edit_rows) || count($edit_rows) !== 1){http_response_code(422); exit;}
|
||||
$edit_rows = db_select($mysqli, $tableTeilnehmende, "*", 'id = ?', [$edit_id]);
|
||||
if (!isset($edit_rows) || !is_array($edit_rows) || count($edit_rows) !== 1) {
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
$edit_row = $edit_rows[0];
|
||||
if ($edit_row && ($edit_row['verein'] === $selectedverein || $selectedverein === 'admin')) {
|
||||
if ($edit_row && ($edit_row['verein'] === $selectedverein || $isAdmin)) {
|
||||
$_POST['nachname'] = $edit_row['name'] ?? '';
|
||||
$_POST['vorname'] = $edit_row['vorname'] ?? '';
|
||||
$_POST['geburtsdatum'] = $edit_row['geburtsdatum'] ?? '';
|
||||
$_POST['programm'] = $edit_row['programm'] ?? '';
|
||||
$_POST['edit_id'] = $edit_id;
|
||||
if ($selectedverein === 'admin'){
|
||||
if ($isAdmin) {
|
||||
$_POST['verein'] = $edit_row['verein'] ?? '';
|
||||
if (intval($edit_row['bezahltoverride']) !== 0) {
|
||||
$_POST['bezahltoverride'] = $edit_row['bezahltoverride'] ?? '';
|
||||
} else {
|
||||
$_POST['bezahltoverride'] = $edit_row['bezahlt'] ?? '';
|
||||
}
|
||||
$_POST['bezahltOverride'] = $edit_row['bezahltoverride'] ?? 0;
|
||||
}
|
||||
} else {
|
||||
$_SESSION['form_message'] = 'Ungültiger Eintrag zum Bearbeiten.';
|
||||
$_SESSION['form_message_type'] = 0;
|
||||
header('Location: '. $_SERVER['REQUEST_URI']);
|
||||
header('Location: ' . $_SERVER['REQUEST_URI']);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// === INSERT/UPDATE Handler ===
|
||||
if ( $access_granted_trainer && isset($_POST['submit_turnerinnen_form']) ) {
|
||||
// Check nonce
|
||||
if ($access_granted_trainer && isset($_POST['submit_turnerinnen_form'])) {
|
||||
|
||||
verify_csrf();
|
||||
$name = htmlspecialchars( $_POST['nachname'] );
|
||||
$vorname = htmlspecialchars( $_POST['vorname'] );
|
||||
$geburtsdatum = trim($_POST['geburtsdatum'] );
|
||||
$programm = htmlspecialchars( $_POST['programm'] );
|
||||
if ($selectedverein !== 'admin'){
|
||||
$verein = $selectedverein;
|
||||
} else {$verein = htmlspecialchars( $_POST['verein'] ); $bezahlt = htmlspecialchars( $_POST['bezahlt'] ); }
|
||||
if ( empty($name) || empty($vorname) || empty($geburtsdatum) || empty($programm)) {
|
||||
|
||||
$name = htmlspecialchars($_POST['nachname']);
|
||||
$vorname = htmlspecialchars($_POST['vorname']);
|
||||
$geburtsdatum = trim($_POST['geburtsdatum']);
|
||||
$programm = htmlspecialchars($_POST['programm']);
|
||||
|
||||
if (!$isAdmin) {
|
||||
$verein = $selectedverein;
|
||||
} else {
|
||||
$verein = htmlspecialchars($_POST['verein']);
|
||||
$bezahlt = intval($_POST['bezahltOverride']);
|
||||
}
|
||||
|
||||
if (empty($name) || empty($vorname) || empty($geburtsdatum) || empty($programm)) {
|
||||
$_SESSION['form_message'] = 'Bitte füllen Sie alle erforderlichen Felder aus.';
|
||||
$_SESSION['form_message_type'] = 0;
|
||||
} else {
|
||||
|
||||
$data_to_insert = [];
|
||||
|
||||
$data_to_insert = array(
|
||||
'name' => $name,
|
||||
'vorname' => $vorname,
|
||||
$data_to_insert = [
|
||||
'name' => $name,
|
||||
'vorname' => $vorname,
|
||||
'geburtsdatum' => $geburtsdatum,
|
||||
'programm' => $programm,
|
||||
'verein' => $verein,
|
||||
);
|
||||
|
||||
'verein' => $verein,
|
||||
];
|
||||
|
||||
$data_formats = array('%s', '%s', '%s', '%s', '%s');
|
||||
|
||||
if ($selectedverein === 'admin') {
|
||||
if ($isAdmin) {
|
||||
$data_to_insert['bezahltoverride'] = $bezahlt;
|
||||
$data_formats[] = '%d';
|
||||
}
|
||||
|
||||
print_r($data_to_insert);
|
||||
|
||||
|
||||
// Check if we are editing an existing entry
|
||||
$is_editing = isset($_POST['edit_id']) && is_numeric($_POST['edit_id']) && $_POST['edit_id'] > 0;
|
||||
|
||||
|
||||
if ($is_editing) {
|
||||
$edit_id = intval($_POST['edit_id']);
|
||||
|
||||
$entries = db_select($mysqli, $tableTurnerinnen, '*', 'id = ?', [$edit_id], 'rang ASC');
|
||||
$entries = db_select($mysqli, $tableTeilnehmende, '*', 'id = ?', [$edit_id], 'rang ASC');
|
||||
|
||||
$entry = $entries[0]; // since you're fetching by ID, this should return exactly one row
|
||||
|
||||
@@ -320,7 +185,7 @@ if ( $access_granted_trainer && isset($_POST['submit_turnerinnen_form']) ) {
|
||||
array_map(fn($col) => "$col = ?", $columns)
|
||||
);
|
||||
|
||||
$sql = "UPDATE $tableTurnerinnen SET $set WHERE id = ?";
|
||||
$sql = "UPDATE $tableTeilnehmende SET $set WHERE id = ?";
|
||||
|
||||
var_dump($sql);
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
@@ -337,13 +202,13 @@ if ( $access_granted_trainer && isset($_POST['submit_turnerinnen_form']) ) {
|
||||
|
||||
if ($updated === false) {
|
||||
error_log('DB Update Error: ' . $wpdb->last_error);
|
||||
$_SESSION['form_message'] = 'Fehler beim Aktualisieren des Eintrags.';
|
||||
$_SESSION['form_message'] = 'Fehler beim Aktualisieren der Personendaten.';
|
||||
$_SESSION['form_message_type'] = 0;
|
||||
} else if ($updated === 0) {
|
||||
$_SESSION['form_message'] = 'Keine Änderungen vorgenommen.';
|
||||
$_SESSION['form_message_type'] = 0;
|
||||
} else {
|
||||
$_SESSION['form_message'] = 'Eintrag erfolgreich aktualisiert!';
|
||||
$_SESSION['form_message'] = $personEinzahl . ' erfolgreich aktualisiert!';
|
||||
$_SESSION['form_message_type'] = 1;
|
||||
$_POST = [];
|
||||
header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
@@ -358,11 +223,11 @@ if ( $access_granted_trainer && isset($_POST['submit_turnerinnen_form']) ) {
|
||||
array_map(fn($col) => "$col = ?", $columns)
|
||||
);
|
||||
|
||||
$sql = "INSERT INTO $tableTurnerinnen SET $set";
|
||||
$sql = "INSERT INTO $tableTeilnehmende SET $set";
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
$types = str_repeat('s', count($data_to_insert));
|
||||
$types = str_repeat('s', count($data_to_insert));
|
||||
$values = array_values($data_to_insert);
|
||||
|
||||
$stmt->bind_param($types, ...$values);
|
||||
@@ -372,7 +237,7 @@ if ( $access_granted_trainer && isset($_POST['submit_turnerinnen_form']) ) {
|
||||
$stmt->close();
|
||||
|
||||
|
||||
if ( $inserted ) {
|
||||
if ($inserted) {
|
||||
$_SESSION['form_message'] = 'Daten erfolgreich gespeichert!';
|
||||
$_SESSION['form_message_type'] = 1;
|
||||
header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?'));
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
<?php
|
||||
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
use Dotenv\Dotenv;
|
||||
|
||||
$wsPermissions = [
|
||||
'displaycontrol' => ['access_granted_wk_leitung'],
|
||||
@@ -11,16 +20,13 @@ $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require_once __DIR__ . '/../redis/connect-to-redis.php';
|
||||
|
||||
$redisSaveTime = 100;
|
||||
$redis = null;
|
||||
|
||||
connectToRedis();
|
||||
|
||||
function checkWSTokenPermissions($RPerm) {
|
||||
switch ($RPerm) {
|
||||
case 'displaycontrol':
|
||||
return $_SESSION['access_granted_wk_leitung'] ?? false;
|
||||
case 'einstellungen':
|
||||
case 'wk_leitung':
|
||||
return $_SESSION['access_granted_wk_leitung'] ?? false;
|
||||
case 'kampfrichter';
|
||||
return $_SESSION['access_granted_kampfrichter'] ?? false;
|
||||
@@ -29,22 +35,56 @@ function checkWSTokenPermissions($RPerm) {
|
||||
}
|
||||
}
|
||||
|
||||
function generateWSToken($wsRequestedPermission) {
|
||||
|
||||
global $redis;
|
||||
$envFile = realpath(__DIR__ . '/../../config/.env.wk-id');
|
||||
|
||||
if (!checkWSTokenPermissions($wsRequestedPermission)) return null;
|
||||
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.wk-id');
|
||||
|
||||
$dotenv->load();
|
||||
} catch (Throwable $e) {
|
||||
http_response_code(500);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => "Dotenv error"
|
||||
]);
|
||||
}
|
||||
|
||||
$wkId = $_ENV['WETTKAMPF_ID'];
|
||||
|
||||
$allowedWkLeitungAccess = ['displaycontrol', 'einstellungen'];
|
||||
|
||||
function generateWSAdminToken($wsRequestedAcesstype, $wsRequestedAccess) {
|
||||
|
||||
global $redis, $wkId, $allowedWkLeitungAccess;
|
||||
|
||||
if (!checkWSTokenPermissions($wsRequestedAcesstype)) return null;
|
||||
|
||||
$wsGrantedPermission = [];
|
||||
|
||||
if ($wsRequestedPermission === 'kampfrichter') {
|
||||
if (!isset($_SESSION['selectedFreigabeKampfrichter'])) return null;
|
||||
if ($wsRequestedAcesstype === 'kampfrichter' && isset($_SESSION['selectedFreigabeIdKampfrichter'])) {
|
||||
$wsGrantedPermission['type'] = 'kampfrichter';
|
||||
$wsGrantedPermission['access'] = $_SESSION['selectedFreigabeKampfrichter'];
|
||||
$wsGrantedPermission['access'] = $_SESSION['selectedFreigabeIdKampfrichter'];
|
||||
} elseif ($wsRequestedAcesstype === 'wk_leitung' && in_array($wsRequestedAccess, $allowedWkLeitungAccess)) {
|
||||
$wsGrantedPermission['type'] = $wsRequestedAcesstype;
|
||||
$wsGrantedPermission['access'] = $wsRequestedAccess;
|
||||
} else {
|
||||
$wsGrantedPermission['type'] = $wsRequestedPermission;
|
||||
return null;
|
||||
}
|
||||
|
||||
$wsGrantedPermission['wk_id'] = $wkId;
|
||||
$wsGrantedPermission['authenticated'] = true;
|
||||
|
||||
$token = bin2hex(random_bytes(32));
|
||||
$key = "ws:token:" . $token;
|
||||
|
||||
@@ -52,5 +92,32 @@ function generateWSToken($wsRequestedPermission) {
|
||||
|
||||
$_SESSION['WS_KEY'] = $key;
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
$allowedReadTypes = ['display', 'audio', 'rankLive'];
|
||||
|
||||
function generateWSReadToken($wsRequestedAcesstype, $wsRequestedAccess) {
|
||||
|
||||
global $redis, $wkId, $allowedReadTypes;
|
||||
|
||||
$wsGrantedPermission = [];
|
||||
|
||||
if (!in_array($wsRequestedAcesstype, $allowedReadTypes)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$wsGrantedPermission['access'] = $wsRequestedAccess;
|
||||
$wsGrantedPermission['type'] = $wsRequestedAcesstype;
|
||||
$wsGrantedPermission['wk_id'] = $wkId;
|
||||
$wsGrantedPermission['authenticated'] = false;
|
||||
|
||||
$token = bin2hex(random_bytes(16));
|
||||
$key = "ws:token:" . $token;
|
||||
|
||||
$success = $redis->set($key, json_encode($wsGrantedPermission), ['nx', 'ex' => 30]);
|
||||
|
||||
$_SESSION['WS_KEY'] = $key;
|
||||
|
||||
return $key;
|
||||
}
|
||||
Reference in New Issue
Block a user