- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
136 lines
4.1 KiB
PHP
136 lines
4.1 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 "=== Generating Side-by-Side Comparison ===\n\n";
|
|
|
|
// 1. Generate our QR code
|
|
$config = new QrCodeConfig(
|
|
version: QrCodeVersion::fromNumber(1),
|
|
errorCorrectionLevel: ErrorCorrectionLevel::M,
|
|
encodingMode: EncodingMode::BYTE
|
|
);
|
|
|
|
$ourMatrix = QrCodeGenerator::generate("HELLO WORLD", $config);
|
|
$size = 21;
|
|
|
|
// Extract our format info
|
|
$formatCols = [0, 1, 2, 3, 4, 5, 7, 8, 20, 19, 18, 17, 16, 15, 14];
|
|
$ourFormat = '';
|
|
foreach ($formatCols as $col) {
|
|
$ourFormat .= $ourMatrix->getModuleAt(8, $col)->isDark() ? '1' : '0';
|
|
}
|
|
|
|
echo "Our QR Code:\n";
|
|
echo " Format Info: $ourFormat\n";
|
|
echo " Decoded: M, Mask 2\n\n";
|
|
|
|
// 2. Load Python reference
|
|
$pythonImg = imagecreatefrompng('/var/www/html/public/qrcode-python-large.png');
|
|
|
|
function getPythonBit($img, $row, $col): string {
|
|
$scale = 20;
|
|
$qz = 4;
|
|
$x = ($qz + $col) * $scale + 10;
|
|
$y = ($qz + $row) * $scale + 10;
|
|
$rgb = imagecolorat($img, $x, $y);
|
|
$r = ($rgb >> 16) & 0xFF;
|
|
return $r < 128 ? '1' : '0';
|
|
}
|
|
|
|
$pythonFormat = '';
|
|
foreach ($formatCols as $col) {
|
|
$pythonFormat .= getPythonBit($pythonImg, 8, $col);
|
|
}
|
|
|
|
echo "Python QR Code:\n";
|
|
echo " Format Info: $pythonFormat\n";
|
|
echo " Decoded: M, Mask 0\n\n";
|
|
|
|
// 3. Create comparison image (side-by-side)
|
|
$scale = 15;
|
|
$qz = 4;
|
|
$qrSize = ($size + 2 * $qz) * $scale;
|
|
$totalWidth = $qrSize * 2 + 60; // Two QR codes + spacing
|
|
$totalHeight = $qrSize + 80;
|
|
|
|
$image = imagecreatetruecolor($totalWidth, $totalHeight);
|
|
$white = imagecolorallocate($image, 255, 255, 255);
|
|
$black = imagecolorallocate($image, 0, 0, 0);
|
|
$red = imagecolorallocate($image, 255, 0, 0);
|
|
$gray = imagecolorallocate($image, 200, 200, 200);
|
|
|
|
imagefill($image, 0, 0, $white);
|
|
|
|
// Draw labels
|
|
imagestring($image, 5, 40, 10, "OUR CODE (Mask 2)", $black);
|
|
imagestring($image, 5, $qrSize + 80, 10, "PYTHON (Mask 0 - WORKS!)", $black);
|
|
|
|
// Draw grid background
|
|
for ($r = 0; $r < $size; $r++) {
|
|
for ($c = 0; $c < $size; $c++) {
|
|
// Our code (left)
|
|
$x1 = ($qz + $c) * $scale + 20;
|
|
$y1 = ($qz + $r) * $scale + 40;
|
|
imagerectangle($image, $x1, $y1, $x1+$scale-1, $y1+$scale-1, $gray);
|
|
|
|
// Python (right)
|
|
$x2 = $qrSize + 40 + ($qz + $c) * $scale;
|
|
$y2 = ($qz + $r) * $scale + 40;
|
|
imagerectangle($image, $x2, $y2, $x2+$scale-1, $y2+$scale-1, $gray);
|
|
}
|
|
}
|
|
|
|
// Draw modules
|
|
$diffCount = 0;
|
|
for ($r = 0; $r < $size; $r++) {
|
|
for ($c = 0; $c < $size; $c++) {
|
|
$ourDark = $ourMatrix->getModuleAt($r, $c)->isDark();
|
|
$pythonDark = getPythonBit($pythonImg, $r, $c) === '1';
|
|
|
|
// Our code
|
|
if ($ourDark) {
|
|
$x = ($qz + $c) * $scale + 20;
|
|
$y = ($qz + $r) * $scale + 40;
|
|
imagefilledrectangle($image, $x, $y, $x+$scale-1, $y+$scale-1, $black);
|
|
}
|
|
|
|
// Python code
|
|
if ($pythonDark) {
|
|
$x = $qrSize + 40 + ($qz + $c) * $scale;
|
|
$y = ($qz + $r) * $scale + 40;
|
|
imagefilledrectangle($image, $x, $y, $x+$scale-1, $y+$scale-1, $black);
|
|
}
|
|
|
|
// Mark differences in red
|
|
if ($ourDark !== $pythonDark) {
|
|
$diffCount++;
|
|
// Mark on our code
|
|
$x = ($qz + $c) * $scale + 20 + $scale/2;
|
|
$y = ($qz + $r) * $scale + 40 + $scale/2;
|
|
imagefilledellipse($image, (int)$x, (int)$y, 3, 3, $red);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add diff count
|
|
$diffText = "Differences: $diffCount modules (" . number_format($diffCount / 441 * 100, 1) . "%)";
|
|
imagestring($image, 3, 20, $qrSize + 50, $diffText, $black);
|
|
|
|
imagepng($image, '/var/www/html/public/qr-comparison.png');
|
|
imagedestroy($image);
|
|
imagedestroy($pythonImg);
|
|
|
|
echo "✅ Generated comparison: qr-comparison.png\n";
|
|
echo " Differences: $diffCount / 441 modules (" . number_format($diffCount / 441 * 100, 1) . "%)\n";
|
|
echo "\nURL: https://localhost/qr-comparison.png\n";
|
|
|