$u['username'],
'{{password}}' => $u['password'],
'{{price}}' => $u['price'],
'{{validity}}' => $u['validity'],
'{{timelimit}}' => $u['timelimit'] ?? $u['validity'], // Fallback if missing
'{{datalimit}}' => $u['datalimit'] ?? '',
'{{profile}}' => $u['profile'],
'{{comment}}' => $u['comment'],
'{{hotspotname}}' => $u['hotspotname'],
'{{dns_name}}' => $u['dns_name'],
'{{login_url}}' => $u['login_url'],
'{{num}}' => ($index + 1),
'{{logo}}' => '

', // Default Logo placeholder
];
// 1. Handle {{logo id=...}}
$html = preg_replace_callback('/\{\{logo\s+id=[\'"]?([^\'"\s]+)[\'"]?\}\}/i', function($matches) use ($logoMap) {
$id = $matches[1];
if (isset($logoMap[$id])) {
return '

'; // Default style, user can wrap in div
}
return ''; // Return empty if not found
}, $html);
foreach ($replacements as $key => $val) {
$html = str_replace($key, $val, $html);
}
// 2. Handle QR Code with Logo support
$html = preg_replace_callback('/\{\{qrcode(?:\s+(.*?))?\}\}/i', function($matches) use ($index, $u, $logoMap) {
$qrId = "qr-custom-" . $index . "-" . uniqid();
$qrCodeValue = $u['login_url'] . "?user=" . $u['username'] . "&password=" . $u['password'];
// Default Options
$opts = [
'element' => 'document.getElementById("'.$qrId.'")',
'value' => $qrCodeValue,
'size' => 100,
'foreground' => 'black',
'background' => 'white',
'padding' => null,
'logo' => null // Logo ID
];
$rounded = '';
// Parse Attributes
if (!empty($matches[1])) {
$attrs = $matches[1];
if (preg_match('/fg\s*=\s*[\'"]?([^\'"\s]+)[\'"]?/i', $attrs, $m)) $opts['foreground'] = $m[1];
if (preg_match('/bg\s*=\s*[\'"]?([^\'"\s]+)[\'"]?/i', $attrs, $m)) $opts['background'] = $m[1];
if (preg_match('/size\s*=\s*[\'"]?(\d+)[\'"]?/i', $attrs, $m)) $opts['size'] = $m[1];
if (preg_match('/padding\s*=\s*[\'"]?(\d+)[\'"]?/i', $attrs, $m)) $opts['padding'] = $m[1];
if (preg_match('/rounded\s*=\s*[\'"]?(\d+)[\'"]?/i', $attrs, $m)) $rounded = 'border-radius: ' . $m[1] . 'px;';
if (preg_match('/logo\s*=\s*[\'"]?([^\'"\s]+)[\'"]?/i', $attrs, $m)) $opts['logo'] = $m[1];
}
// CSS Styles
$cssPadding = $opts['padding'] ? ('padding: ' . $opts['padding'] . 'px; ') : '';
$cssBg = 'background-color: ' . $opts['background'] . '; ';
$baseStyle = 'display: inline-block; vertical-align: middle; ' . $cssBg . $cssPadding . $rounded;
// JS Generation
$qrJs = "
(function() {
var qr = new QRious({
element: document.getElementById('$qrId'),
value: \"{$opts['value']}\",
size: {$opts['size']},
foreground: \"{$opts['foreground']}\",
backgroundAlpha: 0
});
";
// If Logo is requested and found
if ($opts['logo'] && isset($logoMap[$opts['logo']])) {
$logoPath = $logoMap[$opts['logo']];
$qrJs .= "
var img = new Image();
img.src = '$logoPath';
img.onload = function() {
var canvas = document.getElementById('$qrId');
var ctx = canvas.getContext('2d');
var size = {$opts['size']};
var logoSize = size * 0.2; // Logo is 20% of QR size
var logoPos = (size - logoSize) / 2;
ctx.drawImage(img, logoPos, logoPos, logoSize, logoSize);
};
";
}
$qrJs .= "})();";
return '
';
}, $html);
echo $html;
?>