Enforce topology rules and fix device deletion flow
This commit is contained in:
@@ -77,6 +77,19 @@ function endpointExists($sql, string $type, int $id): bool
|
||||
return false;
|
||||
}
|
||||
|
||||
function isTopologyPairAllowed(string $typeA, string $typeB): bool
|
||||
{
|
||||
$allowed = ['device' => true, 'module' => true, 'outlet' => true, 'patchpanel' => true];
|
||||
if (!isset($allowed[$typeA]) || !isset($allowed[$typeB])) {
|
||||
return false;
|
||||
}
|
||||
if ($typeA === 'patchpanel' || $typeB === 'patchpanel') {
|
||||
return ($typeA === 'patchpanel' && in_array($typeB, ['patchpanel', 'outlet'], true))
|
||||
|| ($typeB === 'patchpanel' && in_array($typeA, ['patchpanel', 'outlet'], true));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function loadConnections($sql): void
|
||||
{
|
||||
$contextType = strtolower(trim((string)($_GET['context_type'] ?? 'all')));
|
||||
@@ -189,6 +202,9 @@ function saveConnection($sql): void
|
||||
if ($portAId <= 0 || $portBId <= 0) {
|
||||
jsonError('port_a_id und port_b_id sind erforderlich', 400);
|
||||
}
|
||||
if (!isTopologyPairAllowed($portAType, $portBType)) {
|
||||
jsonError('Patchpanel-Ports duerfen nur mit Patchpanel-Ports oder Netzwerkdosen-Ports verbunden werden', 400);
|
||||
}
|
||||
|
||||
if ($portAType === $portBType && $portAId === $portBId) {
|
||||
jsonError('Port A und Port B duerfen nicht identisch sein', 400);
|
||||
|
||||
@@ -51,8 +51,49 @@
|
||||
});
|
||||
}
|
||||
|
||||
function enforceTopologyTypeRules(typeA, typeB) {
|
||||
const allowWithPatchpanel = { patchpanel: true, outlet: true };
|
||||
const selectedA = typeA.value;
|
||||
const selectedB = typeB.value;
|
||||
|
||||
const applyRules = (sourceType, targetSelect) => {
|
||||
for (const option of targetSelect.options) {
|
||||
const value = option.value;
|
||||
if (!value) {
|
||||
option.disabled = false;
|
||||
continue;
|
||||
}
|
||||
if (sourceType === 'patchpanel') {
|
||||
option.disabled = !allowWithPatchpanel[value];
|
||||
} else {
|
||||
option.disabled = false;
|
||||
}
|
||||
}
|
||||
if (targetSelect.selectedOptions.length > 0 && targetSelect.selectedOptions[0].disabled) {
|
||||
targetSelect.value = '';
|
||||
}
|
||||
};
|
||||
|
||||
applyRules(selectedA, typeB);
|
||||
applyRules(selectedB, typeA);
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
bindPair('port_a_type', 'port_a_id');
|
||||
bindPair('port_b_type', 'port_b_id');
|
||||
|
||||
const typeA = document.getElementById('port_a_type');
|
||||
const typeB = document.getElementById('port_b_type');
|
||||
if (!typeA || !typeB) {
|
||||
return;
|
||||
}
|
||||
|
||||
const syncRules = () => {
|
||||
enforceTopologyTypeRules(typeA, typeB);
|
||||
};
|
||||
|
||||
syncRules();
|
||||
typeA.addEventListener('change', syncRules);
|
||||
typeB.addEventListener('change', syncRules);
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -42,6 +42,18 @@ $normalizePortType = static function (string $value): string {
|
||||
$portAType = $normalizePortType((string)$portAType);
|
||||
$portBType = $normalizePortType((string)$portBType);
|
||||
|
||||
$isTopologyPairAllowed = static function (string $typeA, string $typeB): bool {
|
||||
$allowed = ['device' => true, 'module' => true, 'outlet' => true, 'patchpanel' => true];
|
||||
if (!isset($allowed[$typeA]) || !isset($allowed[$typeB])) {
|
||||
return false;
|
||||
}
|
||||
if ($typeA === 'patchpanel' || $typeB === 'patchpanel') {
|
||||
return ($typeA === 'patchpanel' && in_array($typeB, ['patchpanel', 'outlet'], true))
|
||||
|| ($typeB === 'patchpanel' && in_array($typeA, ['patchpanel', 'outlet'], true));
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// =========================
|
||||
// Validierung (einfach)
|
||||
// =========================
|
||||
@@ -50,6 +62,9 @@ $errors = [];
|
||||
if ($portAId <= 0 || $portBId <= 0) {
|
||||
$errors[] = "Beide Ports sind erforderlich";
|
||||
}
|
||||
if (!$isTopologyPairAllowed($portAType, $portBType)) {
|
||||
$errors[] = "Patchpanel-Ports duerfen nur mit Patchpanel-Ports oder Netzwerkdosen-Ports verbunden werden";
|
||||
}
|
||||
|
||||
$otherConnections = $sql->get(
|
||||
"SELECT id, port_a_type, port_a_id, port_b_type, port_b_id
|
||||
|
||||
@@ -56,10 +56,10 @@ $dependencies = $sql->single(
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM connections c
|
||||
WHERE (c.port_a_type = 'device' AND c.port_a_id IN (
|
||||
WHERE ((c.port_a_type = 'device' OR c.port_a_type = 'device_ports') AND c.port_a_id IN (
|
||||
SELECT dp3.id FROM device_ports dp3 WHERE dp3.device_id = ?
|
||||
))
|
||||
OR (c.port_b_type = 'device' AND c.port_b_id IN (
|
||||
OR ((c.port_b_type = 'device' OR c.port_b_type = 'device_ports') AND c.port_b_id IN (
|
||||
SELECT dp4.id FROM device_ports dp4 WHERE dp4.device_id = ?
|
||||
))
|
||||
) AS connection_count",
|
||||
@@ -108,8 +108,8 @@ if ($hasDependencies && !$forceDelete) {
|
||||
// Connections referenzieren device_ports nur logisch, daher manuell entfernen.
|
||||
$sql->set(
|
||||
"DELETE FROM connections
|
||||
WHERE (port_a_type = 'device' AND port_a_id IN (SELECT id FROM device_ports WHERE device_id = ?))
|
||||
OR (port_b_type = 'device' AND port_b_id IN (SELECT id FROM device_ports WHERE device_id = ?))",
|
||||
WHERE ((port_a_type = 'device' OR port_a_type = 'device_ports') AND port_a_id IN (SELECT id FROM device_ports WHERE device_id = ?))
|
||||
OR ((port_b_type = 'device' OR port_b_type = 'device_ports') AND port_b_id IN (SELECT id FROM device_ports WHERE device_id = ?))",
|
||||
"ii",
|
||||
[$deviceId, $deviceId]
|
||||
);
|
||||
|
||||
@@ -47,10 +47,10 @@ if ($isEdit) {
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM connections c
|
||||
WHERE (c.port_a_type = 'device' AND c.port_a_id IN (
|
||||
WHERE ((c.port_a_type = 'device' OR c.port_a_type = 'device_ports') AND c.port_a_id IN (
|
||||
SELECT dp3.id FROM device_ports dp3 WHERE dp3.device_id = ?
|
||||
))
|
||||
OR (c.port_b_type = 'device' AND c.port_b_id IN (
|
||||
OR ((c.port_b_type = 'device' OR c.port_b_type = 'device_ports') AND c.port_b_id IN (
|
||||
SELECT dp4.id FROM device_ports dp4 WHERE dp4.device_id = ?
|
||||
))
|
||||
) AS connection_count",
|
||||
|
||||
@@ -97,10 +97,10 @@ $devices = $sql->get(
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM connections c
|
||||
WHERE (c.port_a_type = 'device' AND c.port_a_id IN (
|
||||
WHERE ((c.port_a_type = 'device' OR c.port_a_type = 'device_ports') AND c.port_a_id IN (
|
||||
SELECT dp3.id FROM device_ports dp3 WHERE dp3.device_id = d.id
|
||||
))
|
||||
OR (c.port_b_type = 'device' AND c.port_b_id IN (
|
||||
OR ((c.port_b_type = 'device' OR c.port_b_type = 'device_ports') AND c.port_b_id IN (
|
||||
SELECT dp4.id FROM device_ports dp4 WHERE dp4.device_id = d.id
|
||||
))
|
||||
) AS connection_count
|
||||
|
||||
Reference in New Issue
Block a user