Erlaube feste Verdrahtung plus Patchkabel fuer Outlet/Patchpanel
closes #26
This commit is contained in:
1
NEXT.md
1
NEXT.md
@@ -1,6 +1,7 @@
|
|||||||
# NEXT_STEPS
|
# NEXT_STEPS
|
||||||
|
|
||||||
## Aktive Aufgaben (priorisiert)
|
## Aktive Aufgaben (priorisiert)
|
||||||
|
- [x] [#26] patchfelder haben natürlich auf den gleichen port eine feste verdrahtung und dann ein patchkabel zum switch, bei wand buchsen muss das auch erlaubt sein
|
||||||
- [x] [#24] infrastruktur stockerkkarte zoomen wird die grundrisskarten overlay nicht mitgezoomt
|
- [x] [#24] infrastruktur stockerkkarte zoomen wird die grundrisskarten overlay nicht mitgezoomt
|
||||||
- [x] [#23] netzwerkdosen haben nur port 1 und brauche in den auswahlen nicht mit port 1 angezeigt zu werden
|
- [x] [#23] netzwerkdosen haben nur port 1 und brauche in den auswahlen nicht mit port 1 angezeigt zu werden
|
||||||
- [x] [#22] für neue verbindungen nur ports anbieten die noch keine verbingung haben
|
- [x] [#22] für neue verbindungen nur ports anbieten die noch keine verbingung haben
|
||||||
|
|||||||
@@ -90,6 +90,87 @@ function isTopologyPairAllowed(string $typeA, string $typeB): bool
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildEndpointUsageMap($sql, int $excludeConnectionId = 0): array
|
||||||
|
{
|
||||||
|
$usage = [
|
||||||
|
'device' => [],
|
||||||
|
'module' => [],
|
||||||
|
'outlet' => [],
|
||||||
|
'patchpanel' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
$rows = $sql->get(
|
||||||
|
"SELECT id, port_a_type, port_a_id, port_b_type, port_b_id
|
||||||
|
FROM connections
|
||||||
|
WHERE id <> ?",
|
||||||
|
'i',
|
||||||
|
[$excludeConnectionId]
|
||||||
|
);
|
||||||
|
|
||||||
|
$track = static function (string $endpointType, int $endpointId, string $otherType) use (&$usage): void {
|
||||||
|
if ($endpointId <= 0 || !isset($usage[$endpointType])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!isset($usage[$endpointType][$endpointId])) {
|
||||||
|
$usage[$endpointType][$endpointId] = [
|
||||||
|
'total' => 0,
|
||||||
|
'fixed' => 0,
|
||||||
|
'patch' => 0,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$usage[$endpointType][$endpointId]['total']++;
|
||||||
|
if (in_array($endpointType, ['outlet', 'patchpanel'], true)) {
|
||||||
|
if (in_array($otherType, ['outlet', 'patchpanel'], true)) {
|
||||||
|
$usage[$endpointType][$endpointId]['fixed']++;
|
||||||
|
} elseif (in_array($otherType, ['device', 'module'], true)) {
|
||||||
|
$usage[$endpointType][$endpointId]['patch']++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach ((array)$rows as $row) {
|
||||||
|
$typeA = normalizeEndpointType((string)($row['port_a_type'] ?? ''));
|
||||||
|
$typeB = normalizeEndpointType((string)($row['port_b_type'] ?? ''));
|
||||||
|
$idA = (int)($row['port_a_id'] ?? 0);
|
||||||
|
$idB = (int)($row['port_b_id'] ?? 0);
|
||||||
|
if ($typeA === null || $typeB === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$track($typeA, $idA, $typeB);
|
||||||
|
$track($typeB, $idB, $typeA);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateEndpointCapacity(array $usage, string $endpointType, int $endpointId, string $otherType, string $label): ?string
|
||||||
|
{
|
||||||
|
if ($endpointId <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$stats = $usage[$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';
|
||||||
|
}
|
||||||
|
|
||||||
function loadConnections($sql): void
|
function loadConnections($sql): void
|
||||||
{
|
{
|
||||||
$contextType = strtolower(trim((string)($_GET['context_type'] ?? 'all')));
|
$contextType = strtolower(trim((string)($_GET['context_type'] ?? 'all')));
|
||||||
@@ -226,9 +307,20 @@ function saveConnection($sql): void
|
|||||||
$mode = isset($data['mode']) ? (string)$data['mode'] : null;
|
$mode = isset($data['mode']) ? (string)$data['mode'] : null;
|
||||||
$comment = isset($data['comment']) ? (string)$data['comment'] : null;
|
$comment = isset($data['comment']) ? (string)$data['comment'] : null;
|
||||||
|
|
||||||
if (!empty($data['id'])) {
|
$connectionId = !empty($data['id']) ? (int)$data['id'] : 0;
|
||||||
$id = (int)$data['id'];
|
$usage = buildEndpointUsageMap($sql, $connectionId);
|
||||||
$existing = $sql->single('SELECT id FROM connections WHERE id = ?', 'i', [$id]);
|
$capacityErrorA = validateEndpointCapacity($usage, $portAType, $portAId, $portBType, 'Port an Endpunkt A');
|
||||||
|
if ($capacityErrorA !== null) {
|
||||||
|
jsonError($capacityErrorA, 409);
|
||||||
|
}
|
||||||
|
$capacityErrorB = validateEndpointCapacity($usage, $portBType, $portBId, $portAType, 'Port an Endpunkt B');
|
||||||
|
if ($capacityErrorB !== null) {
|
||||||
|
jsonError($capacityErrorB, 409);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($connectionId > 0) {
|
||||||
|
$id = $connectionId;
|
||||||
|
$existing = $sql->single('SELECT id FROM connections WHERE id = ?', 'i', [$connectionId]);
|
||||||
if (!$existing) {
|
if (!$existing) {
|
||||||
jsonError('Verbindung existiert nicht', 404);
|
jsonError('Verbindung existiert nicht', 404);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ $endpointOptions = [
|
|||||||
'patchpanel' => [],
|
'patchpanel' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
$occupiedByType = [
|
$occupiedStatsByType = [
|
||||||
'device' => [],
|
'device' => [],
|
||||||
'module' => [],
|
'module' => [],
|
||||||
'outlet' => [],
|
'outlet' => [],
|
||||||
@@ -62,18 +62,24 @@ $occupiedRows = $sql->get(
|
|||||||
foreach ((array)$occupiedRows as $row) {
|
foreach ((array)$occupiedRows as $row) {
|
||||||
$typeA = $normalizePortType((string)($row['port_a_type'] ?? ''));
|
$typeA = $normalizePortType((string)($row['port_a_type'] ?? ''));
|
||||||
$idA = (int)($row['port_a_id'] ?? 0);
|
$idA = (int)($row['port_a_id'] ?? 0);
|
||||||
if ($idA > 0 && isset($occupiedByType[$typeA])) {
|
if ($idA > 0 && isset($occupiedStatsByType[$typeA])) {
|
||||||
$occupiedByType[$typeA][$idA] = true;
|
if (!isset($occupiedStatsByType[$typeA][$idA])) {
|
||||||
|
$occupiedStatsByType[$typeA][$idA] = ['total' => 0];
|
||||||
|
}
|
||||||
|
$occupiedStatsByType[$typeA][$idA]['total']++;
|
||||||
}
|
}
|
||||||
|
|
||||||
$typeB = $normalizePortType((string)($row['port_b_type'] ?? ''));
|
$typeB = $normalizePortType((string)($row['port_b_type'] ?? ''));
|
||||||
$idB = (int)($row['port_b_id'] ?? 0);
|
$idB = (int)($row['port_b_id'] ?? 0);
|
||||||
if ($idB > 0 && isset($occupiedByType[$typeB])) {
|
if ($idB > 0 && isset($occupiedStatsByType[$typeB])) {
|
||||||
$occupiedByType[$typeB][$idB] = true;
|
if (!isset($occupiedStatsByType[$typeB][$idB])) {
|
||||||
|
$occupiedStatsByType[$typeB][$idB] = ['total' => 0];
|
||||||
|
}
|
||||||
|
$occupiedStatsByType[$typeB][$idB]['total']++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$isEndpointAllowed = static function (string $type, int $id) use ($occupiedByType, $portAType, $portAId, $portBType, $portBId): bool {
|
$isEndpointAllowed = static function (string $type, int $id) use ($occupiedStatsByType, $portAType, $portAId, $portBType, $portBId): bool {
|
||||||
if ($id <= 0) {
|
if ($id <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -83,7 +89,10 @@ $isEndpointAllowed = static function (string $type, int $id) use ($occupiedByTyp
|
|||||||
if ($type === $portBType && $id === $portBId) {
|
if ($type === $portBType && $id === $portBId) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return empty($occupiedByType[$type][$id]);
|
|
||||||
|
$stats = $occupiedStatsByType[$type][$id] ?? ['total' => 0];
|
||||||
|
$maxConnections = in_array($type, ['outlet', 'patchpanel'], true) ? 2 : 1;
|
||||||
|
return (int)($stats['total'] ?? 0) < $maxConnections;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Auto-heal: ensure each outlet has at least one selectable port.
|
// Auto-heal: ensure each outlet has at least one selectable port.
|
||||||
|
|||||||
@@ -75,16 +75,26 @@ $otherConnections = $sql->get(
|
|||||||
);
|
);
|
||||||
|
|
||||||
$endpointUsage = [];
|
$endpointUsage = [];
|
||||||
$trackUsage = static function (string $endpointType, int $endpointId) use (&$endpointUsage): void {
|
$trackUsage = static function (string $endpointType, int $endpointId, string $otherType) use (&$endpointUsage): void {
|
||||||
if ($endpointId <= 0) {
|
if ($endpointId <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!isset($endpointUsage[$endpointType][$endpointId])) {
|
if (!isset($endpointUsage[$endpointType][$endpointId])) {
|
||||||
$endpointUsage[$endpointType][$endpointId] = [
|
$endpointUsage[$endpointType][$endpointId] = [
|
||||||
'total' => 0,
|
'total' => 0,
|
||||||
|
'fixed' => 0,
|
||||||
|
'patch' => 0,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
$endpointUsage[$endpointType][$endpointId]['total']++;
|
$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) {
|
foreach ((array)$otherConnections as $row) {
|
||||||
@@ -93,29 +103,42 @@ foreach ((array)$otherConnections as $row) {
|
|||||||
$idA = (int)($row['port_a_id'] ?? 0);
|
$idA = (int)($row['port_a_id'] ?? 0);
|
||||||
$idB = (int)($row['port_b_id'] ?? 0);
|
$idB = (int)($row['port_b_id'] ?? 0);
|
||||||
|
|
||||||
$trackUsage($typeA, $idA);
|
$trackUsage($typeA, $idA, $typeB);
|
||||||
$trackUsage($typeB, $idB);
|
$trackUsage($typeB, $idB, $typeA);
|
||||||
}
|
}
|
||||||
|
|
||||||
$validateEndpointUsage = static function (string $endpointType, int $endpointId, string $label) use ($endpointUsage): ?string {
|
$validateEndpointUsage = static function (string $endpointType, int $endpointId, string $otherType, string $label) use ($endpointUsage): ?string {
|
||||||
if ($endpointId <= 0) {
|
if ($endpointId <= 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$stats = $endpointUsage[$endpointType][$endpointId] ?? ['total' => 0];
|
$stats = $endpointUsage[$endpointType][$endpointId] ?? ['total' => 0, 'fixed' => 0, 'patch' => 0];
|
||||||
if ((int)$stats['total'] <= 0) {
|
if ((int)$stats['total'] <= 0) {
|
||||||
return null;
|
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";
|
return $label . " ist bereits in Verwendung";
|
||||||
};
|
};
|
||||||
|
|
||||||
$errorA = $validateEndpointUsage($portAType, $portAId, 'Port an Endpunkt A');
|
$errorA = $validateEndpointUsage($portAType, $portAId, $portBType, 'Port an Endpunkt A');
|
||||||
if ($errorA !== null) {
|
if ($errorA !== null) {
|
||||||
$errors[] = $errorA;
|
$errors[] = $errorA;
|
||||||
}
|
}
|
||||||
|
|
||||||
$errorB = $validateEndpointUsage($portBType, $portBId, 'Port an Endpunkt B');
|
$errorB = $validateEndpointUsage($portBType, $portBId, $portAType, 'Port an Endpunkt B');
|
||||||
if ($errorB !== null) {
|
if ($errorB !== null) {
|
||||||
$errors[] = $errorB;
|
$errors[] = $errorB;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user