connections admin
This commit is contained in:
7
TODO.md
7
TODO.md
@@ -234,3 +234,10 @@ Hinweis: Die Eintraege sind direkt aus den Quelldateien aggregiert.
|
|||||||
- [ ] L253: - TODO: SVG-Editor um Drag & Drop für diese Objekte erweitern und Klicks direkt mit dem Modul verbinden.
|
- [ ] L253: - TODO: SVG-Editor um Drag & Drop für diese Objekte erweitern und Klicks direkt mit dem Modul verbinden.
|
||||||
|
|
||||||
- [ ] //TODO infrastruktur patchfelder löschen soll implementiert werden.
|
- [ ] //TODO infrastruktur patchfelder löschen soll implementiert werden.
|
||||||
|
|
||||||
|
## Topologie-Abgleich (16. Februar 2026)
|
||||||
|
|
||||||
|
- [ ] #TODO: `connections.port_a_type` und `connections.port_b_type` um einen Patchpanel-Port-Typ erweitern (z. B. `patchpanel`) und auf `floor_patchpanel_ports.id` referenzieren.
|
||||||
|
- [ ] #TODO: Business-Regeln fuer Topologie in der Verbindungs-Validierung hinterlegen: Patchpanel-Port nur mit Patchpanel-Port oder Netzwerkbuchsen-Port verbinden.
|
||||||
|
- [ ] #TODO: Port-CRUD fuer Patchpanels ergaenzen: `floor_patchpanel_ports` beim Speichern aus `port_count` erzeugen/synchronisieren.
|
||||||
|
- [ ] #TODO: Port-CRUD fuer Netzwerkbuchsen ergaenzen: `network_outlet_ports` pflegen (mindestens ein Port je Buchse) und fuer Verbindungen nutzbar machen.
|
||||||
|
|||||||
@@ -14,6 +14,49 @@
|
|||||||
$search = trim($_GET['search'] ?? '');
|
$search = trim($_GET['search'] ?? '');
|
||||||
$deviceId = (int)($_GET['device_id'] ?? 0);
|
$deviceId = (int)($_GET['device_id'] ?? 0);
|
||||||
|
|
||||||
|
// Einheitliche Endpunkt-Aufloesung fuer polymorphe Port-Typen.
|
||||||
|
$endpointUnionSql = "
|
||||||
|
SELECT
|
||||||
|
'device' AS endpoint_type,
|
||||||
|
dp.id AS endpoint_id,
|
||||||
|
dp.name AS port_name,
|
||||||
|
d.name AS owner_name,
|
||||||
|
d.id AS owner_device_id
|
||||||
|
FROM device_ports dp
|
||||||
|
JOIN devices d ON d.id = dp.device_id
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'module' AS endpoint_type,
|
||||||
|
mp.id AS endpoint_id,
|
||||||
|
mp.name AS port_name,
|
||||||
|
CONCAT(d.name, ' / ', m.name) AS owner_name,
|
||||||
|
d.id AS owner_device_id
|
||||||
|
FROM module_ports mp
|
||||||
|
JOIN modules m ON m.id = mp.module_id
|
||||||
|
JOIN devices d ON d.id = m.device_id
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'outlet' AS endpoint_type,
|
||||||
|
nop.id AS endpoint_id,
|
||||||
|
nop.name AS port_name,
|
||||||
|
CONCAT(no.name, ' / ', IFNULL(r.name, ''), ' / ', IFNULL(f.name, '')) AS owner_name,
|
||||||
|
NULL AS owner_device_id
|
||||||
|
FROM network_outlet_ports nop
|
||||||
|
JOIN network_outlets no ON no.id = nop.outlet_id
|
||||||
|
LEFT JOIN rooms r ON r.id = no.room_id
|
||||||
|
LEFT JOIN floors f ON f.id = r.floor_id
|
||||||
|
UNION ALL
|
||||||
|
SELECT
|
||||||
|
'floor_patchpanel' AS endpoint_type,
|
||||||
|
fpp.id AS endpoint_id,
|
||||||
|
fpp.name AS port_name,
|
||||||
|
CONCAT(fp.name, ' / ', IFNULL(f.name, '')) AS owner_name,
|
||||||
|
NULL AS owner_device_id
|
||||||
|
FROM floor_patchpanel_ports fpp
|
||||||
|
JOIN floor_patchpanels fp ON fp.id = fpp.patchpanel_id
|
||||||
|
LEFT JOIN floors f ON f.id = fp.floor_id
|
||||||
|
";
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
// WHERE-Clause bauen
|
// WHERE-Clause bauen
|
||||||
// =========================
|
// =========================
|
||||||
@@ -22,7 +65,7 @@ $types = '';
|
|||||||
$params = [];
|
$params = [];
|
||||||
|
|
||||||
if ($search !== '') {
|
if ($search !== '') {
|
||||||
$where[] = "(d1.name LIKE ? OR d2.name LIKE ? OR dpt1.name LIKE ? OR dpt2.name LIKE ?)";
|
$where[] = "(e1.owner_name LIKE ? OR e2.owner_name LIKE ? OR e1.port_name LIKE ? OR e2.port_name LIKE ?)";
|
||||||
$types .= "ssss";
|
$types .= "ssss";
|
||||||
$params[] = "%$search%";
|
$params[] = "%$search%";
|
||||||
$params[] = "%$search%";
|
$params[] = "%$search%";
|
||||||
@@ -31,7 +74,7 @@ if ($search !== '') {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ($deviceId > 0) {
|
if ($deviceId > 0) {
|
||||||
$where[] = "(d1.id = ? OR d2.id = ?)";
|
$where[] = "(e1.owner_device_id = ? OR e2.owner_device_id = ?)";
|
||||||
$types .= "ii";
|
$types .= "ii";
|
||||||
$params[] = $deviceId;
|
$params[] = $deviceId;
|
||||||
$params[] = $deviceId;
|
$params[] = $deviceId;
|
||||||
@@ -46,19 +89,35 @@ $connections = $sql->get(
|
|||||||
"SELECT
|
"SELECT
|
||||||
c.id,
|
c.id,
|
||||||
c.port_a_type, c.port_a_id, c.port_b_type, c.port_b_id,
|
c.port_a_type, c.port_a_id, c.port_b_type, c.port_b_id,
|
||||||
d1.name AS device_a_name,
|
e1.owner_name AS endpoint_a_name,
|
||||||
d2.name AS device_b_name,
|
e2.owner_name AS endpoint_b_name,
|
||||||
dpt1.name AS port_a_name,
|
e1.port_name AS port_a_name,
|
||||||
dpt2.name AS port_b_name,
|
e2.port_name AS port_b_name,
|
||||||
c.vlan_config,
|
c.vlan_config,
|
||||||
c.comment
|
c.comment
|
||||||
FROM connections c
|
FROM connections c
|
||||||
LEFT JOIN device_ports dpt1 ON c.port_a_type = 'device' AND c.port_a_id = dpt1.id
|
LEFT JOIN ($endpointUnionSql) e1
|
||||||
LEFT JOIN devices d1 ON dpt1.device_id = d1.id
|
ON c.port_a_id = e1.endpoint_id
|
||||||
LEFT JOIN device_ports dpt2 ON c.port_b_type = 'device' AND c.port_b_id = dpt2.id
|
AND (
|
||||||
LEFT JOIN devices d2 ON dpt2.device_id = d2.id
|
c.port_a_type = e1.endpoint_type
|
||||||
|
OR (c.port_a_type = 'device_ports' AND e1.endpoint_type = 'device')
|
||||||
|
OR (c.port_a_type = 'module_ports' AND e1.endpoint_type = 'module')
|
||||||
|
OR (c.port_a_type = 'network_outlet_ports' AND e1.endpoint_type = 'outlet')
|
||||||
|
OR (c.port_a_type = 'floor_patchpanel_ports' AND e1.endpoint_type = 'floor_patchpanel')
|
||||||
|
OR (c.port_a_type = 'patchpanel' AND e1.endpoint_type = 'floor_patchpanel')
|
||||||
|
)
|
||||||
|
LEFT JOIN ($endpointUnionSql) e2
|
||||||
|
ON c.port_b_id = e2.endpoint_id
|
||||||
|
AND (
|
||||||
|
c.port_b_type = e2.endpoint_type
|
||||||
|
OR (c.port_b_type = 'device_ports' AND e2.endpoint_type = 'device')
|
||||||
|
OR (c.port_b_type = 'module_ports' AND e2.endpoint_type = 'module')
|
||||||
|
OR (c.port_b_type = 'network_outlet_ports' AND e2.endpoint_type = 'outlet')
|
||||||
|
OR (c.port_b_type = 'floor_patchpanel_ports' AND e2.endpoint_type = 'floor_patchpanel')
|
||||||
|
OR (c.port_b_type = 'patchpanel' AND e2.endpoint_type = 'floor_patchpanel')
|
||||||
|
)
|
||||||
$whereSql
|
$whereSql
|
||||||
ORDER BY d1.name, d2.name",
|
ORDER BY e1.owner_name, e2.owner_name",
|
||||||
$types,
|
$types,
|
||||||
$params
|
$params
|
||||||
);
|
);
|
||||||
@@ -84,29 +143,65 @@ if ($deviceId > 0) {
|
|||||||
|
|
||||||
if ($selectedDevice) {
|
if ($selectedDevice) {
|
||||||
$selectedDevice['port_count'] = (int)($sql->single(
|
$selectedDevice['port_count'] = (int)($sql->single(
|
||||||
"SELECT COUNT(*) AS cnt FROM device_ports WHERE device_id = ?",
|
"SELECT COUNT(*) AS cnt
|
||||||
"i",
|
FROM (
|
||||||
[$deviceId]
|
SELECT dp.id
|
||||||
|
FROM device_ports dp
|
||||||
|
WHERE dp.device_id = ?
|
||||||
|
UNION ALL
|
||||||
|
SELECT mp.id
|
||||||
|
FROM module_ports mp
|
||||||
|
JOIN modules m ON m.id = mp.module_id
|
||||||
|
WHERE m.device_id = ?
|
||||||
|
) p",
|
||||||
|
"ii",
|
||||||
|
[$deviceId, $deviceId]
|
||||||
)['cnt'] ?? 0);
|
)['cnt'] ?? 0);
|
||||||
|
|
||||||
$selectedDevice['connection_count'] = (int)($sql->single(
|
$selectedDevice['connection_count'] = (int)($sql->single(
|
||||||
"SELECT COUNT(DISTINCT c.id) AS cnt
|
"SELECT COUNT(DISTINCT c.id) AS cnt
|
||||||
FROM connections c
|
FROM connections c
|
||||||
LEFT JOIN device_ports dpt1 ON c.port_a_type = 'device' AND c.port_a_id = dpt1.id
|
LEFT JOIN ($endpointUnionSql) e1
|
||||||
LEFT JOIN device_ports dpt2 ON c.port_b_type = 'device' AND c.port_b_id = dpt2.id
|
ON c.port_a_id = e1.endpoint_id
|
||||||
WHERE dpt1.device_id = ? OR dpt2.device_id = ?",
|
AND (
|
||||||
|
c.port_a_type = e1.endpoint_type
|
||||||
|
OR (c.port_a_type = 'device_ports' AND e1.endpoint_type = 'device')
|
||||||
|
OR (c.port_a_type = 'module_ports' AND e1.endpoint_type = 'module')
|
||||||
|
OR (c.port_a_type = 'network_outlet_ports' AND e1.endpoint_type = 'outlet')
|
||||||
|
OR (c.port_a_type = 'floor_patchpanel_ports' AND e1.endpoint_type = 'floor_patchpanel')
|
||||||
|
OR (c.port_a_type = 'patchpanel' AND e1.endpoint_type = 'floor_patchpanel')
|
||||||
|
)
|
||||||
|
LEFT JOIN ($endpointUnionSql) e2
|
||||||
|
ON c.port_b_id = e2.endpoint_id
|
||||||
|
AND (
|
||||||
|
c.port_b_type = e2.endpoint_type
|
||||||
|
OR (c.port_b_type = 'device_ports' AND e2.endpoint_type = 'device')
|
||||||
|
OR (c.port_b_type = 'module_ports' AND e2.endpoint_type = 'module')
|
||||||
|
OR (c.port_b_type = 'network_outlet_ports' AND e2.endpoint_type = 'outlet')
|
||||||
|
OR (c.port_b_type = 'floor_patchpanel_ports' AND e2.endpoint_type = 'floor_patchpanel')
|
||||||
|
OR (c.port_b_type = 'patchpanel' AND e2.endpoint_type = 'floor_patchpanel')
|
||||||
|
)
|
||||||
|
WHERE e1.owner_device_id = ? OR e2.owner_device_id = ?",
|
||||||
"ii",
|
"ii",
|
||||||
[$deviceId, $deviceId]
|
[$deviceId, $deviceId]
|
||||||
)['cnt'] ?? 0);
|
)['cnt'] ?? 0);
|
||||||
|
|
||||||
$selectedDevicePorts = $sql->get(
|
$selectedDevicePorts = $sql->get(
|
||||||
"SELECT name, vlan_config
|
"SELECT name, vlan_config
|
||||||
FROM device_ports
|
FROM (
|
||||||
WHERE device_id = ?
|
SELECT dp.name, dp.vlan_config, dp.id AS sort_id
|
||||||
ORDER BY id
|
FROM device_ports dp
|
||||||
|
WHERE dp.device_id = ?
|
||||||
|
UNION ALL
|
||||||
|
SELECT CONCAT(m.name, ' / ', mp.name) AS name, NULL AS vlan_config, (1000000 + mp.id) AS sort_id
|
||||||
|
FROM module_ports mp
|
||||||
|
JOIN modules m ON m.id = mp.module_id
|
||||||
|
WHERE m.device_id = ?
|
||||||
|
) p
|
||||||
|
ORDER BY sort_id
|
||||||
LIMIT 12",
|
LIMIT 12",
|
||||||
"i",
|
"ii",
|
||||||
[$deviceId]
|
[$deviceId, $deviceId]
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach ($selectedDevicePorts as $port) {
|
foreach ($selectedDevicePorts as $port) {
|
||||||
@@ -179,7 +274,7 @@ if ($deviceId > 0) {
|
|||||||
<?php foreach ($connections as $conn): ?>
|
<?php foreach ($connections as $conn): ?>
|
||||||
<?php
|
<?php
|
||||||
$comment = trim($conn['comment'] ?? '');
|
$comment = trim($conn['comment'] ?? '');
|
||||||
$hasMissingInfo = empty($conn['device_a_name']) || empty($conn['device_b_name'])
|
$hasMissingInfo = empty($conn['endpoint_a_name']) || empty($conn['endpoint_b_name'])
|
||||||
|| empty($conn['port_a_name']) || empty($conn['port_b_name']);
|
|| empty($conn['port_a_name']) || empty($conn['port_b_name']);
|
||||||
$commentLower = mb_strtolower($comment, 'UTF-8');
|
$commentLower = mb_strtolower($comment, 'UTF-8');
|
||||||
$warningFromComment = preg_match('/warn|achtung|critical/', $commentLower);
|
$warningFromComment = preg_match('/warn|achtung|critical/', $commentLower);
|
||||||
@@ -187,12 +282,12 @@ if ($deviceId > 0) {
|
|||||||
?>
|
?>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<strong><?php echo htmlspecialchars($conn['device_a_name'] ?? 'N/A'); ?></strong><br>
|
<strong><?php echo htmlspecialchars($conn['endpoint_a_name'] ?? 'N/A'); ?></strong><br>
|
||||||
<small><?php echo htmlspecialchars($conn['port_a_name'] ?? '—'); ?></small>
|
<small><?php echo htmlspecialchars($conn['port_a_name'] ?? '—'); ?></small>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<strong><?php echo htmlspecialchars($conn['device_b_name'] ?? 'N/A'); ?></strong><br>
|
<strong><?php echo htmlspecialchars($conn['endpoint_b_name'] ?? 'N/A'); ?></strong><br>
|
||||||
<small><?php echo htmlspecialchars($conn['port_b_name'] ?? '—'); ?></small>
|
<small><?php echo htmlspecialchars($conn['port_b_name'] ?? '—'); ?></small>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,25 @@ $portBId = (int)($_POST['port_b_id'] ?? 0);
|
|||||||
$vlanConfig = $_POST['vlan_config'] ?? '';
|
$vlanConfig = $_POST['vlan_config'] ?? '';
|
||||||
$comment = trim($_POST['comment'] ?? '');
|
$comment = trim($_POST['comment'] ?? '');
|
||||||
|
|
||||||
|
$normalizePortType = static function (string $value): string {
|
||||||
|
$map = [
|
||||||
|
'device' => 'device',
|
||||||
|
'device_ports' => 'device',
|
||||||
|
'module' => 'module',
|
||||||
|
'module_ports' => 'module',
|
||||||
|
'outlet' => 'outlet',
|
||||||
|
'network_outlet_ports' => 'outlet',
|
||||||
|
'patchpanel' => 'patchpanel',
|
||||||
|
'floor_patchpanel' => 'patchpanel',
|
||||||
|
'floor_patchpanel_ports' => 'patchpanel',
|
||||||
|
];
|
||||||
|
$key = strtolower(trim($value));
|
||||||
|
return $map[$key] ?? $key;
|
||||||
|
};
|
||||||
|
|
||||||
|
$portAType = $normalizePortType((string)$portAType);
|
||||||
|
$portBType = $normalizePortType((string)$portBType);
|
||||||
|
|
||||||
// =========================
|
// =========================
|
||||||
// Validierung (einfach)
|
// Validierung (einfach)
|
||||||
// =========================
|
// =========================
|
||||||
|
|||||||
Reference in New Issue
Block a user