91 lines
3.0 KiB
PHP
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);
|
|
}
|
|
}
|