*/ function energieflussLaden() { $ergebnis = []; try { $res = meshDb()->query("SELECT id, aktiv, name, x, y, optionen FROM energiefluss"); } catch (Throwable $e) { return $ergebnis; } while ($res && $z = $res->fetch_assoc()) { $optionen = $z["optionen"] !== null ? json_decode($z["optionen"], true) : null; $ergebnis[$z["id"]] = [ "aktiv" => (bool)$z["aktiv"], "name" => $z["name"], "x" => $z["x"] !== null ? (int)$z["x"] : null, "y" => $z["y"] !== null ? (int)$z["y"] : null, "optionen" => is_array($optionen) ? $optionen : null, ]; } return $ergebnis; } /** * Den ganzen Stand ersetzen. * * Die Maske schickt immer alle Kreise, auch unveränderte - so gibt es keinen * Zwischenstand, in dem die Hälfte gespeichert ist. Einträge, die dem Katalog * entsprechen (aktiv, ohne Name, Lage und Optionen), werden gar nicht erst * geschrieben: die Tabelle hält nur echte Abweichungen. * * @param array $knoten [{id, aktiv, name, x, y, optionen}, ...] * @return int Anzahl gespeicherter Abweichungen */ function energieflussSpeichern($knoten) { if (!is_array($knoten)) { throw new InvalidArgumentException("Keine Kreise übergeben."); } $zeilen = []; foreach ($knoten as $k) { $id = (string)($k["id"] ?? ""); if (!preg_match('/^[A-Za-z][A-Za-z0-9_]{0,19}$/', $id)) { throw new InvalidArgumentException("Ungültige Kennung: " . $id); } $name = trim((string)($k["name"] ?? "")); if (mb_strlen($name) > 40) { throw new InvalidArgumentException("Der Name „" . $name . "“ ist länger als 40 Zeichen."); } $x = isset($k["x"]) && $k["x"] !== null ? (int)round($k["x"]) : null; $y = isset($k["y"]) && $k["y"] !== null ? (int)round($k["y"]) : null; foreach ([$x, $y] as $w) { if ($w !== null && ($w < -2000 || $w > 4000)) { throw new InvalidArgumentException("Die Lage von „" . $id . "“ liegt außerhalb der Zeichenfläche."); } } $optionen = $k["optionen"] ?? null; if ($optionen !== null && !is_array($optionen)) { throw new InvalidArgumentException("Optionen von „" . $id . "“ sind kein Objekt."); } $aktiv = !isset($k["aktiv"]) || (bool)$k["aktiv"]; if ($aktiv && $name === "" && $x === null && $y === null && $optionen === null) { continue; } $zeilen[] = [$id, $aktiv ? 1 : 0, $name === "" ? null : $name, $x, $y, $optionen === null ? null : json_encode($optionen, JSON_UNESCAPED_UNICODE)]; } $db = meshDb(); $db->begin_transaction(); try { $db->query("DELETE FROM energiefluss"); $st = $db->prepare("INSERT INTO energiefluss (id, aktiv, name, x, y, optionen) VALUES (?, ?, ?, ?, ?, ?)"); foreach ($zeilen as $z) { $st->bind_param("sisiis", $z[0], $z[1], $z[2], $z[3], $z[4], $z[5]); $st->execute(); } $db->commit(); } catch (Throwable $e) { $db->rollback(); throw new RuntimeException("Die Übersicht wurde nicht gespeichert: " . $e->getMessage()); } return count($zeilen); }