Remove test.php and enhance null safety and sorting across components
- Deleted `test.php` as it was no longer in use. - Enhanced null safety checks in `Inventory.php`, `StdOut-detail.php`, `Backups.php`, and `SwitchsSAN.php` to prevent potential warnings. - Refactored `SwitchsSAN.php` to improve sorting logic for ports based on errors, vFabric, and Port ID. - Added seasonal snow effect script in `all.php` with toggle functionality for user engagement. - Updated navigation bar (`navbar.html`) to include a new VIO page link. - Introduced a new `VIO.php` page to display VIO monitoring details with table export and sorting features.
This commit is contained in:
@@ -79,69 +79,87 @@
|
||||
|
||||
<tbody> <!-- Body -->
|
||||
<?php
|
||||
// get all active servers
|
||||
$today = date("Y-m-d");
|
||||
$active = Invoke_Infra("SELECT name from cmdb_vms where LastInventory like'$today%'");
|
||||
$active = array_column($active, 'name');
|
||||
|
||||
// NO Backup or Backup with Errors
|
||||
$er = 0;
|
||||
$answers = Invoke_infra("SELECT * FROM VMs_Backup where ( Owner like 'DUN-VMH%' or Owner like 'MDK-VMH%' ) and name not like 'WS%' and owner not like '%WKG%' and owner not like '%VMH-WM%' and Exclusion ='' and (LastResult <> 'OK' or lastresult is null) and policy is not null order by lastresult,name");
|
||||
foreach ($answers as $row) {
|
||||
if(in_array($row['Name'], $active)){
|
||||
$er++;
|
||||
$date1 = date_create($row['LastKnownGood']??'01/01/1970'); $diff = date_diff($date1, date_create(date("Y-m-d")));
|
||||
if ($diff->format("%R%a") >= 2 || $row['LastKnownGood'] == ''){
|
||||
$date1 = date_create($row['LastKnownGood'] ?? '01/01/1970');
|
||||
$diff = date_diff($date1, date_create(date("Y-m-d")));
|
||||
if ($diff->format("%R%a") >= 2 || $row['LastKnownGood'] == '') {
|
||||
echo "<tr class='table-danger'>";
|
||||
}else{
|
||||
} else {
|
||||
echo "<tr class='table-warning'>";
|
||||
}
|
||||
if($diff->format("%R%a") == "-0"){$LastGood = "NEVER";}else{$LastGood = $row['LastKnownGood']." (".$diff->format("%R%a")."J)";}
|
||||
echo "<td><b>".$row['Name']."<b></td>";
|
||||
echo "<td>".$row['LastBackup']." ".$row['TimeStamp']."</td>";
|
||||
echo "<td>".$row['LastResult']."</td>";
|
||||
echo "<td>".$LastGood."</td>";
|
||||
echo "<td>".$row['LastSize']."</td>";
|
||||
echo "<td>".$row['Owner']."</td>";
|
||||
echo "<td>".$row['Policy']."</td>";
|
||||
if ($diff->format("%R%a") == "-0") {
|
||||
$LastGood = "NEVER";
|
||||
} else {
|
||||
$LastGood = $row['LastKnownGood'] . " (" . $diff->format("%R%a") . "J)";
|
||||
}
|
||||
echo "<td><b>" . $row['Name'] . "<b></td>";
|
||||
echo "<td>" . $row['LastBackup'] . " " . $row['TimeStamp'] . "</td>";
|
||||
echo "<td>" . $row['LastResult'] . "</td>";
|
||||
echo "<td>" . $LastGood . "</td>";
|
||||
echo "<td>" . $row['LastSize'] . "</td>";
|
||||
echo "<td>" . $row['Owner'] . "</td>";
|
||||
echo "<td>" . $row['Policy'] . "</td>";
|
||||
|
||||
echo "</tr>";
|
||||
}
|
||||
}
|
||||
|
||||
// Outdated
|
||||
$outdated = 0;
|
||||
$answers = Invoke_infra("SELECT * FROM VMs_Backup where ( Owner like 'DUN-VMH%' or Owner like 'MDK-VMH%' ) and name not like 'WS%' and owner not like '%WKG%' and owner not like '%VMH-WM%' and Exclusion ='' and LastResult = 'OK' and TRY_CAST(lastknowngood AS DATE) < CAST(DATEADD(DAY, -2, GETDATE()) AS DATE) order by name");
|
||||
foreach ($answers as $row) {
|
||||
$date1 = date_create($row['LastKnownGood']); $diff = date_diff($date1, date_create(date("Y-m-d")));
|
||||
if(date('w') >= 2 && date('w') <= 6 ){
|
||||
if ($diff->format("%R%a") >= 2){
|
||||
if (in_array($row['Name'], $active)) {
|
||||
$date1 = date_create($row['LastKnownGood']);
|
||||
$diff = date_diff($date1, date_create(date("Y-m-d")));
|
||||
if (date('w') >= 2 && date('w') <= 6) {
|
||||
if ($diff->format("%R%a") >= 2) {
|
||||
echo "<tr class='table-warning'>";
|
||||
}else{
|
||||
} else {
|
||||
echo "<tr class='table-success'>";
|
||||
}
|
||||
}else{
|
||||
if((date('w') < 2 || date('w') == 7)){
|
||||
if($diff->format("%R%a") <= 3){
|
||||
} else {
|
||||
if ((date('w') < 2 || date('w') == 7)) {
|
||||
if ($diff->format("%R%a") <= 3) {
|
||||
echo "<tr class='table-success'>";
|
||||
}else{
|
||||
} else {
|
||||
echo "<tr class='table-warning'>";
|
||||
}
|
||||
}
|
||||
}
|
||||
if($diff->format("%R%a") == "-0"){$LastGood = $row['LastKnownGood'];}else{$LastGood = $row['LastKnownGood']." (".$diff->format("%R%a")."J)";}
|
||||
echo "<td><b>".$row['Name']."<b></td>";
|
||||
echo "<td>".$row['LastBackup']." ".$row['TimeStamp']."</td>";
|
||||
echo "<td>".$row['LastResult']."</td>";
|
||||
if (date('w') >= 2 && date('w') <= 6 && $diff->format("%R%a") < 1){
|
||||
echo "<td>".$LastGood."</td>";
|
||||
}else{
|
||||
if ((date('w') == 1 || date('w') == 7) && $diff->format("%R%a") <= 3){
|
||||
echo "<td>".$LastGood."</td>";
|
||||
}else{
|
||||
echo "<td class='table-warning'>".$LastGood."</td>";
|
||||
if ($diff->format("%R%a") == "-0") {
|
||||
$LastGood = $row['LastKnownGood'];
|
||||
} else {
|
||||
$LastGood = $row['LastKnownGood'] . " (" . $diff->format("%R%a") . "J)";
|
||||
}
|
||||
echo "<td><b>" . $row['Name'] . "<b></td>";
|
||||
echo "<td>" . $row['LastBackup'] . " " . $row['TimeStamp'] . "</td>";
|
||||
echo "<td>" . $row['LastResult'] . "</td>";
|
||||
if (date('w') >= 2 && date('w') <= 6 && $diff->format("%R%a") < 1) {
|
||||
echo "<td>" . $LastGood . "</td>";
|
||||
} else {
|
||||
if ((date('w') == 1 || date('w') == 7) && $diff->format("%R%a") <= 3) {
|
||||
echo "<td>" . $LastGood . "</td>";
|
||||
} else {
|
||||
echo "<td class='table-warning'>" . $LastGood . "</td>";
|
||||
$outdated++;
|
||||
}
|
||||
}
|
||||
echo "<td>".$row['LastSize']."</td>";
|
||||
echo "<td>".$row['Owner']."</td>";
|
||||
echo "<td>".$row['Policy']."</td>";
|
||||
echo "<td>" . $row['LastSize'] . "</td>";
|
||||
echo "<td>" . $row['Owner'] . "</td>";
|
||||
echo "<td>" . $row['Policy'] . "</td>";
|
||||
echo "</tr>";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Backup OK
|
||||
$answers = Invoke_infra("SELECT * FROM VMs_Backup where ( Owner like 'DUN-VMH%' or Owner like 'MDK-VMH%' ) and name not like 'WS%' and owner not like '%WKG%' and owner not like '%VMH-WM%' and Exclusion ='' and LastResult = 'OK' and TRY_CAST(lastknowngood AS DATE) >= CAST(DATEADD(DAY, -2, GETDATE()) AS DATE) order by name");
|
||||
|
||||
@@ -14,11 +14,11 @@
|
||||
<link rel="stylesheet" href="/css/bootstrap-icons/bootstrap-icons.css">
|
||||
<script src="/js/bootstrap.bundle.min.js"></script>
|
||||
|
||||
<link rel="stylesheet" href="/css/bootstrap-table.min.css">
|
||||
<script src="/js/bootstrap-table.min.js"></script>
|
||||
<script src="/js/bootstrap-table-fr-FR.min.js"></script>
|
||||
|
||||
<style>
|
||||
/* Custom styles to match the previous JS rendering */
|
||||
.table-danger { background-color: #f8d7da !important; }
|
||||
.table-success { background-color: #d1e7dd !important; }
|
||||
/* Ensure text is readable on colored headers */
|
||||
.card-header a { text-decoration: none; color: white; display: block; width: 100%; }
|
||||
.card-header a:hover { color: #f0f0f0; }
|
||||
</style>
|
||||
@@ -26,13 +26,12 @@
|
||||
|
||||
<body class="bg-light text-dark">
|
||||
<?php
|
||||
// Include your existing libraries
|
||||
// Include global configurations
|
||||
include $_SERVER['DOCUMENT_ROOT'] . "/include/all.php";
|
||||
|
||||
// --- PHP LOGIC START ---
|
||||
|
||||
// 1. Fetch JSON Data
|
||||
// Ensure the PostJson function returns a valid JSON string
|
||||
$jsonString = PostJson("$bdnuss/Storage/BROCADE/PORT/BROCADE_PORT_LIST.php", '');
|
||||
|
||||
// 2. Decode to PHP Array
|
||||
@@ -40,7 +39,7 @@
|
||||
|
||||
// Check if decode was successful
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
$sanData = []; // Fallback to empty array to avoid errors
|
||||
$sanData = [];
|
||||
$errorMessage = "Error decoding JSON: " . json_last_error_msg();
|
||||
}
|
||||
?>
|
||||
@@ -62,42 +61,65 @@
|
||||
|
||||
<div id="accordion">
|
||||
<?php
|
||||
// 3. Loop through Switches
|
||||
// Loop through Switches
|
||||
if (!empty($sanData)) {
|
||||
$switchIndex = 0; // Iterator for unique IDs
|
||||
$switchIndex = 0;
|
||||
|
||||
foreach ($sanData as $switchName => $ports) {
|
||||
$switchIndex++;
|
||||
$collapseId = "collapse_" . $switchIndex; // Unique ID for Bootstrap
|
||||
$collapseId = "collapse_" . $switchIndex;
|
||||
|
||||
// Initialize counters
|
||||
// Inject PortID into the array content for easier sorting
|
||||
foreach ($ports as $k => $v) $ports[$k]['_PortID'] = $k;
|
||||
|
||||
// Custom Sort: Errors (Desc) > vFabric (Asc) > Port (Natural Asc)
|
||||
uasort($ports, function ($a, $b) {
|
||||
// Errors (Descending)
|
||||
$errA = (int)$a['Errors'];
|
||||
$errB = (int)$b['Errors'];
|
||||
if ($errA !== $errB) {
|
||||
return $errB <=> $errA;
|
||||
}
|
||||
|
||||
// vFabric (Ascending / Case Insensitive)
|
||||
$vfA = $a['vFabric'] ?? '';
|
||||
$vfB = $b['vFabric'] ?? '';
|
||||
$cmpVf = strcasecmp($vfA, $vfB);
|
||||
if ($cmpVf !== 0) {
|
||||
return $cmpVf;
|
||||
}
|
||||
|
||||
// Port ID (Natural Sort, e.g. 2 comes before 10)
|
||||
return strnatcmp($a['_PortID'], $b['_PortID']);
|
||||
});
|
||||
// Initialize counters & buffers
|
||||
$upCount = 0;
|
||||
$downCount = 0;
|
||||
$errorCount = 0;
|
||||
$tableBody = "";
|
||||
|
||||
// Arrays to store HTML rows (for sorting logic)
|
||||
$errorRows = [];
|
||||
$normalRows = [];
|
||||
|
||||
// 4. Loop through Ports to calculate stats and build rows
|
||||
// Generate HTML Rows based on sorted data
|
||||
foreach ($ports as $portId => $portData) {
|
||||
$state = $portData['State'];
|
||||
$errors = (int)$portData['Errors']; // Cast to int for safety
|
||||
$errors = (int)$portData['Errors'];
|
||||
|
||||
if ($state === 'UP') {
|
||||
$upCount++;
|
||||
if ($state === 'UP') $upCount++;
|
||||
elseif ($state === 'DN') $downCount++;
|
||||
|
||||
// Determine row color
|
||||
$rowClass = "table-success";
|
||||
if ($errors > 0) {
|
||||
$errorCount++;
|
||||
$rowClass = "table-danger";
|
||||
if ($errors > 0 && $state === 'UP') $errorCount++;
|
||||
|
||||
if ($state === 'DN') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Build the HTML for this row
|
||||
// Note: Using variables in double quotes for cleaner syntax
|
||||
$rowHtml = "
|
||||
// Determine Row CSS Class
|
||||
$rowClass = "table-success";
|
||||
if ($errors > 0) $rowClass = "table-danger";
|
||||
|
||||
// Build Row HTML
|
||||
$tableBody .= "
|
||||
<tr class='{$rowClass}'>
|
||||
<td>{$portData['vFabric']}</td>
|
||||
<td>{$portId}</td>
|
||||
<td>{$portData['Status']}</td>
|
||||
<td>{$portData['State']}</td>
|
||||
@@ -105,34 +127,13 @@
|
||||
<td>{$portData['Nego']}</td>
|
||||
<td>{$portData['FrameTX']}</td>
|
||||
<td>{$portData['FrameRX']}</td>
|
||||
<td><strong>{$portData['Errors']}</strong></td>
|
||||
<td data-value='{$errors}'><strong>{$portData['Errors']}</strong></td>
|
||||
</tr>";
|
||||
|
||||
// Sort into appropriate array
|
||||
if ($errors > 0) {
|
||||
$errorRows[] = $rowHtml;
|
||||
} else {
|
||||
$normalRows[] = $rowHtml;
|
||||
}
|
||||
|
||||
} elseif ($state === 'DN') {
|
||||
$downCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Merge rows: Errors first
|
||||
$finalRows = array_merge($errorRows, $normalRows);
|
||||
$tableBody = implode("\n", $finalRows);
|
||||
|
||||
// 6. Determine Header Style
|
||||
$headerColor = "green";
|
||||
$msg = "OK";
|
||||
if ($errorCount > 0) {
|
||||
$headerColor = "DarkOrange";
|
||||
$msg = "<b> --> {$errorCount} issue(s)</b>";
|
||||
}
|
||||
|
||||
// 7. Output the Accordion Item (Card)
|
||||
// Determine Header Color
|
||||
$headerColor = ($errorCount > 0) ? "DarkOrange" : "green";
|
||||
$msg = ($errorCount > 0) ? "<b> {$errorCount} issue(s)</b>" : "OK";
|
||||
?>
|
||||
|
||||
<div class="card" style="background-color:<?php echo $headerColor; ?>;">
|
||||
@@ -142,20 +143,22 @@
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
<div id="<?php echo $collapseId; ?>" class="collapse" data-bs-parent="#accordion">
|
||||
<div class="card-body bg-white border p-0">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-bordered table-hover mb-0 text-center">
|
||||
<table class="table table-bordered table-hover mb-0 text-center" data-toggle="table">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Port</th>
|
||||
<th>Status</th>
|
||||
<th>State</th>
|
||||
<th>Speed</th>
|
||||
<th>Nego</th>
|
||||
<th>FrameTX</th>
|
||||
<th>FrameRX</th>
|
||||
<th>Errors</th>
|
||||
<th data-sortable="true">vFabric</th>
|
||||
<th data-sortable="true">Port</th>
|
||||
<th data-sortable="true">Status</th>
|
||||
<th data-sortable="true">State</th>
|
||||
<th data-sortable="true">Speed</th>
|
||||
<th data-sortable="true">Nego</th>
|
||||
<th data-sortable="true">FrameTX</th>
|
||||
<th data-sortable="true">FrameRX</th>
|
||||
<th data-sortable="true">Errors</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -168,14 +171,16 @@
|
||||
<br>
|
||||
|
||||
<?php
|
||||
} // End foreach Switch
|
||||
}
|
||||
} else {
|
||||
echo "<div class='alert alert-warning'>No data available via API.</div>";
|
||||
}
|
||||
?>
|
||||
</div> </div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="/js/switch.js"></script>
|
||||
</html>
|
||||
@@ -82,7 +82,7 @@
|
||||
foreach ($list as $s) {
|
||||
$name = $s['HOSTNAME'];
|
||||
$ts = $s['ts'];
|
||||
$lastBackup = (explode(".",$s['LastBackup']))[0];
|
||||
$lastBackup = (explode(".",$s['LastBackup'] ?? ''))[0];
|
||||
$location = $s['Location'];
|
||||
$log = $s['Log'];
|
||||
$backuptype = $s['BackupType'];
|
||||
@@ -135,19 +135,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="/js/switch.js"></script>
|
||||
|
||||
<script>
|
||||
$(function() {
|
||||
// Dès que le switch #showAll change d'état
|
||||
$('#showAll').on('change', function() {
|
||||
// On soumet le formulaire le plus proche (le parent)
|
||||
$(this).closest('form').submit();
|
||||
});
|
||||
$('#showSize').on('change', function() {
|
||||
// On soumet le formulaire le plus proche (le parent)
|
||||
$(this).closest('form').submit();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -179,11 +179,11 @@
|
||||
|
||||
//LastBackup
|
||||
$lr = explode(".", $s['backuplast'] ?? "")[0];
|
||||
if(str_contains(strtolower($s['backuplog']), 'progress')){
|
||||
if(str_contains(strtolower($s['backuplog'] ?? ''), 'progress')){
|
||||
$size = "<span class='text-warning'>In Progress</span>";
|
||||
}elseif (str_contains(strtolower($s['backuplog']), 'waiting')){
|
||||
}elseif (str_contains(strtolower($s['backuplog'] ?? ''), 'waiting')){
|
||||
$size = "<span class='text-warning'><br>".$s['backuplog']."</span>";
|
||||
}elseif (str_contains(strtolower($s['backuplog']), 'error')){
|
||||
}elseif (str_contains(strtolower($s['backuplog'] ?? ''), 'error')){
|
||||
$size = "<span class='text-danger'><b> ERROR !!!</b></span>";
|
||||
}else {
|
||||
$size = 0;
|
||||
|
||||
@@ -176,8 +176,8 @@
|
||||
<tbody> <?php
|
||||
foreach ($hosts as $h) {
|
||||
$host = strtoupper($h['HOSTNAME']);
|
||||
$os = strtoupper($h['Type']);
|
||||
$osver = strtoupper($h['OSVersion']);
|
||||
$os = strtoupper($h['Type'] ?? "");
|
||||
$osver = strtoupper($h['OSVersion'] ?? "");
|
||||
|
||||
if ($os == "AIX") {
|
||||
$taix++;
|
||||
|
||||
191
X/VIO.php
Normal file
191
X/VIO.php
Normal file
@@ -0,0 +1,191 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Web Infra Reports IT</title>
|
||||
<link rel="shortcut icon" type="image/png" href="/include/favicon-32x32.png">
|
||||
|
||||
<script src="/js/jquery-3.6.1.min.js"></script>
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/css/bootstrap-icons/bootstrap-icons.css">
|
||||
<link rel="stylesheet" href="/css/preloader.css">
|
||||
<script src="/js/bootstrap.bundle.min.js"></script>
|
||||
<link rel="stylesheet" href="/css/bootstrap-table.min.css">
|
||||
<script src="/js/bootstrap-table.min.js"></script>
|
||||
<script src="/js/bootstrap-table-fr-FR.min.js"></script>
|
||||
<script src="/js/tableExport.min.js"></script>
|
||||
<script src="/js/bootstrap-table-export.min.js"></script>
|
||||
<script src="/js/libs/js-xlsx/xlsx.core.min.js"></script>
|
||||
|
||||
<style>
|
||||
.cell-multiline {
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* Custom style for VIOErr badges */
|
||||
.badge-err {
|
||||
background-color: #dc3545 !important;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body class="bg-light text-dark">
|
||||
<?php include $_SERVER['DOCUMENT_ROOT'] . "/include/all.php"; ?>
|
||||
|
||||
<?php
|
||||
// ==========================================
|
||||
// 1. DATA PROCESSING (PHP)
|
||||
// ==========================================
|
||||
|
||||
$rawRows = Invoke_Infra("SELECT * FROM x_cmdb_VIO");
|
||||
if (!$rawRows) $rawRows = [];
|
||||
|
||||
// Grouping
|
||||
$groupedData = [];
|
||||
foreach ($rawRows as $row) {
|
||||
$key = $row['clintname'];
|
||||
if (empty($key)) $key = "[No Client Name]";
|
||||
if (!isset($groupedData[$key])) $groupedData[$key] = [];
|
||||
$groupedData[$key][] = $row;
|
||||
}
|
||||
|
||||
// Flattening for Display (1 Row per Client)
|
||||
$displayRows = [];
|
||||
|
||||
foreach ($groupedData as $clientKey => $rows) {
|
||||
// 1. Sort by date desc
|
||||
usort($rows, function($a, $b) {
|
||||
return strcmp($b['ts'], $a['ts']);
|
||||
});
|
||||
|
||||
// 2. Keep max 2
|
||||
if (count($rows) > 2) {
|
||||
$rows = array_slice($rows, 0, 2);
|
||||
}
|
||||
|
||||
$names = []; $inerrs = []; $vfcs = []; $vios = [];
|
||||
$clintids = []; $fcnames = []; $tss = []; $vioerrs = [];
|
||||
|
||||
$hasError = false;
|
||||
$maxVioErr = 0;
|
||||
|
||||
foreach ($rows as $r) {
|
||||
if ($r['inerr'] != 0 && $r['inerr'] != '0') $hasError = true;
|
||||
|
||||
// Track VIOErr
|
||||
$errVal = (int)($r['VIOErr'] ?? 0);
|
||||
if ($errVal > $maxVioErr) $maxVioErr = $errVal;
|
||||
|
||||
// Format VIOErr for display (Red badge if > 0)
|
||||
$vioerrs[] = ($errVal > 0) ? "<span class='badge badge-err'>$errVal</span>" : $errVal;
|
||||
|
||||
$names[] = $r['name'] ?? '-';
|
||||
$inerrs[] = $r['inerr'] ?? '-';
|
||||
$vfcs[] = $r['vfcclientname'] ?? '-';
|
||||
$vios[] = $r['vio'] ?? '-';
|
||||
$clintids[] = $r['clintid'] ?? '-';
|
||||
$fcnames[] = $r['fcname'] ?? '-';
|
||||
$tss[] = $r['ts'] ?? '-';
|
||||
}
|
||||
|
||||
$displayRows[] = [
|
||||
'clintname' => $clientKey,
|
||||
'hasError' => $hasError,
|
||||
'maxVioErr' => $maxVioErr,
|
||||
'name' => implode('<br>', $names),
|
||||
'inerr' => implode('<br>', $inerrs),
|
||||
'vfc' => implode('<br>', $vfcs),
|
||||
'vio' => implode('<br>', $vios),
|
||||
'clintid' => implode('<br>', $clintids),
|
||||
'fcname' => implode('<br>', $fcnames),
|
||||
'ts' => implode('<br>', $tss),
|
||||
'vioerr' => implode('<br>', $vioerrs),
|
||||
];
|
||||
}
|
||||
|
||||
// 4. Final Sort: 1. Warning (inerr), 2. VIOErr > 0, 3. Alpha
|
||||
usort($displayRows, function($a, $b) {
|
||||
// Priority 1: InErr (table-warning)
|
||||
if ($a['hasError'] && !$b['hasError']) return -1;
|
||||
if (!$a['hasError'] && $b['hasError']) return 1;
|
||||
|
||||
// Priority 2: VIOErr count
|
||||
if ($a['maxVioErr'] > 0 && $b['maxVioErr'] == 0) return -1;
|
||||
if ($a['maxVioErr'] == 0 && $b['maxVioErr'] > 0) return 1;
|
||||
if ($a['maxVioErr'] != $b['maxVioErr']) return $b['maxVioErr'] - $a['maxVioErr'];
|
||||
|
||||
// Priority 3: Alphabetical
|
||||
return strcasecmp($a['clintname'], $b['clintname']);
|
||||
});
|
||||
?>
|
||||
|
||||
<div class="container-fluid" id="content">
|
||||
<div class="row flex-nowrap">
|
||||
<div class="col-auto col-md-2 col-xl-2 px-sm-2 px-0 bg-dark vh-100 position-sticky top-0" style="flex: 0 0 230px;">
|
||||
<?php include $_SERVER['DOCUMENT_ROOT'] . "/navbar.html"; ?>
|
||||
</div>
|
||||
|
||||
<div class="col py-3">
|
||||
<h1><span class="badge text-bg-secondary w-100">VIO Monitoring</span></h1>
|
||||
|
||||
<div class="container-fluid">
|
||||
<div>
|
||||
<table class='table table-bordered table-hover table-sm' id='t1'
|
||||
data-toggle="table"
|
||||
data-search="true"
|
||||
data-show-columns="true"
|
||||
data-export-types="['xlsx','csv','json']"
|
||||
data-show-export="true"
|
||||
data-sortable="true"> <thead>
|
||||
<tr>
|
||||
<th data-field="clintname" data-sortable="true">Clint Name</th>
|
||||
<th data-field="name">Name</th>
|
||||
<th data-field="vioerr">VIOErr</th>
|
||||
<th data-field="inerr">InErr</th>
|
||||
<th data-field="vfcclientname">VFC Client Name</th>
|
||||
<th data-field="vio">VIO</th>
|
||||
<th data-field="clintid">ClintID</th>
|
||||
<th data-field="fcname">FC Name</th>
|
||||
<th data-field="ts">Last Update</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php foreach ($displayRows as $row): ?>
|
||||
<?php $class = $row['hasError'] ? 'table-warning' : ''; ?>
|
||||
<tr class="<?php echo $class; ?>">
|
||||
<td class="fw-bold align-middle"><?php echo htmlspecialchars($row['clintname']); ?></td>
|
||||
<td class="cell-multiline"><?php echo $row['name']; ?></td>
|
||||
<td class="cell-multiline text-center fw-bold"><?php echo $row['vioerr']; ?></td>
|
||||
<td class="cell-multiline"><?php echo $row['inerr']; ?></td>
|
||||
<td class="cell-multiline"><?php echo $row['vfc']; ?></td>
|
||||
<td class="cell-multiline"><?php echo $row['vio']; ?></td>
|
||||
<td class="cell-multiline"><?php echo $row['clintid']; ?></td>
|
||||
<td class="cell-multiline"><?php echo $row['fcname']; ?></td>
|
||||
<td class="cell-multiline small"><?php echo $row['ts']; ?></td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="/js/switch.js"></script>
|
||||
<script>
|
||||
var $table = $('#t1');
|
||||
function adjustTableHeight() {
|
||||
let height = $(window).height() - 170;
|
||||
$table.bootstrapTable('resetView', { height: height });
|
||||
}
|
||||
$(function () {
|
||||
adjustTableHeight();
|
||||
$(window).resize(function () { adjustTableHeight(); });
|
||||
});
|
||||
</script>
|
||||
</html>
|
||||
204
include/all.php
204
include/all.php
@@ -335,6 +335,207 @@
|
||||
|
||||
?>
|
||||
|
||||
|
||||
<style>
|
||||
/* 1. CONFIGURATION DES COULEURS */
|
||||
:root {
|
||||
/* Par défaut (Mode Clair / bg-light) : Gris visible sur blanc */
|
||||
--snow-color: rgba(160, 160, 160, 0.9);
|
||||
}
|
||||
|
||||
/* 2. DÉTECTION DU MODE SOMBRE BASÉE SUR TON SCRIPT */
|
||||
/* Ton script ajoute la classe 'bg-dark' au body, on s'en sert ici */
|
||||
body.bg-dark {
|
||||
--snow-color: rgba(255, 255, 255, 0.9) !important;
|
||||
}
|
||||
|
||||
/* Gestion des préférences système (OS) au cas où le script JS n'a pas encore chargé */
|
||||
@media (prefers-color-scheme: dark) {
|
||||
body:not(.bg-light) { /* Sauf si l'utilisateur a forcé le mode clair */
|
||||
--snow-color: rgba(255, 255, 255, 0.9);
|
||||
}
|
||||
}
|
||||
|
||||
/* 3. STYLES DU CANVAS ET DU BOUTON */
|
||||
#snow-canvas {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 9999; /* Au-dessus de tout */
|
||||
pointer-events: none; /* LAISSE PASSER LES CLICS (Vital !) */
|
||||
}
|
||||
|
||||
#snow-toggle-btn {
|
||||
position: fixed;
|
||||
/* Positionné un peu au-dessus du bas pour ne pas gêner d'autres footers */
|
||||
bottom: 20px;
|
||||
right: 20px;
|
||||
z-index: 10000;
|
||||
background: transparent;
|
||||
color: var(--snow-color); /* Le bouton prend aussi la couleur du thème */
|
||||
border: 1px solid var(--snow-color);
|
||||
border-radius: 50%;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
transition: all 0.3s;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
opacity: 0.5; /* Discret par défaut */
|
||||
}
|
||||
|
||||
#snow-toggle-btn:hover {
|
||||
opacity: 1;
|
||||
background: rgba(128, 128, 128, 0.2);
|
||||
}
|
||||
</style>
|
||||
|
||||
<canvas id="snow-canvas"></canvas>
|
||||
<button id="snow-toggle-btn" title="Activer/Désactiver la neige">❄️</button>
|
||||
|
||||
<script>
|
||||
(function() {
|
||||
// --- 1. GESTION DES DATES (15 Déc au 5 Jan) ---
|
||||
const now = new Date();
|
||||
const month = now.getMonth() + 1; // JS compte les mois de 0 à 11, donc on ajoute 1
|
||||
const day = now.getDate();
|
||||
|
||||
// La condition : (Mois = 12 ET Jour >= 15) OU (Mois = 1 ET Jour <= 5)
|
||||
const isSeason = (month === 12 && day >= 15) || (month === 1 && day <= 5);
|
||||
|
||||
const canvas = document.getElementById('snow-canvas');
|
||||
const toggleBtn = document.getElementById('snow-toggle-btn');
|
||||
|
||||
// Si on n'est pas dans la période, on cache tout et on arrête le script.
|
||||
if (!isSeason) {
|
||||
if (canvas) canvas.style.display = 'none';
|
||||
if (toggleBtn) toggleBtn.style.display = 'none';
|
||||
return; // Arrêt immédiat du script
|
||||
}
|
||||
|
||||
// --- 2. CONFIGURATION ---
|
||||
const ctx = canvas.getContext('2d');
|
||||
|
||||
let width = window.innerWidth;
|
||||
let height = window.innerHeight;
|
||||
|
||||
const maxFlakes = 80;
|
||||
let flakes = [];
|
||||
let animationId;
|
||||
let isSnowing = false;
|
||||
|
||||
// Gestion du redimensionnement
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
window.addEventListener('resize', () => {
|
||||
width = window.innerWidth;
|
||||
height = window.innerHeight;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
});
|
||||
|
||||
// --- 3. CLASSE FLOCON ---
|
||||
class Snowflake {
|
||||
constructor() {
|
||||
this.reset(true);
|
||||
}
|
||||
|
||||
reset(initial = false) {
|
||||
this.x = Math.random() * width;
|
||||
this.y = initial ? Math.random() * height : -10;
|
||||
this.radius = Math.random() * 3 + 1;
|
||||
this.speed = Math.random() * 1.5 + 0.5;
|
||||
this.drift = Math.random() * 2 - 1;
|
||||
}
|
||||
|
||||
update() {
|
||||
this.y += this.speed;
|
||||
this.x += this.drift;
|
||||
|
||||
if (this.y > height || this.x > width || this.x < 0) {
|
||||
this.reset();
|
||||
}
|
||||
}
|
||||
|
||||
draw(color) {
|
||||
ctx.beginPath();
|
||||
ctx.fillStyle = color;
|
||||
ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true);
|
||||
ctx.fill();
|
||||
}
|
||||
}
|
||||
|
||||
// --- 4. ANIMATION ---
|
||||
function initFlakes() {
|
||||
flakes = [];
|
||||
for (let i = 0; i < maxFlakes; i++) {
|
||||
flakes.push(new Snowflake());
|
||||
}
|
||||
}
|
||||
|
||||
function animate() {
|
||||
if (!isSnowing) {
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
|
||||
// Récupération dynamique de la couleur (compatible avec ton script Light Switch)
|
||||
const style = getComputedStyle(document.body);
|
||||
const currentColor = style.getPropertyValue('--snow-color').trim();
|
||||
|
||||
flakes.forEach(flake => {
|
||||
flake.update();
|
||||
flake.draw(currentColor);
|
||||
});
|
||||
|
||||
animationId = requestAnimationFrame(animate);
|
||||
}
|
||||
|
||||
// --- 5. BOUTON & INIT ---
|
||||
function toggleSnow() {
|
||||
isSnowing = !isSnowing;
|
||||
updateButtonState();
|
||||
|
||||
if (isSnowing) {
|
||||
initFlakes();
|
||||
animate();
|
||||
localStorage.setItem('snow-preference', 'on');
|
||||
} else {
|
||||
cancelAnimationFrame(animationId);
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
localStorage.setItem('snow-preference', 'off');
|
||||
}
|
||||
}
|
||||
|
||||
function updateButtonState() {
|
||||
if(isSnowing) {
|
||||
toggleBtn.style.opacity = "1";
|
||||
toggleBtn.style.background = "rgba(128, 128, 128, 0.3)";
|
||||
} else {
|
||||
toggleBtn.style.opacity = "0.5";
|
||||
toggleBtn.style.background = "transparent";
|
||||
}
|
||||
}
|
||||
|
||||
toggleBtn.addEventListener('click', toggleSnow);
|
||||
|
||||
const savedPref = localStorage.getItem('snow-preference');
|
||||
|
||||
if (savedPref !== 'off') {
|
||||
isSnowing = true;
|
||||
initFlakes();
|
||||
animate();
|
||||
updateButtonState();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- MODAL WAIT -->
|
||||
<div class="modal fade bs-example-modal-sm" id="wait" tabindex="-1" role="dialog" aria-hidden="true" data-backdrop="static" style="padding-top: 15%;">
|
||||
<div class="modal-dialog modal-sm">
|
||||
@@ -352,3 +553,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
<?php
|
||||
// Temporarily enable all error reporting to catch details from odbc_connect
|
||||
// error_reporting(E_ALL); // Uncomment this line if you still don't get enough info
|
||||
|
||||
$conn_string = "DRIVER={IBM DB2 ODBC DRIVER - F_DB2_clidriver};" .
|
||||
"DATABASE=AIXCMDB; " .
|
||||
"HOSTNAME=db2_aixcmdb.appliarmony.net;" .
|
||||
"PORT=50000; " .
|
||||
"PROTOCOL=TCPIP; " .
|
||||
"UID=aixcmdb;" .
|
||||
"AUTHENTICATION=SERVER;" .
|
||||
"PWD=aixcmdb;";
|
||||
|
||||
$conn = odbc_connect($conn_string, "", "");
|
||||
|
||||
if (!$conn) {
|
||||
// --- IMPORTANT: Récupérer le message d'erreur ODBC détaillé ---
|
||||
$error_message = "ODBC Connect Error: " . odbc_errormsg() . " (" . odbc_error() . ")";
|
||||
echo "Pas de connexion : " . $error_message . "<br>";
|
||||
// Pour débogage, tu peux aussi loguer cette erreur dans un fichier
|
||||
// error_log($error_message);
|
||||
return "ERROR: Could not connect to DB2. Check connection string and ODBC setup."; // Retourne une erreur pour éviter l'appel à odbc_exec
|
||||
}
|
||||
|
||||
$rs = odbc_exec($conn, $request);
|
||||
|
||||
// Ton code existant après la connexion
|
||||
if (strpos(strtoupper($request), "SELECT") !== false) { // strpos est plus robuste que instr ici en PHP
|
||||
$answer = []; // Initialize array to prevent undefined variable warning
|
||||
while ($row = odbc_fetch_array($rs)) {
|
||||
$answer[] = $row;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($answer)) {
|
||||
return $answer;
|
||||
} else {
|
||||
if ($rs) {
|
||||
return "OK";
|
||||
} else {
|
||||
// If odbc_exec failed
|
||||
error_reporting(E_ALL); // Re-enable for this specific error if needed
|
||||
return "ERROR : " . odbc_errormsg($conn);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
<a href="/X/autoremediationlog.php" class="nav-link px-0"> <span class="d-none d-sm-inline text-white h7">- AutoRemediation Logs</span></a>
|
||||
<a href="/X/stdout.php" class="nav-link px-0"> <span class="d-none d-sm-inline text-white h7">- Scripts Result</span></a>
|
||||
<a href="/X/backups.php" class="nav-link px-0"> <span class="d-none d-sm-inline text-white h7">- Backups</span></a>
|
||||
<a href="/X/VIO.php" class="nav-link px-0"> <span class="d-none d-sm-inline text-white h7">- VIO</span></a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
Reference in New Issue
Block a user