real_escape_string((string)$v); } return addslashes((string)$v); } } if (!function_exists('fetch_all_assoc')) { function fetch_all_assoc($db, $sql) { if (!($db instanceof mysqli)) return []; $res = $db->query($sql); return $res ? $res->fetch_all(MYSQLI_ASSOC) : []; } } if (!function_exists('col_exists')) { function col_exists($db, $table, $col) { if (!($db instanceof mysqli)) return false; $t = $db->real_escape_string($table); $c = $db->real_escape_string($col); $res = $db->query("SHOW COLUMNS FROM `{$t}` LIKE '{$c}'"); return ($res && $res->num_rows > 0); } } // expose a convenience variable for scripts that expect $db // Do not overwrite an existing $db if present if (!isset($db) || !($db instanceof mysqli)) { $maybe = billing_get_db(); if ($maybe instanceof mysqli) { $db = $maybe; } } /** * Resolve a billing_services.img_url value to a browser-safe URL. * * Rules: * - Empty string → '' (caller should skip the tag). * - Full URL (http:// or https://) → returned as-is. * - Bare filename (e.g. "dayz.jpg") → "/images/games/{filename}". * - Anything else treated as a bare filename for safety. * * Output is NOT htmlspecialchars'd here; callers must escape for HTML context. */ if (!function_exists('billing_image_url')) { function billing_image_url(string $imgUrl): string { $imgUrl = trim($imgUrl); if ($imgUrl === '') { return ''; } // Keep full external URLs intact if (str_starts_with($imgUrl, 'http://') || str_starts_with($imgUrl, 'https://')) { return $imgUrl; } // Strip any leading path separators/directories so we always get a bare filename $filename = basename($imgUrl); if ($filename === '') { return ''; } return '/images/games/' . $filename; } } // End bootstrap