null]): array { $db = self::getDB(); $table = self::getFullyQualifiedTable(); $customFilterSql = ''; // Check if the intelligent 'assetDetails' filter is being used. if (!empty($filter['assetDetails'])) { $searchTerms = explode(' ', $filter['assetDetails']); $searchConditions = []; foreach ($searchTerms as $term) { if (empty(trim($term))) continue; $escapedTerm = $db->real_escape_string($term); // For each term, search in name, assetNumber, and description. $searchConditions[] = "(`name` LIKE '%$escapedTerm%' OR `assetNumber` LIKE '%$escapedTerm%' OR `description` LIKE '%$escapedTerm%')"; } if (!empty($searchConditions)) { // All search terms must be found (AND logic). $customFilterSql = ' AND (' . implode(' AND ', $searchConditions) . ')'; } // Remove the 'assetDetails' key to prevent errors in the standard filter generation. } unset($filter['assetDetails']); $sqlFilter = self::getSQLFilter($filter); if ($sqlFilter === '') { if ($customFilterSql !== '') { // If the base filter is empty but a custom filter exists, start with WHERE. $sqlFilter = 'WHERE' . ltrim($customFilterSql, ' AND'); } } else { // If a base filter already exists, just append the custom one. $sqlFilter .= $customFilterSql; } $sql = "SELECT * FROM $table $sqlFilter"; $sql .= $order['key'] === null ? " ORDER BY `id` ASC" : " ORDER BY `" . $order['key'] . "` " . $order['order']; $sql .= $limit === null ? "" : " LIMIT " . $limit . " OFFSET " . $offset; try { $result = $db->query($sql); } catch (Exception $e) { echo $sql; die($e->getMessage()); } $rows = []; $class = get_called_class(); while ($row = $result->fetch_assoc()) { $rows[] = new $class($row); } return $rows; } /** * Counts assets based on a filter, with special handling for 'assetDetails'. * * @param array $filter The filter criteria. If 'assetDetails' is present, it will perform a multi-field count. * @return int The total count of matching records. */ public static function count($filter = []): int { $db = self::getDB(); $table = self::getFullyQualifiedTable(); $customFilterSql = ''; // Check if the intelligent 'assetDetails' filter is being used. if (!empty($filter['assetDetails'])) { $searchTerms = explode(' ', $filter['assetDetails']); $searchConditions = []; foreach ($searchTerms as $term) { if (empty(trim($term))) continue; $escapedTerm = $db->real_escape_string($term); // For each term, search in name, assetNumber, and description. $searchConditions[] = "(`name` LIKE '%$escapedTerm%' OR `assetNumber` LIKE '%$escapedTerm%' OR `description` LIKE '%$escapedTerm%')"; } if (!empty($searchConditions)) { // All search terms must be found (AND logic). $customFilterSql = ' AND (' . implode(' AND ', $searchConditions) . ')'; } // Remove the 'assetDetails' key to prevent errors in the standard filter generation. } unset($filter['assetDetails']); $sqlFilter = self::getSQLFilter($filter); if ($sqlFilter === '') { if ($customFilterSql !== '') { // If the base filter is empty but a custom filter exists, start with WHERE. $sqlFilter = 'WHERE' . ltrim($customFilterSql, ' AND'); } } else { // If a base filter already exists, just append the custom one. $sqlFilter .= $customFilterSql; } $sql = "SELECT COUNT(*) as count FROM $table $sqlFilter"; $result = $db->query($sql); return $result->fetch_assoc()['count']; } }