New Filestructure for Docker
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
upload_max_filesize = 50M
|
||||
post_max_size = 55M
|
||||
max_execution_time = 120
|
||||
max_input_time = 120
|
||||
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$allowedTypes = [
|
||||
'wkName',
|
||||
'displayCTextLogo',
|
||||
'displayCTextWKName',
|
||||
'displayColourLogo',
|
||||
'displayTextColourLogo',
|
||||
'displayColorScoringBg',
|
||||
'displayColorScoringBgSoft',
|
||||
'displayColorScoringShadowColor',
|
||||
'displayColorScoringBorderColor',
|
||||
'displayColorScoringPanel',
|
||||
'displayColorScoringPanelSoft',
|
||||
'displayColorScoringPanelText',
|
||||
'displayColorScoringPanelTextSoft',
|
||||
'displayColorScoringPanelTextNoteL',
|
||||
'displayColorScoringPanelTextNoteR',
|
||||
'displayIdNoteL',
|
||||
'displayIdNoteR',
|
||||
'rechnungenName',
|
||||
'rechnungenVorname',
|
||||
'rechnungenStrasse',
|
||||
'rechnungenHausnummer',
|
||||
'rechnungenPostleitzahl',
|
||||
'rechnungenOrt',
|
||||
'rechnungenIBAN',
|
||||
'maxLengthMusic',
|
||||
'linkWebseite',
|
||||
'rangNote',
|
||||
'orderBestRang',
|
||||
'rechnungenPostversand',
|
||||
'rechnungenPostversandKosten',
|
||||
'personEinzahl',
|
||||
'personMehrzahl',
|
||||
'rankLivePublic',
|
||||
'riegeneinteilungPublic'
|
||||
];
|
||||
|
||||
$type = $_POST['type'] ? trim($_POST['type']) : '';
|
||||
|
||||
if (!in_array($type, $allowedTypes)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid input']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$value = $_POST['value'] ? trim($_POST['value']) : null;
|
||||
|
||||
// ---------- Step 2: Get values from DB ----------
|
||||
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
|
||||
if (!$stmt) {
|
||||
echo json_encode(['success' => false, 'message' => 'Critical db error']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->bind_param("ss", $type, $value);
|
||||
$success = $stmt->execute();
|
||||
$stmt->close();
|
||||
|
||||
if (!$success) {
|
||||
echo json_encode(['success' => false, 'message' => 'Insert failed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Return JSON
|
||||
echo json_encode([
|
||||
'success' => true
|
||||
]);
|
||||
exit;
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$type = 'wkl';
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/cache/cache-creators/regenerate-display-dependencies-cache.php';
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add') {
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$start_index = intval($_POST['start_index'] ?? 0);
|
||||
$color = trim($_POST['color'] ?? '#424242');
|
||||
$audiofile = intval($_POST['audiofile'] ?? 0);
|
||||
$audiofile_max_duration = (int) $_POST['audiofileMaxDuration'] ?? 0;
|
||||
|
||||
if ($name === '') {
|
||||
echo json_encode(['success' => false, 'message' => 'Name ist erforderlich.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $db_tabelle_disziplinen (`name`, `start_index`, `color_kampfrichter`, `audiofile`, `audiofile_max_duration`) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param("sisii", $name, $start_index, $color, $audiofile, $audiofile_max_duration);
|
||||
$success = $stmt->execute();
|
||||
$new_id = $mysqli->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
if ($success) {
|
||||
echo json_encode(['success' => true, 'id' => $new_id]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler beim Hinzufügen.']);
|
||||
}
|
||||
|
||||
generateIntersectCache($mysqli, $baseDir);
|
||||
|
||||
} elseif ($action === 'update') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
$field = $_POST['field'] ?? '';
|
||||
$value = $_POST['value'] ?? '';
|
||||
$audiofile = intval($_POST['audiofile'] ?? 0);
|
||||
|
||||
$allowedFields = ['name', 'start_index', 'color_kampfrichter', 'audiofile', 'audiofile_max_duration'];
|
||||
if ($id > 0 && in_array($field, $allowedFields)) {
|
||||
if ($field === 'start_index' || $field === 'audiofile' || $field === 'audiofile_max_duration') {
|
||||
$value = intval($value);
|
||||
}
|
||||
|
||||
$updated = db_update($mysqli, $db_tabelle_disziplinen, [$field => $value], ['id' => $id]);
|
||||
if ($updated !== false) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'DB Update failed.']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid parameters.']);
|
||||
}
|
||||
|
||||
} elseif ($action === 'delete') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
|
||||
if ($id > 0) {
|
||||
db_delete($mysqli, $db_tabelle_disziplinen, ['id' => $id]);
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID.']);
|
||||
}
|
||||
|
||||
generateIntersectCache($mysqli, $baseDir);
|
||||
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Action not found.']);
|
||||
}
|
||||
@@ -0,0 +1,281 @@
|
||||
<?php
|
||||
ini_set("display_errors",1);
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
require $baseDir . '/../scripts/string-calculator/string-calculator-functions.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/cache/cache-creators/regenerate-display-dependencies-cache.php';
|
||||
require_once $baseDir . '/../scripts/cache/cache-creators/regenerate-noten-cache.php';
|
||||
|
||||
|
||||
|
||||
$recalculateJSONs = false;
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add') {
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$type_val = $_POST['type_val'] ?? 'input';
|
||||
$berechnung = trim($_POST['berechnung'] ?? '');
|
||||
$pro_geraet = intval($_POST['pro_geraet'] ?? 0);
|
||||
$default_value = (isset($_POST['default_value'])) ? floatval($_POST['default_value']) : null;
|
||||
$min_value = (isset($_POST['min_value'])) ? floatval($_POST['min_value']) : null;
|
||||
$max_value = (isset($_POST['max_value'])) ? floatval($_POST['max_value']) : null;
|
||||
|
||||
$id = (isset($_POST['id'])) ? floatval($_POST['id']) : 1;
|
||||
|
||||
if (!$id) {
|
||||
echo json_encode(['success' => false, 'message' => 'Id ist erforderlich.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("SELECT 1 FROM $db_tabelle_wertungstypen WHERE id = ?");
|
||||
$stmt->bind_param("i", $id);
|
||||
$stmt->execute();
|
||||
|
||||
$result = $stmt->get_result();
|
||||
|
||||
if ($result->num_rows > 0) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Eine Note mit dieser Id existiert bereits.'
|
||||
]);
|
||||
$stmt->close();
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
|
||||
if (!$name) {
|
||||
echo json_encode(['success' => false, 'message' => 'Name ist erforderlich.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $db_tabelle_wertungstypen (id, name, type, berechnung, pro_geraet, default_value, min_value, max_value) VALUES (?, ?, ?, ?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param("isssisss", $id, $name, $type_val, $berechnung, $pro_geraet, $default_value, $min_value, $max_value);
|
||||
$success = $stmt->execute();
|
||||
$new_id = $mysqli->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
$recalculateJSONs = true;
|
||||
|
||||
if ($success) {
|
||||
regenerate_noten_cache($mysqli, $db_tabelle_wertungstypen, $baseDir);
|
||||
generateIntersectCache($mysqli, $baseDir);
|
||||
if (!$recalculateJSONs) { echo json_encode(['success' => true, 'id' => $new_id]); }
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler beim Hinzufügen.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
} elseif ($action === 'update') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
$field = $_POST['field'] ?? '';
|
||||
$value = $_POST['value'] ?? '';
|
||||
|
||||
$allowedFields = ['name', 'type', 'berechnung', 'pro_geraet', 'geraete_json', 'anzahl_laeufe_json', 'default_value', 'min_value', 'max_value', 'zeige_auf_rangliste', 'nullstellen', 'display_string', 'groesse_auf_rangliste'];
|
||||
if ($id > 0 && in_array($field, $allowedFields)) {
|
||||
if ($field === 'pro_geraet') {
|
||||
$value = intval($value);
|
||||
}
|
||||
|
||||
if ($field === 'berechnung' || $field === 'type') {
|
||||
$recalculateJSONs = true;
|
||||
}
|
||||
|
||||
$updated = db_update($mysqli, $db_tabelle_wertungstypen, [$field => $value], ['id' => $id]);
|
||||
if ($updated !== false) {
|
||||
regenerate_noten_cache($mysqli, $db_tabelle_wertungstypen, $baseDir);
|
||||
generateIntersectCache($mysqli, $baseDir);
|
||||
if (!$recalculateJSONs) { echo json_encode(['success' => true]); }
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'DB Update failed.']);
|
||||
exit;
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid parameters.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
} elseif ($action === 'delete') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
|
||||
if ($id > 0) {
|
||||
db_delete($mysqli, $db_tabelle_wertungstypen, ['id' => $id]);
|
||||
regenerate_noten_cache($mysqli, $db_tabelle_wertungstypen, $baseDir);
|
||||
generateIntersectCache($mysqli, $baseDir);
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID.']);
|
||||
}
|
||||
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Action not found.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($recalculateJSONs) {
|
||||
$noten = db_select($mysqli, $db_tabelle_wertungstypen, "id, berechnung, type");
|
||||
|
||||
// 1. Re-index the array so the keys match the database IDs
|
||||
$notenById = array_column($noten, null, 'id');
|
||||
|
||||
$berechnungen = [];
|
||||
foreach ($notenById as $id => $sn) {
|
||||
if ($sn['type'] === 'berechnung') {
|
||||
$berechnungen[] = $sn;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($berechnungen)) {
|
||||
echo json_encode(['success' => true, 'message' => "Keine Berechnungen ausgewählt"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$notenRechner = new NotenRechner();
|
||||
|
||||
// 1. Build the direct map
|
||||
// Format: [ Changed_Note_ID => [ "CalcId|GeraetId" => [CalcId, GeraetId] ] ]
|
||||
$dependencyMap = [];
|
||||
|
||||
foreach ($berechnungen as $calc) {
|
||||
$neededIdsArrayWithRun = $notenRechner->getBenoetigteIdsComplexWithRun($calc['berechnung']);
|
||||
|
||||
if (empty($neededIdsArrayWithRun) || count($neededIdsArrayWithRun) < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$calcId = (int)$calc['id'];
|
||||
|
||||
$neededIdsArray = $neededIdsArrayWithRun;
|
||||
|
||||
unset($neededIdsArray['targetRun']);
|
||||
unset($neededIdsArray['targetGeraet']);
|
||||
|
||||
$targetRunId = $neededIdsArrayWithRun['targetRun'];
|
||||
$target_geraet_id = $neededIdsArrayWithRun['targetGeraet'];
|
||||
|
||||
foreach ($neededIdsArray as $key => $needed) {
|
||||
|
||||
$nId = (int)$needed['noteId'];
|
||||
|
||||
// Keep geraetId as integer if it's a number (e.g., 3), otherwise string ('S')
|
||||
$gId = is_numeric($needed['geraetId']) ? (int)$needed['geraetId'] : $needed['geraetId'];
|
||||
|
||||
// Create a unique string key so we don't store exact duplicates
|
||||
$nodeKey = $calcId . '|' . $gId . '|' . $targetRunId . '|' . $target_geraet_id; // e.g., "10|S|R2" or "12|3|RA"
|
||||
|
||||
if (!isset($dependencyMap[$nId])) {
|
||||
$dependencyMap[$nId] = [];
|
||||
}
|
||||
|
||||
// Store it as the "little array" you requested: [DependentCalcId, GeraetId]
|
||||
$dependencyMap[$nId][$nodeKey] = [$calcId, $gId, [$targetRunId, $target_geraet_id]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 2. Our recursive helper function (Updated for complex nodes)
|
||||
function getCompleteDependencyChain($id, $directMap, $visited = [])
|
||||
{
|
||||
// If this ID doesn't have anything depending on it, return empty
|
||||
if (!isset($directMap[$id])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$allDependencies = [];
|
||||
|
||||
foreach ($directMap[$id] as $nodeKey => $complexNode) {
|
||||
// CIRCULAR DEPENDENCY CHECK:
|
||||
// We check against the string key (e.g., "10|S") to prevent infinite loops
|
||||
if (isset($visited[$nodeKey])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 1. Mark this specific node as visited
|
||||
$visited[$nodeKey] = true;
|
||||
|
||||
// 2. Add the little array [CalcId, GeraetId] to our master list
|
||||
$allDependencies[$nodeKey] = $complexNode;
|
||||
|
||||
// 3. Recursively find everything that depends on THIS calculation ID
|
||||
// $complexNode[0] is the dependent Calc ID
|
||||
$childDependencies = getCompleteDependencyChain($complexNode[0], $directMap, $visited);
|
||||
|
||||
// 4. Merge the child results into our master list safely
|
||||
foreach ($childDependencies as $childKey => $childNode) {
|
||||
$allDependencies[$childKey] = $childNode;
|
||||
$visited[$childKey] = true; // Ensure the parent loop knows this was visited
|
||||
}
|
||||
}
|
||||
|
||||
return $allDependencies;
|
||||
}
|
||||
|
||||
|
||||
// 3. Create the final flattened map for ALL IDs
|
||||
$flatDependencyMap = [];
|
||||
|
||||
foreach (array_keys($notenById) as $id) {
|
||||
$chain = getCompleteDependencyChain($id, $dependencyMap);
|
||||
|
||||
// Only add it if dependencies exist
|
||||
if (!empty($chain)) {
|
||||
// array_values() removes the "10|S" string keys, turning it into a perfect
|
||||
// 0-indexed array for clean JSON encoding: [[10, "S"], [12, 3]]
|
||||
$flatDependencyMap[$id] = array_values($chain);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 4. Database Updates
|
||||
// Step 1: Reset all rows to NULL in a single query
|
||||
$resetSql = "UPDATE $db_tabelle_wertungstypen SET `berechnung_json` = NULL";
|
||||
$mysqli->query($resetSql);
|
||||
|
||||
// Step 2: Prepare the statement
|
||||
$updateSql = "UPDATE $db_tabelle_wertungstypen SET `berechnung_json` = ? WHERE id = ?";
|
||||
$stmt = $mysqli->prepare($updateSql);
|
||||
|
||||
foreach ($flatDependencyMap as $id => $completeDependencyArray) {
|
||||
if (empty($completeDependencyArray)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$jsonString = json_encode($completeDependencyArray);
|
||||
|
||||
// Bind parameters: 's' for string (JSON), 'i' for integer (ID)
|
||||
$stmt->bind_param("si", $jsonString, $id);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
echo json_encode(['success' => true, 'message' => "Abhaengigkeiten berechnet"]);
|
||||
exit;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
if (!isset($_POST['css_content'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Missing css_content parameter.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$css_content = $_POST['css_content'] ?? '';
|
||||
|
||||
if (strlen($css_content) > 200000) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'File size too large.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (preg_match('/javascript:/i', $css_content) || preg_match('/<script/i', $css_content)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid characters detected.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
file_put_contents($baseDir . '/intern/css/user.css', $css_content);
|
||||
|
||||
http_response_code(200);
|
||||
echo json_encode(['success' => true, 'message' => 'CSS saved successfully.']);
|
||||
exit;
|
||||
@@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* Upload Image API
|
||||
* Accepts multipart/form-data POST with 'image' file.
|
||||
* Converts JPG/PNG to WebP (resized to max 2400px), saves to /files/img/admin_upload/{uid}.webp
|
||||
* Returns JSON: { success: true }
|
||||
*/
|
||||
|
||||
// Allow large uploads and enough memory for GD processing
|
||||
ini_set('memory_limit', '256M');
|
||||
ini_set('upload_max_filesize', '50M');
|
||||
ini_set('post_max_size', '55M');
|
||||
ini_set('max_execution_time', '120');
|
||||
|
||||
const MAX_DIMENSION = 2400;
|
||||
const MAX_DIMENSION_ICON = 1000;
|
||||
const WEBP_QUALITY = 80;
|
||||
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
|
||||
// Only accept POST
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
http_response_code(405);
|
||||
echo json_encode(['success' => false, 'message' => 'Method not allowed']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$allowedTypes = ['Kampfrichter', 'Trainer', 'Wk_leitung', 'Otl', 'icon', 'logo-normal'];
|
||||
|
||||
if (!isset($_POST['type']) || !in_array($_POST['type'], $allowedTypes)) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => 'Typ nicht angegeben oder nicht erlaubt']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$pngs = ['icon', 'logo-normal'];
|
||||
|
||||
$type = $_POST['type'];
|
||||
$isIcon = in_array($type, $pngs);
|
||||
|
||||
// Check if $_FILES is empty entirely (can happen if post_max_size exceeded)
|
||||
if (empty($_FILES)) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'No files received. The file may exceed the server upload limit).',
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Check specific file field
|
||||
if (!isset($_FILES['image'])) {
|
||||
http_response_code(400);
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'No "image" field in upload. Received fields: ' . implode(', ', array_keys($_FILES)),
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
if ($_FILES['image']['error'] !== UPLOAD_ERR_OK) {
|
||||
http_response_code(400);
|
||||
$errors = [
|
||||
UPLOAD_ERR_INI_SIZE => 'File exceeds upload_max_filesize',
|
||||
UPLOAD_ERR_FORM_SIZE => 'File exceeds form MAX_FILE_SIZE',
|
||||
UPLOAD_ERR_PARTIAL => 'File was only partially uploaded',
|
||||
UPLOAD_ERR_NO_FILE => 'No file was uploaded',
|
||||
UPLOAD_ERR_NO_TMP_DIR => 'Missing temp directory',
|
||||
UPLOAD_ERR_CANT_WRITE => 'Failed to write to disk',
|
||||
];
|
||||
$code = $_FILES['image']['error'];
|
||||
$msg = $errors[$code] ?? "Unknown error code: $code";
|
||||
echo json_encode(['success' => false, 'message' => $msg]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$file = $_FILES['image'];
|
||||
$tmpPath = $file['tmp_name'];
|
||||
|
||||
// Validate MIME type
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mime = $finfo->file($tmpPath);
|
||||
|
||||
$allowedMimes = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
|
||||
if (!in_array($mime, $allowedMimes, true)) {
|
||||
http_response_code(415);
|
||||
echo json_encode(['success' => false, 'message' => "Unsupported file type: $mime"]);
|
||||
exit;
|
||||
}
|
||||
|
||||
// Target directory
|
||||
|
||||
|
||||
if ($isIcon) {
|
||||
$uploadDir = $baseDir . '/intern/img/';
|
||||
} else {
|
||||
$uploadDir = $baseDir . '/intern/img/login';
|
||||
}
|
||||
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
// Load image into GD
|
||||
$srcImage = null;
|
||||
switch ($mime) {
|
||||
case 'image/jpeg':
|
||||
$srcImage = @imagecreatefromjpeg($tmpPath);
|
||||
break;
|
||||
case 'image/png':
|
||||
$srcImage = @imagecreatefrompng($tmpPath);
|
||||
break;
|
||||
case 'image/webp':
|
||||
$srcImage = @imagecreatefromwebp($tmpPath);
|
||||
break;
|
||||
case 'image/gif':
|
||||
$srcImage = @imagecreatefromgif($tmpPath);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!$srcImage) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to load image into GD. It may be corrupt or too large.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
// ── Resize if needed ────────────────────────────────
|
||||
$origW = imagesx($srcImage);
|
||||
$origH = imagesy($srcImage);
|
||||
|
||||
$maxDimension = ($isIcon) ? MAX_DIMENSION_ICON : MAX_DIMENSION;
|
||||
|
||||
if ($origW > $maxDimension || $origH > $maxDimension) {
|
||||
// Calculate new dimensions keeping aspect ratio
|
||||
if ($origW >= $origH) {
|
||||
$newW = $maxDimension;
|
||||
$newH = intval(round($origH * ($maxDimension / $origW)));
|
||||
} else {
|
||||
$newH = $maxDimension;
|
||||
$newW = intval(round($origW * ($maxDimension / $origH)));
|
||||
}
|
||||
|
||||
$resized = imagecreatetruecolor($newW, $newH);
|
||||
|
||||
// Preserve transparency
|
||||
imagealphablending($resized, false);
|
||||
imagesavealpha($resized, true);
|
||||
$transparent = imagecolorallocatealpha($resized, 0, 0, 0, 127);
|
||||
imagefill($resized, 0, 0, $transparent);
|
||||
|
||||
imagecopyresampled($resized, $srcImage, 0, 0, 0, 0, $newW, $newH, $origW, $origH);
|
||||
imagedestroy($srcImage);
|
||||
$srcImage = $resized;
|
||||
} else {
|
||||
// Still preserve transparency
|
||||
imagepalettetotruecolor($srcImage);
|
||||
imagealphablending($srcImage, true);
|
||||
imagesavealpha($srcImage, true);
|
||||
}
|
||||
|
||||
if ($isIcon) {
|
||||
// ── Save as PNG ────────────────────────────────────
|
||||
$filename = $type . '.png';
|
||||
$destPath = $uploadDir . '/' . $filename;
|
||||
$webPath = '/intern/img/' . $filename;
|
||||
|
||||
$pngCompression = 6;
|
||||
|
||||
$success = imagepng($srcImage, $destPath, $pngCompression);
|
||||
} else {
|
||||
// ── Save as WebP ────────────────────────────────────
|
||||
$filename = 'bg' . $_POST['type'] . '.webp';
|
||||
$destPath = $uploadDir . '/' . $filename;
|
||||
$webPath = '/intern/img/admin_upload/' . $filename;
|
||||
|
||||
$success = imagewebp($srcImage, $destPath, WEBP_QUALITY);
|
||||
}
|
||||
|
||||
imagedestroy($srcImage);
|
||||
|
||||
if (!$success) {
|
||||
http_response_code(500);
|
||||
echo json_encode(['success' => false, 'message' => 'Failed to convert to WebP']);
|
||||
exit;
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true
|
||||
]);
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (!isset($baseDir)) {
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
}
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
|
||||
$type = 'wkl';
|
||||
$dbconnection = require $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($dbconnection['success'] !== true){
|
||||
echo json_encode(['success' => false, 'message' => 'Critical DB Error.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$action = $_POST['action'] ?? '';
|
||||
|
||||
if ($action === 'add') {
|
||||
$name = trim($_POST['name'] ?? '');
|
||||
$has_endtime = intval($_POST['has_endtime'] ?? 0);
|
||||
$index = intval($_POST['index'] ?? 0);
|
||||
|
||||
if (!$name) {
|
||||
echo json_encode(['success' => false, 'message' => 'Name ist erforderlich.']);
|
||||
exit;
|
||||
}
|
||||
|
||||
$stmt = $mysqli->prepare("INSERT INTO $db_tabelle_zeitplan_types (`name`, `has_endtime`, `display_index`) VALUES (?, ?, ?)");
|
||||
$stmt->bind_param("sii", $name, $has_endtime, $index);
|
||||
$success = $stmt->execute();
|
||||
$new_id = $mysqli->insert_id;
|
||||
$stmt->close();
|
||||
|
||||
if ($success) {
|
||||
echo json_encode(['success' => true, 'id' => $new_id]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Fehler beim Hinzufügen.']);
|
||||
}
|
||||
|
||||
} elseif ($action === 'update') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
$field = $_POST['field'] ?? '';
|
||||
$value = $_POST['value'] ?? '';
|
||||
$audiofile = intval($_POST['audiofile'] ?? 0);
|
||||
|
||||
$allowedFields = ['name', 'has_endtime', 'display_index'];
|
||||
if ($id > 0 && in_array($field, $allowedFields)) {
|
||||
if ($field === 'display_index') {
|
||||
$value = intval($value);
|
||||
}
|
||||
|
||||
$updated = db_update($mysqli, $db_tabelle_zeitplan_types, [$field => $value], ['id' => $id]);
|
||||
if ($updated !== false) {
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'DB Update failed.']);
|
||||
}
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid parameters.']);
|
||||
}
|
||||
|
||||
} elseif ($action === 'delete') {
|
||||
$id = intval($_POST['id'] ?? 0);
|
||||
|
||||
if ($id > 0) {
|
||||
db_delete($mysqli, $db_tabelle_zeitplan_types, ['id' => $id]);
|
||||
echo json_encode(['success' => true]);
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Invalid ID.']);
|
||||
}
|
||||
|
||||
} else {
|
||||
echo json_encode(['success' => false, 'message' => 'Action not found.']);
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
|
||||
try {
|
||||
$mysqli->set_charset("utf8mb4");
|
||||
|
||||
// 4. Fetch all rows ordered by ID so the layout hierarchy is preserved
|
||||
$sql = "SELECT * FROM `$db_tabelle_wertungstypen` ORDER BY `id` ASC";
|
||||
$result = $mysqli->query($sql);
|
||||
|
||||
$exportData = [];
|
||||
|
||||
while ($row = $result->fetch_assoc()) {
|
||||
$presetItem = [];
|
||||
|
||||
foreach ($row as $columnName => $value) {
|
||||
if ($columnName === 'berechnung_json') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($value === null) {
|
||||
$presetItem[$columnName] = null;
|
||||
} elseif (is_numeric($value)) {
|
||||
$presetItem[$columnName] = (strpos($value, '.') !== false) ? (float)$value : (int)$value;
|
||||
} else {
|
||||
$presetItem[$columnName] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$exportDataDisc[] = $presetItem;
|
||||
}
|
||||
|
||||
$result->free();
|
||||
|
||||
$geraete = db_select($mysqli, $db_tabelle_disziplinen, '*', '', [], 'start_index ASC');
|
||||
$programme = db_select($mysqli, $db_tabelle_kategorien, '*', '', [], 'id ASC');
|
||||
$zeitplanTypen = db_select($mysqli, $db_tabelle_zeitplan_types, '*', '', [], 'id ASC');
|
||||
$rangNote = db_get_var($mysqli, "SELECT `value` FROM $db_tabelle_var WHERE `name` = ?", ['rangNote']);
|
||||
$wkName = db_get_var($mysqli, "SELECT `value` FROM $db_tabelle_var WHERE `name` = ?", ['wkName']);
|
||||
$orderBestRang = db_get_var($mysqli, "SELECT `value` FROM $db_tabelle_var WHERE `name` = ?", ['orderBestRang']);
|
||||
|
||||
$personEinzahl = db_get_variable($mysqli, $db_tabelle_var, ['personEinzahl']);
|
||||
if ($personEinzahl === null) $personEinzahl = 'Person';
|
||||
|
||||
$personMehrzahl = db_get_variable($mysqli, $db_tabelle_var, ['personMehrzahl']);
|
||||
if ($personMehrzahl === null) $personMehrzahl = 'Personen';
|
||||
|
||||
$mysqli->close();
|
||||
|
||||
$exportData = [
|
||||
'metadata' => [
|
||||
'erstellt_am' => date("d.m.Y H:i"),
|
||||
'ersteller' => $_SERVER['HTTP_HOST'],
|
||||
'erstellt_mit' => 'WKVS Auto-Export',
|
||||
'wkvs_json_version' => '1.0.0',
|
||||
'titel' => 'WKVS Preset ' . $wkName . ' (V 1.0.0)'
|
||||
],
|
||||
'noten' => $exportDataDisc,
|
||||
'disziplinen' => $geraete,
|
||||
'zeitplan_typen' => $zeitplanTypen,
|
||||
'rang_konfiguration' => [
|
||||
'rang_note_id' => $rangNote,
|
||||
'order_best_rang' => $orderBestRang
|
||||
],
|
||||
"leistungsklassen" => $programme,
|
||||
"bezeichnungen" =>[
|
||||
"singular" => $personEinzahl,
|
||||
"plural"=> $personMehrzahl
|
||||
]
|
||||
];
|
||||
|
||||
$jsonOutput = json_encode($exportData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
// 6. Force Browser File Download
|
||||
$fileName = 'WKVS-preset-config-' . date('Y-m-d_H-i') . '.json';
|
||||
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
header('Content-Disposition: attachment; filename="' . $fileName . '"');
|
||||
header('Expires: 0');
|
||||
header('Cache-Control: must-revalidate');
|
||||
header('Pragma: public');
|
||||
header('Content-Length: ' . strlen($jsonOutput));
|
||||
|
||||
echo $jsonOutput;
|
||||
exit;
|
||||
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
http_response_code(500);
|
||||
echo "Database export failed";
|
||||
}
|
||||
@@ -0,0 +1,350 @@
|
||||
<?php
|
||||
|
||||
ini_set("display_errors",1);
|
||||
|
||||
if (!isset($baseDir)) $baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session();
|
||||
|
||||
check_user_permission('wk_leitung');
|
||||
|
||||
verify_csrf();
|
||||
|
||||
if (!isset($_FILES['configFile']) || $_FILES['configFile']['error'] !== UPLOAD_ERR_OK) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'message' => 'Keine Config-Datei ausgewählt'
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$wkvsJSONVersion = '1.0.0';
|
||||
|
||||
$type = 'wkl';
|
||||
|
||||
$data = include $baseDir . '/../scripts/db/db-verbindung-script.php';
|
||||
|
||||
if ($data['success'] === false){
|
||||
echo json_encode(['success' => false, 'message' => $data['message']]);
|
||||
exit;
|
||||
}
|
||||
|
||||
require $baseDir . '/../scripts/db/db-tables.php';
|
||||
require $baseDir . '/../scripts/db/db-functions.php';
|
||||
require $baseDir . '/../scripts/string-calculator/string-calculator-functions.php';
|
||||
|
||||
|
||||
|
||||
$saveDir = '/../private-files/config-uploads/';
|
||||
|
||||
$uploadDir = $baseDir . $saveDir;
|
||||
|
||||
|
||||
if (!is_dir($uploadDir)) {
|
||||
mkdir($uploadDir, 0755, true);
|
||||
}
|
||||
|
||||
|
||||
$tmpPath = $_FILES['configFile']['tmp_name'];
|
||||
$originalName = $_FILES['configFile']['name'];
|
||||
$extension = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
|
||||
|
||||
$allowedExt = ['json'];
|
||||
if (!in_array($extension, $allowedExt, true)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Falsches Format (Endung)']);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$finfo = new finfo(FILEINFO_MIME_TYPE);
|
||||
$mimeType = $finfo->file($tmpPath);
|
||||
$allowedMime = ['application/json'];
|
||||
|
||||
if (!in_array($mimeType, $allowedMime, true)) {
|
||||
echo json_encode(['success' => false, 'message' => 'Dateiinhalt ist kein gültiges JSON']);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
$filename = date("Y_m_d_H_i_s") . '-wkvs-config.json';
|
||||
$destination = $uploadDir . $filename;
|
||||
|
||||
|
||||
if (!move_uploaded_file($tmpPath, $destination)) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$JSONcontent = file_get_contents($destination);
|
||||
|
||||
$content = json_decode($JSONcontent, true);
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
die("Invalid JSON layout.");
|
||||
}
|
||||
|
||||
if (!isset($content['metadata']['wkvs_json_version']) || $content['metadata']['wkvs_json_version'] !== $wkvsJSONVersion) {
|
||||
echo json_encode(['success' => false, 'message' => 'Inkompatible Datei-Version. (V ' . $wkvsJSONVersion . ' benötigt'. (isset($content['metadata']['wkvs_json_version']) ? ", benutzte Datei-Version: V " . $content['metadata']['wkvs_json_version'] : '') . ')' ]);
|
||||
unlink($destination);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($content['noten']) || !is_array($content['noten']) || !isset($content['disziplinen']) || !is_array($content['disziplinen'])) {
|
||||
echo json_encode(['success' => false, 'message' => 'Ungültige JSON-Struktur']);
|
||||
unlink($destination);
|
||||
http_response_code(422);
|
||||
exit;
|
||||
}
|
||||
|
||||
$content['added_timestamp'] = date("Y-m-d H:i:s");
|
||||
|
||||
file_put_contents($destination, json_encode($content));
|
||||
|
||||
$allowedColumns = [
|
||||
'noten' => [
|
||||
'id', 'name', 'default_value', 'type', 'berechnung', 'berechnung_json',
|
||||
'max_value', 'min_value', 'pro_geraet', 'anzahl_laeufe_json', 'geraete_json',
|
||||
'nullstellen', 'display_string'
|
||||
],
|
||||
'disziplinen' => ['id', 'name', 'start_index', 'color_kampfrichter', 'audiofile'],
|
||||
'zeitplan_typen' => ['id', 'name', 'has_endtime', 'display_index'],
|
||||
'leistungsklassen' => ['id', 'programm', 'order_index', 'preis', 'aktiv']
|
||||
];
|
||||
|
||||
$tableTable = [
|
||||
'noten' => $db_tabelle_wertungstypen,
|
||||
'disziplinen' => $db_tabelle_disziplinen,
|
||||
'zeitplan_typen' => $db_tabelle_zeitplan_types,
|
||||
'leistungsklassen' => $db_tabelle_kategorien
|
||||
];
|
||||
|
||||
$successCount = 0;
|
||||
|
||||
try {
|
||||
|
||||
$mysqli->begin_transaction();
|
||||
|
||||
foreach ($allowedColumns as $type => $columns) {
|
||||
|
||||
$tableName = "`" . $tableTable[$type] . "`";
|
||||
|
||||
$mysqli->query("DELETE FROM " . $tableName);
|
||||
|
||||
$columnsSql = implode(', ', array_map(fn($col) => "`$col`", $columns));
|
||||
$placeholdersSql = implode(', ', array_fill(0, count($columns), '?'));
|
||||
|
||||
$sql = "INSERT INTO " . $tableName . " ($columnsSql)
|
||||
VALUES ($placeholdersSql)";
|
||||
|
||||
$typesString = str_repeat('s', count($columns));
|
||||
|
||||
$stmt = $mysqli->prepare($sql);
|
||||
|
||||
foreach ($content[$type] as $index => $row) {
|
||||
$bindValues = [];
|
||||
|
||||
foreach ($columns as $column) {
|
||||
if (!array_key_exists($column, $row) || $row[$column] === null) {
|
||||
$bindValues[] = null;
|
||||
} else {
|
||||
$bindValues[] = $row[$column];
|
||||
}
|
||||
}
|
||||
|
||||
$stmt->bind_param($typesString, ...$bindValues);
|
||||
$stmt->execute();
|
||||
$successCount++;
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
$rangNote = intval($content['rang_konfiguration']['rang_note_id'] ?? 0);
|
||||
$orderBestRang = $content['rang_konfiguration']['order_best_rang'] ?? '';
|
||||
|
||||
$allowableOrderValues = ['ASC', 'DESC'];
|
||||
|
||||
if ($rangNote > 0) {
|
||||
$mysqli->query("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES ('rangNote', '" . $rangNote . "') ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
}
|
||||
|
||||
if (in_array($orderBestRang, $allowableOrderValues, true)) {
|
||||
$mysqli->query("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES ('orderBestRang', '" . $orderBestRang . "') ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
}
|
||||
|
||||
if (isset($content['bezeichnungen']['singular']) && $content['bezeichnungen']['singular'] !== null) {
|
||||
$stmt = $mysqli->prepare("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
$varName = 'personEinzahl';
|
||||
$stmt->bind_param("ss", $varName, $content['bezeichnungen']['singular']);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
if (isset($content['bezeichnungen']['plural']) && $content['bezeichnungen']['plural'] !== null) {
|
||||
$stmt = $mysqli->prepare("INSERT INTO $db_tabelle_var (`name`, `value`) VALUES (?, ?) ON DUPLICATE KEY UPDATE `value` = VALUES(`value`)");
|
||||
$varName = 'personMehrzahl';
|
||||
$stmt->bind_param("ss", $varName, $content['bezeichnungen']['plural']);
|
||||
$stmt->execute();
|
||||
$stmt->close();
|
||||
}
|
||||
|
||||
|
||||
$noten = db_select($mysqli, $db_tabelle_wertungstypen, "id, berechnung, type");
|
||||
|
||||
$notenById = array_column($noten, null, 'id');
|
||||
|
||||
$berechnungen = [];
|
||||
foreach ($notenById as $id => $sn) {
|
||||
if ($sn['type'] === 'berechnung') {
|
||||
$berechnungen[] = $sn;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($berechnungen)) {
|
||||
$mysqli->commit();
|
||||
echo json_encode(['success' => true, 'message' => "Successfully imported $successCount rows."]);
|
||||
exit;
|
||||
}
|
||||
|
||||
$notenRechner = new NotenRechner();
|
||||
|
||||
$dependencyMap = [];
|
||||
|
||||
foreach ($berechnungen as $calc) {
|
||||
$neededIdsArrayWithRun = $notenRechner->getBenoetigteIdsComplexWithRun($calc['berechnung']);
|
||||
|
||||
if (empty($neededIdsArrayWithRun) || count($neededIdsArrayWithRun) < 2) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$calcId = (int)$calc['id'];
|
||||
|
||||
$neededIdsArray = $neededIdsArrayWithRun;
|
||||
|
||||
unset($neededIdsArray['targetRun']);
|
||||
unset($neededIdsArray['targetGeraet']);
|
||||
|
||||
$targetRunId = $neededIdsArrayWithRun['targetRun'];
|
||||
|
||||
foreach ($neededIdsArray as $key => $needed) {
|
||||
|
||||
$nId = (int)$needed['noteId'];
|
||||
|
||||
$gId = is_numeric($needed['geraetId']) ? (int)$needed['geraetId'] : $needed['geraetId'];
|
||||
|
||||
$nodeKey = $calcId . '|' . $gId . '|' . $targetRunId;
|
||||
|
||||
if (!isset($dependencyMap[$nId])) {
|
||||
$dependencyMap[$nId] = [];
|
||||
}
|
||||
|
||||
$dependencyMap[$nId][$nodeKey] = [$calcId, $gId, [$targetRunId]];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function getCompleteDependencyChain($id, $directMap, $visited = [])
|
||||
{
|
||||
if (!isset($directMap[$id])) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$allDependencies = [];
|
||||
|
||||
foreach ($directMap[$id] as $nodeKey => $complexNode) {
|
||||
if (isset($visited[$nodeKey])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$visited[$nodeKey] = true;
|
||||
|
||||
$allDependencies[$nodeKey] = $complexNode;
|
||||
|
||||
$childDependencies = getCompleteDependencyChain($complexNode[0], $directMap, $visited);
|
||||
|
||||
foreach ($childDependencies as $childKey => $childNode) {
|
||||
$allDependencies[$childKey] = $childNode;
|
||||
$visited[$childKey] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $allDependencies;
|
||||
}
|
||||
|
||||
$flatDependencyMap = [];
|
||||
|
||||
foreach (array_keys($notenById) as $id) {
|
||||
$chain = getCompleteDependencyChain($id, $dependencyMap);
|
||||
|
||||
if (!empty($chain)) {
|
||||
$flatDependencyMap[$id] = array_values($chain);
|
||||
}
|
||||
}
|
||||
|
||||
$resetSql = "UPDATE $db_tabelle_wertungstypen SET `berechnung_json` = NULL";
|
||||
$mysqli->query($resetSql);
|
||||
|
||||
// Step 2: Prepare the statement
|
||||
$updateSql = "UPDATE $db_tabelle_wertungstypen SET `berechnung_json` = ? WHERE id = ?";
|
||||
$stmt = $mysqli->prepare($updateSql);
|
||||
|
||||
foreach ($flatDependencyMap as $id => $completeDependencyArray) {
|
||||
if (empty($completeDependencyArray)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$jsonString = json_encode($completeDependencyArray);
|
||||
|
||||
$stmt->bind_param("si", $jsonString, $id);
|
||||
$stmt->execute();
|
||||
}
|
||||
|
||||
$stmt->close();
|
||||
|
||||
$mysqli->commit();
|
||||
echo json_encode(['success' => true, 'message' => "Successfully imported $successCount rows."]);
|
||||
|
||||
require_once $baseDir . '/../scripts/cache/cache-creators/regenerate-display-dependencies-cache.php';
|
||||
require_once $baseDir . '/../scripts/cache/cache-creators/regenerate-noten-cache.php';
|
||||
|
||||
generateIntersectCache($mysqli, $baseDir);
|
||||
regenerate_noten_cache($mysqli, $db_tabelle_wertungstypen, $baseDir);
|
||||
|
||||
} catch (mysqli_sql_exception $e) {
|
||||
$mysqli->rollback();
|
||||
unlink($destination);
|
||||
|
||||
if ($e->getCode() === 1048) {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => "Import failed: A required data field is missing in your preset file."]);
|
||||
exit;
|
||||
} else {
|
||||
http_response_code(400);
|
||||
echo json_encode(['success' => false, 'message' => "Database error during import." . " Error Code: " . $e->getMessage()]);
|
||||
exit;
|
||||
}
|
||||
} finally {
|
||||
$mysqli->close();
|
||||
$allFiles = glob($uploadDir . '*.json');
|
||||
|
||||
$timestamps = array_map(function($file) {
|
||||
$jsonContent = file_get_contents($file) ?? '';
|
||||
|
||||
$data = json_decode($jsonContent, true) ?? [];
|
||||
|
||||
return $data['added_timestamp'] ?? 0;
|
||||
}, $allFiles);
|
||||
|
||||
array_multisort($timestamps, SORT_DESC, $allFiles);
|
||||
|
||||
$filesToDelete = array_slice($allFiles, 3);
|
||||
|
||||
foreach ($filesToDelete as $file) {
|
||||
unlink($file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user