Added suport for error correction level to QR codes

This commit is contained in:
Alejandro Celaya 2021-07-13 13:22:50 +02:00
parent 32f483c333
commit 5a2350bac1
2 changed files with 37 additions and 10 deletions

View File

@ -35,10 +35,7 @@
"required": false,
"schema": {
"type": "string",
"enum": [
"png",
"svg"
]
"enum": ["png", "svg"]
}
},
{
@ -51,6 +48,16 @@
"minimum": 0,
"default": 0
}
},
{
"name": "errorCorrection",
"in": "query",
"description": "The error correction level to apply to the the QR code: **[L]**ow, **[M]**edium, **[Q]**uartile or **[H]**igh. See [docs](https://www.qrcode.com/en/about/error_correction.html).",
"required": false,
"schema": {
"type": "string",
"enum": ["L", "M", "Q", "H"]
}
}
],
"responses": {

View File

@ -5,6 +5,11 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\Action;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelHigh;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelInterface;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelLow;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelMedium;
use Endroid\QrCode\ErrorCorrectionLevel\ErrorCorrectionLevelQuartile;
use Endroid\QrCode\Writer\SvgWriter;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
@ -18,6 +23,9 @@ use Shlinkio\Shlink\Core\Model\ShortUrlIdentifier;
use Shlinkio\Shlink\Core\Service\ShortUrl\ShortUrlResolverInterface;
use Shlinkio\Shlink\Core\ShortUrl\Helper\ShortUrlStringifierInterface;
use function strtoupper;
use function trim;
class QrCodeAction implements MiddlewareInterface
{
private const DEFAULT_SIZE = 300;
@ -46,17 +54,18 @@ class QrCodeAction implements MiddlewareInterface
}
$query = $request->getQueryParams();
$qrCode = Builder::create()
$qrCodeBuilder = Builder::create()
->data($this->stringifier->stringify($shortUrl))
->size($this->resolveSize($request, $query))
->margin($this->resolveMargin($query));
->margin($this->resolveMargin($query))
->errorCorrectionLevel($this->resolveErrorCorrection($query));
$format = $query['format'] ?? 'png';
if ($format === 'svg') {
$qrCode->writer(new SvgWriter());
$qrCodeBuilder->writer(new SvgWriter());
}
return new QrCodeResponse($qrCode->build());
return new QrCodeResponse($qrCodeBuilder->build());
}
private function resolveSize(Request $request, array $query): int
@ -72,11 +81,11 @@ class QrCodeAction implements MiddlewareInterface
private function resolveMargin(array $query): int
{
if (! isset($query['margin'])) {
$margin = $query['margin'] ?? null;
if ($margin === null) {
return 0;
}
$margin = $query['margin'];
$intMargin = (int) $margin;
if ($margin !== (string) $intMargin) {
return 0;
@ -84,4 +93,15 @@ class QrCodeAction implements MiddlewareInterface
return $intMargin < 0 ? 0 : $intMargin;
}
private function resolveErrorCorrection(array $query): ErrorCorrectionLevelInterface
{
$errorCorrectionLevel = strtoupper(trim($query['errorCorrection'] ?? ''));
return match ($errorCorrectionLevel) {
'H' => new ErrorCorrectionLevelHigh(),
'Q' => new ErrorCorrectionLevelQuartile(),
'M' => new ErrorCorrectionLevelMedium(),
default => new ErrorCorrectionLevelLow(), // 'L'
};
}
}