204 lines
6.6 KiB
PHP
204 lines
6.6 KiB
PHP
<?php
|
|
/**
|
|
* app/modules/connections/save.php
|
|
*
|
|
* Speichert / aktualisiert eine Netzwerkverbindung
|
|
* (Basis-Implementierung - kann erweitert werden)
|
|
*/
|
|
|
|
// Nur POST
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
|
header('Location: ?module=connections&action=list');
|
|
exit;
|
|
}
|
|
|
|
// =========================
|
|
// Daten einlesen
|
|
// =========================
|
|
$connId = (int)($_POST['id'] ?? 0);
|
|
$portAType = $_POST['port_a_type'] ?? 'device';
|
|
$portAId = (int)($_POST['port_a_id'] ?? 0);
|
|
$portBType = $_POST['port_b_type'] ?? 'device';
|
|
$portBId = (int)($_POST['port_b_id'] ?? 0);
|
|
$vlanConfig = $_POST['vlan_config'] ?? '';
|
|
$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);
|
|
|
|
$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)
|
|
// =========================
|
|
$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
|
|
FROM connections
|
|
WHERE id <> ?",
|
|
"i",
|
|
[$connId]
|
|
);
|
|
|
|
$endpointUsage = [];
|
|
$trackUsage = static function (string $endpointType, int $endpointId, string $otherType) use (&$endpointUsage): void {
|
|
if ($endpointId <= 0) {
|
|
return;
|
|
}
|
|
if (!isset($endpointUsage[$endpointType][$endpointId])) {
|
|
$endpointUsage[$endpointType][$endpointId] = [
|
|
'total' => 0,
|
|
'fixed' => 0,
|
|
'patch' => 0,
|
|
];
|
|
}
|
|
$endpointUsage[$endpointType][$endpointId]['total']++;
|
|
|
|
if (in_array($endpointType, ['outlet', 'patchpanel'], true)) {
|
|
if (in_array($otherType, ['outlet', 'patchpanel'], true)) {
|
|
$endpointUsage[$endpointType][$endpointId]['fixed']++;
|
|
} elseif (in_array($otherType, ['device', 'module'], true)) {
|
|
$endpointUsage[$endpointType][$endpointId]['patch']++;
|
|
}
|
|
}
|
|
};
|
|
|
|
foreach ((array)$otherConnections as $row) {
|
|
$typeA = $normalizePortType((string)($row['port_a_type'] ?? ''));
|
|
$typeB = $normalizePortType((string)($row['port_b_type'] ?? ''));
|
|
$idA = (int)($row['port_a_id'] ?? 0);
|
|
$idB = (int)($row['port_b_id'] ?? 0);
|
|
|
|
$trackUsage($typeA, $idA, $typeB);
|
|
$trackUsage($typeB, $idB, $typeA);
|
|
}
|
|
|
|
$validateEndpointUsage = static function (string $endpointType, int $endpointId, string $otherType, string $label) use ($endpointUsage): ?string {
|
|
if ($endpointId <= 0) {
|
|
return null;
|
|
}
|
|
|
|
$stats = $endpointUsage[$endpointType][$endpointId] ?? ['total' => 0, 'fixed' => 0, 'patch' => 0];
|
|
if ((int)$stats['total'] <= 0) {
|
|
return null;
|
|
}
|
|
|
|
if (in_array($endpointType, ['outlet', 'patchpanel'], true)) {
|
|
if ((int)$stats['total'] >= 2) {
|
|
return $label . " hat bereits die maximale Anzahl von 2 Verbindungen";
|
|
}
|
|
if (in_array($otherType, ['outlet', 'patchpanel'], true) && (int)$stats['fixed'] >= 1) {
|
|
return $label . " hat bereits eine feste Verdrahtung";
|
|
}
|
|
if (in_array($otherType, ['device', 'module'], true) && (int)$stats['patch'] >= 1) {
|
|
return $label . " hat bereits ein Patchkabel";
|
|
}
|
|
return null;
|
|
}
|
|
|
|
return $label . " ist bereits in Verwendung";
|
|
};
|
|
|
|
$errorA = $validateEndpointUsage($portAType, $portAId, $portBType, 'Port an Endpunkt A');
|
|
if ($errorA !== null) {
|
|
$errors[] = $errorA;
|
|
}
|
|
|
|
$errorB = $validateEndpointUsage($portBType, $portBId, $portAType, 'Port an Endpunkt B');
|
|
if ($errorB !== null) {
|
|
$errors[] = $errorB;
|
|
}
|
|
|
|
if (!empty($errors)) {
|
|
$_SESSION['error'] = implode(', ', $errors);
|
|
$_SESSION['validation_errors'] = $errors;
|
|
$redirectUrl = $connId ? "?module=connections&action=edit&id=$connId" : "?module=connections&action=edit";
|
|
header("Location: $redirectUrl");
|
|
exit;
|
|
}
|
|
|
|
// =========================
|
|
// In DB speichern
|
|
// =========================
|
|
$vlanJson = $vlanConfig ? json_encode(explode(',', $vlanConfig)) : null;
|
|
|
|
if ($connId > 0) {
|
|
// UPDATE
|
|
$sql->set(
|
|
"UPDATE connections SET port_a_type = ?, port_a_id = ?, port_b_type = ?, port_b_id = ?, vlan_config = ?, comment = ? WHERE id = ?",
|
|
"sisissi",
|
|
[$portAType, $portAId, $portBType, $portBId, $vlanJson, $comment, $connId]
|
|
);
|
|
} else {
|
|
$connectionTypeId = (int)($sql->single(
|
|
"SELECT id FROM connection_types ORDER BY id LIMIT 1",
|
|
"",
|
|
[]
|
|
)['id'] ?? 0);
|
|
|
|
if ($connectionTypeId <= 0) {
|
|
$connectionTypeId = (int)$sql->set(
|
|
"INSERT INTO connection_types (name, medium, duplex, line_style, comment) VALUES (?, ?, ?, ?, ?)",
|
|
"sssss",
|
|
['Default', 'copper', 'custom', 'solid', 'Auto-created by connections/save'],
|
|
true
|
|
);
|
|
}
|
|
|
|
if ($connectionTypeId <= 0) {
|
|
$_SESSION['error'] = "Kein Verbindungstyp verfuegbar";
|
|
$_SESSION['validation_errors'] = ["Kein Verbindungstyp verfuegbar"];
|
|
header("Location: ?module=connections&action=edit");
|
|
exit;
|
|
}
|
|
|
|
// INSERT
|
|
$sql->set(
|
|
"INSERT INTO connections (connection_type_id, port_a_type, port_a_id, port_b_type, port_b_id, vlan_config, comment) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
"isisiss",
|
|
[$connectionTypeId, $portAType, $portAId, $portBType, $portBId, $vlanJson, $comment]
|
|
);
|
|
}
|
|
|
|
$_SESSION['success'] = "Verbindung gespeichert";
|
|
|
|
// =========================
|
|
// Redirect
|
|
// =========================
|
|
header('Location: ?module=connections&action=list');
|
|
exit;
|