Files
2026-06-16 19:33:55 +02:00

91 lines
3.0 KiB
PHP

<?php
namespace Reservair\Templating\Elements;
use Reservair\Templating\RsvTemplateElement;
use Reservair\Templating\RsvTemplateSymbols;
use chillerlan\QRCode\Output\QRGdImagePNG;
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\Data\QRMatrix;
use chillerlan\QRCode\QROptions;
use chillerlan\QRCode\Output\QROutputInterface;
/** Renders a QR payment code for the form's total price into an email body. */
class RsvQrPaymentElement implements RsvTemplateElement {
public function render(RsvTemplateSymbols $symbols): string {
$account = trim((string) $symbols->get('account', ''));
if ($account === '') {
return ''; // No payee account configured — nothing to render.
}
$payload = $this->spayd(
$account,
(float) $symbols->get('price', 0),
(string) $symbols->get('currency', 'CZK'),
(string) $symbols->get('message', ''),
(string) $symbols->get('variable_symbol', '')
);
$src = $this->image_url($payload);
if ($src === '') {
return ''; // Image could not be written.
}
return '<img class="rsv-qr-payment" alt="' . esc_attr__('QR platba', 'reservair')
. '" src="' . esc_url($src) . '" />';
}
public function symbols(): array {
return ['account', 'currency', 'message', 'variable_symbol'];
}
/** Builds a SPAYD string (Czech QR payment). '*' is the field delimiter. */
private function spayd(string $account, float $price, string $currency, string $message, string $vs): string {
$parts = [
'SPD*1.0',
'ACC:' . $account,
'AM:' . number_format($price, 2, '.', ''),
'CC:' . $currency,
];
if ($message !== '') {
$parts[] = 'MSG:' . str_replace('*', ' ', $message);
}
if ($vs !== '') {
$parts[] = 'X-VS:' . preg_replace('/\D/', '', $vs);
}
return implode('*', $parts);
}
/**
* Writes the QR PNG under uploads (deduped by payload hash) and returns its
* public URL, or '' if it could not be written.
*/
private function image_url(string $payload): string {
$uploads = wp_upload_dir();
$dir = $uploads['basedir'] . '/reservair-qr';
$name = hash('sha256', $payload) . '.png';
$path = $dir . '/' . $name;
if (!file_exists($path)) {
wp_mkdir_p($dir);
if (file_put_contents($path, $this->png($payload)) === false) {
return '';
}
}
return $uploads['baseurl'] . '/reservair-qr/' . $name;
}
private function png(string $payload): string {
$options = new QROptions();
$options->version = 7;
$options->outputInterface = QRGdImagePNG::class;
$options->scale = 4;
$options->outputBase64 = false;
$options->bgColor = [200, 150, 200];
return (string) (new QRCode($options))->render($payload);
}
}