2021-09-07 23:01:53 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Services;
|
|
|
|
|
2022-11-22 15:15:52 +01:00
|
|
|
use chillerlan\QRCode\QRCode;
|
|
|
|
use chillerlan\QRCode\QROptions;
|
2021-10-15 23:46:21 +02:00
|
|
|
use Illuminate\Support\Facades\Log;
|
2024-03-22 18:04:44 +01:00
|
|
|
use Zxing\ChecksumException;
|
|
|
|
use Zxing\FormatException;
|
|
|
|
use Zxing\NotFoundException;
|
2022-11-22 15:15:52 +01:00
|
|
|
use Zxing\QrReader;
|
2021-09-07 23:01:53 +02:00
|
|
|
|
|
|
|
class QrCodeService
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* Encode a string into a QR code image
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
2024-04-20 19:03:44 +02:00
|
|
|
* @param string $data The string to encode
|
2022-11-22 15:15:52 +01:00
|
|
|
* @return mixed
|
2021-09-07 23:01:53 +02:00
|
|
|
*/
|
2022-07-30 10:46:02 +02:00
|
|
|
public static function encode(string $data)
|
2021-09-07 23:01:53 +02:00
|
|
|
{
|
|
|
|
$options = new QROptions([
|
|
|
|
'quietzoneSize' => 2,
|
|
|
|
'scale' => 8,
|
|
|
|
]);
|
|
|
|
|
|
|
|
$qrcode = new QRCode($options);
|
|
|
|
|
2021-10-15 23:46:21 +02:00
|
|
|
Log::info('data encoded to QR code');
|
|
|
|
|
2024-06-21 14:55:22 +02:00
|
|
|
return $qrcode->render($data);
|
2021-09-07 23:01:53 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Decode an uploaded QR code image
|
2022-11-22 15:15:52 +01:00
|
|
|
*
|
2022-08-26 15:57:18 +02:00
|
|
|
* @return string
|
2021-09-07 23:01:53 +02:00
|
|
|
*/
|
2022-07-30 10:46:02 +02:00
|
|
|
public static function decode(\Illuminate\Http\UploadedFile $file)
|
2021-09-07 23:01:53 +02:00
|
|
|
{
|
2024-07-03 11:16:08 +02:00
|
|
|
$qrcode = app()->make(QrReader::class, [
|
|
|
|
'imgSource' => $file->get(),
|
|
|
|
'sourceType' => QrReader::SOURCE_TYPE_BLOB
|
|
|
|
]);
|
|
|
|
|
2024-03-22 18:04:44 +01:00
|
|
|
$text = $qrcode->text();
|
2021-09-07 23:01:53 +02:00
|
|
|
|
2024-03-22 18:04:44 +01:00
|
|
|
if (! $text) {
|
|
|
|
$text = $qrcode->text([
|
|
|
|
'TRY_HARDER' => true,
|
|
|
|
'NR_ALLOW_SKIP_ROWS' => 0,
|
|
|
|
]);
|
2021-09-07 23:01:53 +02:00
|
|
|
}
|
2022-11-22 15:15:52 +01:00
|
|
|
|
2024-03-22 18:04:44 +01:00
|
|
|
// At this point, if we do not have a text, QR code cannot be detected or decoded
|
|
|
|
// so we check the error to provide the user a relevant error message
|
|
|
|
if (! $text) {
|
|
|
|
switch (get_class($qrcode->getError())) {
|
|
|
|
case NotFoundException::class:
|
|
|
|
throw new \App\Exceptions\InvalidQrCodeException(__('errors.cannot_detect_qrcode_in_image'));
|
|
|
|
case FormatException::class:
|
|
|
|
throw new \App\Exceptions\InvalidQrCodeException(__('errors.cannot_decode_detected_qrcode'));
|
|
|
|
case ChecksumException::class:
|
|
|
|
throw new \App\Exceptions\InvalidQrCodeException(__('errors.qrcode_has_invalid_checksum'));
|
|
|
|
default:
|
|
|
|
throw new \App\Exceptions\InvalidQrCodeException(__('errors.no_readable_qrcode'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
$data = urldecode($qrcode->text());
|
|
|
|
|
2021-10-15 23:46:21 +02:00
|
|
|
Log::info('QR code decoded');
|
2021-09-07 23:01:53 +02:00
|
|
|
|
|
|
|
return $data;
|
|
|
|
}
|
2022-11-22 15:15:52 +01:00
|
|
|
}
|