Files
michaelschiemer/tests/debug/test-svg-rendering-issues.php
Michael Schiemer 95147ff23e refactor(deployment): Remove WireGuard VPN dependency and restore public service access
Remove WireGuard integration from production deployment to simplify infrastructure:
- Remove docker-compose-direct-access.yml (VPN-bound services)
- Remove VPN-only middlewares from Grafana, Prometheus, Portainer
- Remove WireGuard middleware definitions from Traefik
- Remove WireGuard IPs (10.8.0.0/24) from Traefik forwarded headers

All monitoring services now publicly accessible via subdomains:
- grafana.michaelschiemer.de (with Grafana native auth)
- prometheus.michaelschiemer.de (with Basic Auth)
- portainer.michaelschiemer.de (with Portainer native auth)

All services use Let's Encrypt SSL certificates via Traefik.
2025-11-05 12:48:25 +01:00

144 lines
4.9 KiB
PHP

<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\QrCode\QrCodeGenerator;
use App\Framework\QrCode\QrCodeRenderer;
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
use App\Framework\QrCode\ValueObjects\QrCodeConfig;
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
use App\Framework\QrCode\ValueObjects\EncodingMode;
use App\Framework\QrCode\ValueObjects\QrCodeStyle;
echo "=== SVG Rendering Issues Test ===\n\n";
$testData = 'HELLO WORLD';
$config = new QrCodeConfig(
version: QrCodeVersion::fromNumber(1),
errorCorrectionLevel: ErrorCorrectionLevel::M,
encodingMode: EncodingMode::BYTE
);
$matrix = QrCodeGenerator::generate($testData, $config);
$renderer = new QrCodeRenderer();
// Test with default style
echo "=== Default Style ===\n";
$defaultStyle = QrCodeStyle::default();
echo "Module size: {$defaultStyle->moduleSize}px\n";
echo "Quiet zone: {$defaultStyle->quietZoneSize} modules\n";
$canvasSize = $defaultStyle->calculateCanvasSize($matrix->getSize());
echo "Canvas size: {$canvasSize}px\n\n";
$svg = $renderer->renderSvg($matrix);
$outputPath = __DIR__ . '/test-qrcodes/default-style.svg';
file_put_contents($outputPath, $svg);
echo "✅ Saved: {$outputPath}\n";
echo "Size: " . strlen($svg) . " bytes\n\n";
// Test with larger module size
echo "=== Large Module Size (20px) ===\n";
$largeStyle = QrCodeStyle::large();
echo "Module size: {$largeStyle->moduleSize}px\n";
echo "Quiet zone: {$largeStyle->quietZoneSize} modules\n";
$canvasSize = $largeStyle->calculateCanvasSize($matrix->getSize());
echo "Canvas size: {$canvasSize}px\n\n";
$svgLarge = $renderer->renderSvg($matrix, $largeStyle);
$outputPathLarge = __DIR__ . '/test-qrcodes/large-modules.svg';
file_put_contents($outputPathLarge, $svgLarge);
echo "✅ Saved: {$outputPathLarge}\n";
echo "Size: " . strlen($svgLarge) . " bytes\n\n";
// Analyze SVG structure
echo "=== SVG Analysis ===\n";
$rectCount = substr_count($svg, '<rect');
echo "Rectangles: {$rectCount}\n";
// Check for white background
if (strpos($svg, 'fill="white"') !== false || strpos($svg, 'fill="#FFFFFF"') !== false || strpos($svg, 'fill="#ffffff"') !== false) {
echo "✅ Has white background\n";
} else {
echo "❌ Missing white background\n";
}
// Check for black modules
if (strpos($svg, 'fill="black"') !== false || strpos($svg, 'fill="#000000"') !== false || strpos($svg, 'fill="#000"') !== false) {
echo "✅ Has black modules\n";
} else {
echo "❌ Missing black modules\n";
}
// Check SVG dimensions
preg_match('/width="([0-9.]+)"\s+height="([0-9.]+)"/', $svg, $matches);
if (!empty($matches)) {
$width = (float)$matches[1];
$height = (float)$matches[2];
echo "SVG dimensions: {$width}x{$height}px\n";
// Calculate expected size
$matrixSize = $matrix->getSize();
$expectedSize = ($matrixSize + 2 * $defaultStyle->quietZone) * $defaultStyle->moduleSize;
if (abs($width - $expectedSize) < 1) {
echo "✅ Dimensions correct\n";
} else {
echo "⚠️ Dimensions might be off: expected ~{$expectedSize}px\n";
}
}
echo "\n";
// Check for common SVG issues
echo "=== Common SVG Issues ===\n";
// Check if rectangles are properly positioned
preg_match_all('/x="([0-9.]+)"\s+y="([0-9.]+)"/', $svg, $positionMatches);
if (!empty($positionMatches[1])) {
$minX = min(array_map('floatval', $positionMatches[1]));
$minY = min(array_map('floatval', $positionMatches[2]));
echo "First rectangle position: ({$minX}, {$minY})\n";
// Quiet zone should start at moduleSize * quietZone
$expectedStart = $defaultStyle->moduleSize * $defaultStyle->quietZone;
if (abs($minX - $expectedStart) < 1) {
echo "✅ Quiet zone position correct\n";
} else {
echo "⚠️ Quiet zone position: expected {$expectedStart}px, got {$minX}px\n";
}
}
// Check rectangle sizes
preg_match_all('/width="([0-9.]+)"\s+height="([0-9.]+)"/', $svg, $sizeMatches);
if (!empty($sizeMatches[1])) {
$widths = array_unique(array_map('floatval', $sizeMatches[1]));
$heights = array_unique(array_map('floatval', $sizeMatches[2]));
echo "Rectangle sizes: " . implode(', ', $widths) . " x " . implode(', ', $heights) . "\n";
$expectedSize = $defaultStyle->moduleSize;
if (in_array($expectedSize, $widths) && in_array($expectedSize, $heights)) {
echo "✅ Module size correct ({$expectedSize}px)\n";
} else {
echo "⚠️ Module size might be wrong: expected {$expectedSize}px\n";
}
}
echo "\n";
// Generate PNG version for better scanner compatibility
echo "=== Generating PNG Version ===\n";
echo "PNG format is often more reliable for QR code scanners.\n";
echo "SVG can have issues with:\n";
echo "1. Anti-aliasing in browsers\n";
echo "2. Scaling issues\n";
echo "3. Color precision\n";
echo "4. Rendering differences between browsers\n\n";
echo "Recommendation: Use PNG for production QR codes.\n";