Scaffolded from the Ladill mini/events extraction pattern: multi-file transfers, retention controls, public landing pages, analytics, and Gitea deploy workflow. Co-authored-by: Cursor <cursoragent@cursor.com>
71 lines
2.6 KiB
PHP
71 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Support\Qr;
|
|
|
|
use App\Models\QrCode;
|
|
use Illuminate\Support\Collection;
|
|
|
|
/**
|
|
* Generates ZPL II label code for Zebra-style badge/label printers.
|
|
* One ^XA…^XZ label block per attendee, sized to the chosen badge size at 203 dpi.
|
|
*/
|
|
class EventBadgeZpl
|
|
{
|
|
/** @param Collection<int, \App\Models\QrEventRegistration> $registrations */
|
|
public static function forRegistrations(QrCode $qrCode, Collection $registrations): string
|
|
{
|
|
$content = $qrCode->content();
|
|
$eventName = self::sanitize($content['name'] ?? $qrCode->label);
|
|
$size = $content['badge_size'] ?? '4x3';
|
|
|
|
// Label dimensions in dots @ 203 dpi.
|
|
[$widthDots, $heightDots] = match ($size) {
|
|
'4x6' => [812, 1218],
|
|
'cr80' => [685, 431],
|
|
default => [812, 609], // 4x3
|
|
};
|
|
|
|
$labels = [];
|
|
foreach ($registrations as $reg) {
|
|
$name = self::sanitize($reg->attendee_name);
|
|
$tier = self::sanitize($reg->tier_name);
|
|
$extra = collect($reg->badge_fields ?? [])
|
|
->map(fn ($v, $k) => self::sanitize($k . ': ' . $v))
|
|
->implode(' | ');
|
|
|
|
$zpl = "^XA\n";
|
|
$zpl .= "^PW{$widthDots}\n";
|
|
$zpl .= "^LL{$heightDots}\n";
|
|
$zpl .= "^CI28\n"; // UTF-8
|
|
// Event name (top)
|
|
$zpl .= "^FO40,40^A0N,40,40^FB" . ($widthDots - 80) . ",1,0,C^FD{$eventName}^FS\n";
|
|
// Attendee name (large, centered)
|
|
$zpl .= "^FO40,150^A0N,80,80^FB" . ($widthDots - 80) . ",2,0,C^FD{$name}^FS\n";
|
|
// Tier
|
|
$zpl .= "^FO40,320^A0N,40,40^FB" . ($widthDots - 80) . ",1,0,C^FD{$tier}^FS\n";
|
|
// Extra fields
|
|
if ($extra !== '') {
|
|
$zpl .= "^FO40,375^A0N,28,28^FB" . ($widthDots - 80) . ",2,0,C^FD{$extra}^FS\n";
|
|
}
|
|
// QR of the badge code (bottom)
|
|
$qrX = (int) (($widthDots / 2) - 70);
|
|
$zpl .= "^FO{$qrX}," . ($heightDots - 200) . "^BQN,2,5^FDLA,{$reg->badge_code}^FS\n";
|
|
// Badge code text
|
|
$zpl .= "^FO40," . ($heightDots - 60) . "^A0N,34,34^FB" . ($widthDots - 80) . ",1,0,C^FD{$reg->badge_code}^FS\n";
|
|
$zpl .= "^XZ\n";
|
|
|
|
$labels[] = $zpl;
|
|
}
|
|
|
|
return implode("\n", $labels);
|
|
}
|
|
|
|
private static function sanitize(string $value): string
|
|
{
|
|
// Escape ZPL control chars (^ and ~) and collapse whitespace.
|
|
$value = str_replace(['^', '~'], [' ', ' '], $value);
|
|
|
|
return trim(preg_replace('/\s+/', ' ', $value) ?? '');
|
|
}
|
|
}
|