prepare($sql); $stmt->execute($params); return $stmt->fetchColumn(); } catch (PDOException $e) { return 0; } } // Function to execute query and return results function get_assets($fields, $search = '', $status = '', $limit = 10, $offset = 0, $sort_by = 'created_at', $sort_order = 'DESC') { if (empty($fields)) { return []; // No read permission } // Always include id for edit/delete links if (!in_array('id', $fields)) { $fields[] = 'id'; } $select_fields = implode(', ', $fields); $sql = "SELECT $select_fields FROM assets"; $where = []; $params = []; if (!empty($search)) { // Assuming 'name' is a field that can be searched. if (in_array('name', $fields)) { $where[] = "name LIKE :search"; $params[':search'] = "%$search%"; } } if (!empty($status)) { if (in_array('status', $fields)) { $where[] = "status = :status"; $params[':status'] = $status; } } if (!empty($where)) { $sql .= " WHERE " . implode(' AND ', $where); } // Whitelist sortable columns $sortable_columns = array_merge($fields, ['created_at']); if (!in_array($sort_by, $sortable_columns)) { $sort_by = 'created_at'; } $sort_order = strtoupper($sort_order) === 'ASC' ? 'ASC' : 'DESC'; $sql .= " ORDER BY $sort_by $sort_order LIMIT :limit OFFSET :offset"; $params[':limit'] = $limit; $params[':offset'] = $offset; try { $pdo = db(); $stmt = $pdo->prepare($sql); // Bind parameters separately to handle integer binding for LIMIT and OFFSET foreach ($params as $key => &$val) { if ($key === ':limit' || $key === ':offset') { $stmt->bindParam($key, $val, PDO::PARAM_INT); } else { $stmt->bindParam($key, $val); } } $stmt->execute(); return $stmt->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { return ['error' => 'Database error: ' . $e->getMessage()]; } } $search = $_GET['search'] ?? ''; $status = $_GET['status'] ?? ''; $page = isset($_GET['page']) ? (int)$_GET['page'] : 1; $limit = 10; $offset = ($page - 1) * $limit; $sort_by = $_GET['sort_by'] ?? 'created_at'; $sort_order = $_GET['sort_order'] ?? 'DESC'; $total_assets = count_assets($search, $status); $total_pages = ceil($total_assets / $limit); $assets = get_assets($allowed_fields, $search, $status, $limit, $offset, $sort_by, $sort_order); function getStatusClass($status) { switch (strtolower($status)) { case 'in service': return 'status-in-service'; case 'under repair': return 'status-under-repair'; case 'retired': return 'status-retired'; default: return ''; } } ?>