PDO::ERRMODE_EXCEPTION] ); } catch (PDOException $e) { die("DB Connection failed: " . $e->getMessage()); } require_once '../s3_client.php'; $s3 = new S3Client(); // --- Helper functions (Local DB & S3) --- function get_row($pdo, $table, $id, $company) { $stmt = $pdo->prepare("SELECT * FROM `$table` WHERE Id = :id AND company = :company"); $stmt->execute([':id' => $id, ':company' => $company]); return $stmt->fetch(PDO::FETCH_ASSOC) ?: []; } function update_row($pdo, $table, $id, $data, $company) { if (empty($data)) return; $set = []; $params = [':id' => $id, ':company' => $company]; foreach ($data as $col => $val) { $set[] = "`$col` = :$col"; $params[":$col"] = $val; } $sql = "UPDATE `$table` SET " . implode(', ', $set) . " WHERE Id = :id AND company = :company"; $stmt = $pdo->prepare($sql); $stmt->execute($params); } function get_files($pdo, $table, $id) { $stmt = $pdo->prepare("SELECT * FROM device_files WHERE device_id = :id AND device_table = 'assets'"); $stmt->execute([':id' => $id]); return $stmt->fetchAll(PDO::FETCH_ASSOC); } function upload_file($pdo, $s3, $table, $id, $file) { $fileName = $file['name']; $tmpName = $file['tmp_name']; $mime = $file['type']; $size = $file['size']; // Generate unique key $key = "uploads/$table/$id/" . uniqid() . '_' . $fileName; $result = $s3->uploadFile($tmpName, $key, $mime); if ($result['success']) { $stmt = $pdo->prepare("INSERT INTO device_files (device_id, device_table, file_path, file_name, mime_type, size) VALUES (:did, :dtab, :path, :name, :mime, :size)"); $stmt->execute([ ':did' => $id, ':dtab' => 'assets', ':path' => $key, ':name' => $fileName, ':mime' => $mime, ':size' => $size ]); return ['success' => true]; } return $result; } function delete_file($pdo, $s3, $fileId) { $stmt = $pdo->prepare("SELECT * FROM device_files WHERE id = :id"); $stmt->execute([':id' => $fileId]); $file = $stmt->fetch(PDO::FETCH_ASSOC); if ($file) { if ($s3->deleteFile($file['file_path'])) { $del = $pdo->prepare("DELETE FROM device_files WHERE id = :id"); $del->execute([':id' => $fileId]); return true; } } return false; } // --- Handle file actions --- if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($role === 'user') { die('Access Denied: Read-only user.'); } if (isset($_FILES['new_file'])) { $file = $_FILES['new_file']; if ($file['error'] === UPLOAD_ERR_OK) { $result = upload_file($pdo, $s3, $table, $recordId, $file); if (!$result['success']) { die("S3 Upload Failed. Code: " . $result['code'] . " | Message: " . htmlspecialchars($result['message'])); } } else { die("File upload error code: " . $file['error']); } header("Location: asset.php?id=" . urlencode((string) $recordId)); exit(); } if (isset($_POST['delete_file'])) { delete_file($pdo, $s3, $_POST['delete_file']); header("Location: asset.php?id=" . urlencode((string) $recordId)); exit(); } } // --- Row data --- $row = get_row($pdo, $table, $recordId, $company); if ($role === 'user' && ($row['UserEmail'] ?? '') !== $currentUserEmail) { die('Access Denied: You do not own this asset.'); } $files = get_files($pdo, $table, $recordId); $companyUsers = []; if ($role === 'admin' || $role === 'manager' || $role === 'superadmin') { // Fetch all users for this company to populate the dropdown $uStmt = $pdo->prepare("SELECT email FROM users WHERE company = :comp ORDER BY email ASC"); $uStmt->execute([':comp' => $company]); $companyUsers = $uStmt->fetchAll(PDO::FETCH_COLUMN); } function escape($v) { return htmlspecialchars((string) ($v ?? ''), ENT_QUOTES, 'UTF-8'); } // Serial number for title/h2; fall back to record id if empty $serial = trim((string) ($row['SN'] ?? '')); $serialForTitle = $serial !== '' ? $serial : (string) $recordId; // --- Columns config --- // Reordered: Term first, then LastSeen, then UserEmail, then rest. $columns = [ 'Id', 'UUID', 'SN', 'OS', 'OSVersion', 'Hostname', 'Mobile', 'Manufacturer', 'Term', 'LastSeen', 'UserEmail', 'BYOD', 'Status', 'Warranty', 'Asset', 'PurchaseDate', 'CypherID', 'CypherKey', 'Notes' ]; // Insert the new read-only, view-only columns immediately after CypherKey (or append if not present) $newReadOnlyCols = [ 'CPUs', 'HDs', 'HDsTypes', 'HDsSpacesGB', 'NetworkAdapters', 'MACAddresses', 'ESETComponents', 'PrimaryLocalIP', 'PrimaryRemoteIP' ]; $idx = array_search('CypherKey', $columns, true); if ($idx !== false) { array_splice($columns, $idx + 1, 0, $newReadOnlyCols); } else { // Non-admin or CypherKey absent: still show these new fields $columns = array_merge($columns, $newReadOnlyCols); } $hidden = ['Id']; $editable = ['UserEmail', 'Status', 'Warranty', 'Asset', 'PurchaseDate', 'BYOD']; // Role-based editability if ($role === 'user') { $editable = []; } else { // Manager, Admin, Superadmin can edit Notes if (in_array($role, ['manager', 'admin', 'superadmin'])) { $editable[] = 'Notes'; } // Admin, Superadmin can edit Cypher fields if (in_array($role, ['admin', 'superadmin'])) { $editable[] = 'CypherID'; $editable[] = 'CypherKey'; } } // Mark the requested fields as read-only (view-only) $readonly = array_merge( ['Hostname'], [ 'CPUs', 'HDs', 'HDsTypes', 'HDsSpacesGB', 'NetworkAdapters', 'MACAddresses', 'ESETComponents', 'PrimaryLocalIP', 'PrimaryRemoteIP' ] ); $display = array_filter($columns, fn($c) => !in_array($c, $hidden, true)); $status_options = ["In Use", "In Stock", "In Repair", "Replaced", "Decommissioned", "Lost or Stolen"]; ?> CMDB Row Details (SN #<?php echo escape($serialForTitle); ?>) ← Back to CMDB Company:

CMDB Row Details (SN #)

1 ? 's' : '') : 'No files'; } elseif ($col === 'SN') { echo escape($value); } elseif (in_array($col, $editable, true)) { if ($col === 'BYOD') { $v = strtolower(trim((string) $value)); $isTrue = in_array($v, ['true', '1', 'yes', 'on'], true); ?>

Upload New File

Existing Files

getPresignedUrl($f['file_path']); $title = $f['file_name']; $delete = $f['id']; ?>
No files found.