false, 'message' => $data['message']]); exit; } require $baseDir . '/../scripts/db/db-functions.php'; require $baseDir . '/../scripts/db/db-tables.php'; $noten = db_select($mysqli, $tableNotenBezeichnungen, "id, berechnung, type"); // 1. Re-index the array so the keys match the database IDs $notenById = array_column($noten, null, 'id'); $berechnungen = []; foreach ($notenById as $id => $sn) { if ($sn['type'] === 'berechnung') { $berechnungen[] = $sn; } } if (empty($berechnungen)) { echo json_encode(['success' => true, 'message' => "Keine Berechnungen ausgewählt"]); exit; } require $baseDir . "/../scripts/string-calculator/string-calculator-functions.php"; $notenRechner = new NotenRechner(); // 1. Build the direct map // Format: [ Changed_Note_ID => [ "CalcId|GeraetId" => [CalcId, GeraetId] ] ] $dependencyMap = []; foreach ($berechnungen as $calc) { $neededIdsArray = $notenRechner->getBenoetigteIdsComplex($calc['berechnung']); if (empty($neededIdsArray)) { continue; } $calcId = (int)$calc['id']; foreach ($neededIdsArray as $needed) { $nId = (int)$needed['noteId']; // Keep geraetId as integer if it's a number (e.g., 3), otherwise string ('S') $gId = is_numeric($needed['geraetId']) ? (int)$needed['geraetId'] : $needed['geraetId']; // Create a unique string key so we don't store exact duplicates $nodeKey = $calcId . '|' . $gId; if (!isset($dependencyMap[$nId])) { $dependencyMap[$nId] = []; } // Store it as the "little array" you requested: [DependentCalcId, GeraetId] $dependencyMap[$nId][$nodeKey] = [$calcId, $gId]; } } // 2. Our recursive helper function (Updated for complex nodes) function getCompleteDependencyChain($id, $directMap, $visited = []) { // If this ID doesn't have anything depending on it, return empty if (!isset($directMap[$id])) { return []; } $allDependencies = []; foreach ($directMap[$id] as $nodeKey => $complexNode) { // CIRCULAR DEPENDENCY CHECK: // We check against the string key (e.g., "10|S") to prevent infinite loops if (isset($visited[$nodeKey])) { continue; } // 1. Mark this specific node as visited $visited[$nodeKey] = true; // 2. Add the little array [CalcId, GeraetId] to our master list $allDependencies[$nodeKey] = $complexNode; // 3. Recursively find everything that depends on THIS calculation ID // $complexNode[0] is the dependent Calc ID $childDependencies = getCompleteDependencyChain($complexNode[0], $directMap, $visited); // 4. Merge the child results into our master list safely foreach ($childDependencies as $childKey => $childNode) { $allDependencies[$childKey] = $childNode; $visited[$childKey] = true; // Ensure the parent loop knows this was visited } } return $allDependencies; } // 3. Create the final flattened map for ALL IDs $flatDependencyMap = []; foreach (array_keys($notenById) as $id) { $chain = getCompleteDependencyChain($id, $dependencyMap); // Only add it if dependencies exist if (!empty($chain)) { // array_values() removes the "10|S" string keys, turning it into a perfect // 0-indexed array for clean JSON encoding: [[10, "S"], [12, 3]] $flatDependencyMap[$id] = array_values($chain); } } // 4. Database Updates // Step 1: Reset all rows to NULL in a single query $resetSql = "UPDATE $tableNotenBezeichnungen SET `berechnung_json` = NULL"; $mysqli->query($resetSql); // Step 2: Prepare the statement $updateSql = "UPDATE $tableNotenBezeichnungen SET `berechnung_json` = ? WHERE id = ?"; $stmt = $mysqli->prepare($updateSql); foreach ($flatDependencyMap as $id => $completeDependencyArray) { if (empty($completeDependencyArray)) { continue; } $jsonString = json_encode($completeDependencyArray); // Bind parameters: 's' for string (JSON), 'i' for integer (ID) $stmt->bind_param("si", $jsonString, $id); $stmt->execute(); } $stmt->close(); echo json_encode(['success' => true, 'message' => "Abhaengigkeiten berechnet"]); exit;