'; } $icon = $currentOrder === 'asc' ? 'fa-sort-up' : 'fa-sort-down'; return ''; } /** * Generate pagination URL */ public static function paginationUrl(int $page, array $filters, int $perPage): string { $params = $filters; $params['page'] = $page; $params['per_page'] = $perPage; $currentPath = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); return $currentPath . '?' . http_build_query($params); } /** * Format status badge */ public static function statusBadge(string $status): string { $statusClasses = [ 'active' => 'bg-green-100 text-green-800 border-green-200', 'expiring_soon' => 'bg-orange-100 text-orange-800 border-orange-200', 'expired' => 'bg-red-100 text-red-800 border-red-200', 'available' => 'bg-blue-100 text-blue-800 border-blue-200', 'redemption_period' => 'bg-amber-100 text-amber-800 border-amber-200', 'pending_delete' => 'bg-rose-100 text-rose-800 border-rose-200', 'inactive' => 'bg-gray-100 text-gray-800 border-gray-200', ]; $statusLabels = [ 'active' => 'Active', 'expiring_soon' => 'Expiring Soon', 'expired' => 'Expired', 'available' => 'Available', 'redemption_period' => 'Redemption Period', 'pending_delete' => 'Pending Delete', 'inactive' => 'Inactive', ]; $class = $statusClasses[$status] ?? $statusClasses['inactive']; $label = $statusLabels[$status] ?? ucfirst($status); return '' . htmlspecialchars($label) . ''; } /** * Truncate text with ellipsis */ public static function truncate(string $text, int $length = 50, string $suffix = '...'): string { if (mb_strlen($text) <= $length) { return htmlspecialchars($text); } return htmlspecialchars(mb_substr($text, 0, $length)) . $suffix; } /** * Format bytes to human readable size */ public static function formatBytes(int $bytes, int $precision = 2): string { $units = ['B', 'KB', 'MB', 'GB', 'TB']; for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) { $bytes /= 1024; } return round($bytes, $precision) . ' ' . $units[$i]; } /** * Generate breadcrumb navigation */ public static function breadcrumbs(array $items): string { $html = ''; return $html; } /** * Get the PHP max upload size from ini settings. * Returns the lower of upload_max_filesize and post_max_size as a human-readable string. * * @return string Human-readable size (e.g. "128 MB") */ public static function getMaxUploadSize(): string { $phpUploadMax = self::parseIniSize(ini_get('upload_max_filesize') ?: '2M'); $phpPostMax = self::parseIniSize(ini_get('post_max_size') ?: '8M'); $phpLimit = min($phpUploadMax, $phpPostMax); return self::formatBytes($phpLimit, 0); } /** * Parse a PHP ini size value (e.g. "2M", "128K", "1G") into bytes. */ private static function parseIniSize(string $size): int { $value = (int) $size; $unit = strtolower(substr(trim($size), -1)); return match ($unit) { 'g' => $value * 1073741824, 'm' => $value * 1048576, 'k' => $value * 1024, default => $value, }; } /** * Generate alert message HTML */ public static function alert(string $type, string $message): string { $classes = [ 'success' => 'bg-green-50 border-green-200 text-green-800', 'error' => 'bg-red-50 border-red-200 text-red-800', 'warning' => 'bg-orange-50 border-orange-200 text-orange-800', 'info' => 'bg-blue-50 border-blue-200 text-blue-800', ]; $icons = [ 'success' => 'fa-check-circle', 'error' => 'fa-exclamation-circle', 'warning' => 'fa-exclamation-triangle', 'info' => 'fa-info-circle', ]; $class = $classes[$type] ?? $classes['info']; $icon = $icons[$type] ?? $icons['info']; return '
' . htmlspecialchars($message) . '
'; } }