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.
227 lines
6.0 KiB
PHP
227 lines
6.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use App\Framework\QrCode\QrCodeGenerator;
|
|
use App\Framework\QrCode\ValueObjects\ErrorCorrectionLevel;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeConfig;
|
|
use App\Framework\QrCode\ValueObjects\QrCodeVersion;
|
|
use App\Framework\QrCode\ValueObjects\EncodingMode;
|
|
|
|
echo "=== Complete Matrix Structure Analysis ===\n\n";
|
|
|
|
$testData = 'HELLO WORLD';
|
|
$config = new QrCodeConfig(
|
|
version: QrCodeVersion::fromNumber(1),
|
|
errorCorrectionLevel: ErrorCorrectionLevel::M,
|
|
encodingMode: EncodingMode::BYTE
|
|
);
|
|
|
|
$matrix = QrCodeGenerator::generate($testData, $config);
|
|
$size = $matrix->getSize();
|
|
|
|
echo "Matrix size: {$size}x{$size}\n\n";
|
|
|
|
// 1. Verify all required components
|
|
echo "=== Component Verification ===\n";
|
|
|
|
// Finder patterns
|
|
$finderOk = true;
|
|
$finderPatterns = [
|
|
['name' => 'Top-Left', 'row' => 0, 'col' => 0],
|
|
['name' => 'Top-Right', 'row' => 0, 'col' => 14],
|
|
['name' => 'Bottom-Left', 'row' => 14, 'col' => 0],
|
|
];
|
|
|
|
$expectedFinder = [
|
|
[1, 1, 1, 1, 1, 1, 1],
|
|
[1, 0, 0, 0, 0, 0, 1],
|
|
[1, 0, 1, 1, 1, 0, 1],
|
|
[1, 0, 1, 1, 1, 0, 1],
|
|
[1, 0, 1, 1, 1, 0, 1],
|
|
[1, 0, 0, 0, 0, 0, 1],
|
|
[1, 1, 1, 1, 1, 1, 1],
|
|
];
|
|
|
|
foreach ($finderPatterns as $finder) {
|
|
$errors = 0;
|
|
for ($r = 0; $r < 7; $r++) {
|
|
for ($c = 0; $c < 7; $c++) {
|
|
$row = $finder['row'] + $r;
|
|
$col = $finder['col'] + $c;
|
|
$isDark = $matrix->getModuleAt($row, $col)->isDark();
|
|
$expectedDark = $expectedFinder[$r][$c] === 1;
|
|
|
|
if ($isDark !== $expectedDark) {
|
|
$errors++;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($errors === 0) {
|
|
echo "✅ {$finder['name']} finder pattern\n";
|
|
} else {
|
|
echo "❌ {$finder['name']} finder pattern ({$errors} errors)\n";
|
|
$finderOk = false;
|
|
}
|
|
}
|
|
|
|
// Timing patterns
|
|
$timingOk = true;
|
|
for ($col = 8; $col <= 12; $col++) {
|
|
$expectedDark = (($col - 8) % 2) === 0;
|
|
$isDark = $matrix->getModuleAt(6, $col)->isDark();
|
|
if ($isDark !== $expectedDark) {
|
|
$timingOk = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
for ($row = 8; $row <= 12; $row++) {
|
|
$expectedDark = (($row - 8) % 2) === 0;
|
|
$isDark = $matrix->getModuleAt($row, 6)->isDark();
|
|
if ($isDark !== $expectedDark) {
|
|
$timingOk = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if ($timingOk) {
|
|
echo "✅ Timing patterns\n";
|
|
} else {
|
|
echo "❌ Timing patterns\n";
|
|
}
|
|
|
|
// Dark module
|
|
$darkModuleRow = 4 * 1 + 9; // Version 1
|
|
$darkModuleCol = 8;
|
|
$isDark = $matrix->getModuleAt($darkModuleRow, $darkModuleCol)->isDark();
|
|
if ($isDark) {
|
|
echo "✅ Dark module\n";
|
|
} else {
|
|
echo "❌ Dark module missing\n";
|
|
}
|
|
|
|
// Format information
|
|
$formatCols = [0, 1, 2, 3, 4, 5, 7, 8, 20, 19, 18, 17, 16, 15, 14];
|
|
$formatH = '';
|
|
foreach ($formatCols as $col) {
|
|
$formatH .= $matrix->getModuleAt(8, $col)->isDark() ? '1' : '0';
|
|
}
|
|
|
|
$formatRows = [20, 19, 18, 17, 16, 15, 14, 8, 7, 5, 4, 3, 2, 1, 0];
|
|
$formatV = '';
|
|
foreach ($formatRows as $row) {
|
|
$formatV .= $matrix->getModuleAt($row, 8)->isDark() ? '1' : '0';
|
|
}
|
|
|
|
if ($formatH === $formatV) {
|
|
echo "✅ Format information (match)\n";
|
|
} else {
|
|
echo "❌ Format information (mismatch)\n";
|
|
echo " Horizontal: {$formatH}\n";
|
|
echo " Vertical: {$formatV}\n";
|
|
}
|
|
|
|
echo "\n";
|
|
|
|
// 2. Check if there are any obvious structural issues
|
|
echo "=== Structural Issues Check ===\n";
|
|
|
|
// Count dark/light modules
|
|
$darkCount = 0;
|
|
$lightCount = 0;
|
|
for ($row = 0; $row < $size; $row++) {
|
|
for ($col = 0; $col < $size; $col++) {
|
|
if ($matrix->getModuleAt($row, $col)->isDark()) {
|
|
$darkCount++;
|
|
} else {
|
|
$lightCount++;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo "Dark modules: {$darkCount}\n";
|
|
echo "Light modules: {$lightCount}\n";
|
|
echo "Total: " . ($darkCount + $lightCount) . " (expected: " . ($size * $size) . ")\n";
|
|
|
|
if (($darkCount + $lightCount) === ($size * $size)) {
|
|
echo "✅ All modules are set\n";
|
|
} else {
|
|
echo "❌ Missing modules!\n";
|
|
}
|
|
|
|
// Check data area
|
|
$dataAreaDark = 0;
|
|
$dataAreaTotal = 0;
|
|
for ($row = 0; $row < $size; $row++) {
|
|
for ($col = 0; $col < $size; $col++) {
|
|
// Skip function patterns
|
|
if (
|
|
($row <= 8 && $col <= 8) ||
|
|
($row <= 7 && $col >= $size - 8) ||
|
|
($row >= $size - 8 && $col <= 7) ||
|
|
$row === 6 || $col === 6 ||
|
|
($row === 8 && ($col <= 8 || $col >= $size - 8)) ||
|
|
($col === 8 && ($row <= 7 || $row >= 9)) ||
|
|
($row === 13 && $col === 8)
|
|
) {
|
|
continue;
|
|
}
|
|
|
|
$dataAreaTotal++;
|
|
if ($matrix->getModuleAt($row, $col)->isDark()) {
|
|
$dataAreaDark++;
|
|
}
|
|
}
|
|
}
|
|
|
|
echo "\nData area:\n";
|
|
echo " Total modules: {$dataAreaTotal}\n";
|
|
echo " Dark modules: {$dataAreaDark}\n";
|
|
echo " Light modules: " . ($dataAreaTotal - $dataAreaDark) . "\n";
|
|
|
|
if ($dataAreaDark > 0 && $dataAreaTotal > 0) {
|
|
echo "✅ Data area has content\n";
|
|
} else {
|
|
echo "❌ Data area is empty!\n";
|
|
}
|
|
|
|
echo "\n";
|
|
|
|
// 3. Generate a minimal test QR code
|
|
echo "=== Generating Minimal Test QR Code ===\n";
|
|
$minimalData = 'A';
|
|
$minimalMatrix = QrCodeGenerator::generate($minimalData, $config);
|
|
|
|
// Output as text for manual inspection
|
|
echo "Minimal QR Code (A):\n";
|
|
for ($row = 0; $row < 21; $row++) {
|
|
$line = '';
|
|
for ($col = 0; $col < 21; $col++) {
|
|
$line .= $minimalMatrix->getModuleAt($row, $col)->isDark() ? '██' : ' ';
|
|
}
|
|
echo $line . "\n";
|
|
}
|
|
|
|
echo "\n";
|
|
|
|
// Summary
|
|
echo "=== Summary ===\n";
|
|
if ($finderOk && $timingOk && $isDark && $formatH === $formatV && $dataAreaDark > 0) {
|
|
echo "✅ All structural checks passed\n";
|
|
echo "\nThe QR code structure appears correct.\n";
|
|
echo "If it still doesn't scan, the issue might be:\n";
|
|
echo "1. SVG rendering (try PNG instead)\n";
|
|
echo "2. Module size too small for scanner\n";
|
|
echo "3. Quiet zone too small\n";
|
|
echo "4. Color contrast issues\n";
|
|
echo "5. Data encoding/masking issues\n";
|
|
} else {
|
|
echo "❌ Structural issues found\n";
|
|
echo "Fix these before testing scanning.\n";
|
|
}
|
|
|