Skip to content

Commit

Permalink
refactor: updated endroid/qr-code
Browse files Browse the repository at this point in the history
  • Loading branch information
petrknap committed Oct 12, 2023
1 parent da11ea5 commit 1e613a8
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 81 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ RUN docker-php-ext-install \

WORKDIR /app
COPY . .
RUN composer install
RUN composer update --prefer-lowest
Empty file modified README.md
100644 → 100755
Empty file.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
"name": "petrknap/spayd-qr",
"require": {
"php": ">=8.0",
"endroid/qr-code": "^3.5",
"endroid/qr-code": "^4.0",
"moneyphp/money": "^4.0",
"sunfoxcz/spayd-php": "^2.0"
},
Expand Down
36 changes: 18 additions & 18 deletions src/SpaydQr.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace PetrKnap\SpaydQr;

use Endroid\QrCode\QrCode;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Builder\BuilderInterface;
use Endroid\QrCode\Encoding\Encoding;
use Endroid\QrCode\Writer\PngWriter;
use Endroid\QrCode\Writer\WriterInterface;
use Endroid\QrCode\Writer\Result\ResultInterface;
use Money\Currencies\ISOCurrencies;
use Money\Formatter\DecimalMoneyFormatter;
use Money\Money;
Expand All @@ -15,7 +18,7 @@ class SpaydQr implements SpaydQrInterface
/** @internal */
protected function __construct(
/** @internal */ protected Spayd $spayd,
private QrCode $qrCode,
/** @internal */ protected BuilderInterface $qrCodeBuilder,
string $iban,
Money $money
) {
Expand All @@ -27,12 +30,11 @@ protected function __construct(

public static function create(string $iban, Money $money, WriterInterface $writer = null): self
{
$qrCode = new QrCode();
$qrCode->setWriter($writer ?: new PngWriter());

return new self(
new Spayd(),
$qrCode,
Builder::create()
->writer($writer ?: new PngWriter())
->encoding(new Encoding('UTF-8')),
$iban,
$money
);
Expand Down Expand Up @@ -80,47 +82,45 @@ public function setInvoice(

public function setWriter(WriterInterface $writer): self
{
$this->qrCode->setWriter($writer);
$this->qrCodeBuilder->writer($writer);

return $this;
}

public function getContentType(): string
{
return $this->prepareQrCode(null, null, null)->getContentType();
return $this->buildQrCode(null, null)->getMimeType();
}

public function getContent(int $size = self::QR_SIZE, int $margin = self::QR_MARGIN): string
{
return $this->prepareQrCode($this->spayd, $size, $margin)->writeString();
return $this->buildQrCode($size, $margin)->getString();
}

public function getDataUri(int $size = self::QR_SIZE, int $margin = self::QR_MARGIN): string
{
return $this->prepareQrCode($this->spayd, $size, $margin)->writeDataUri();
return $this->buildQrCode($size, $margin)->getDataUri();
}

public function writeFile(string $path, int $size = self::QR_SIZE, int $margin = self::QR_MARGIN): void
{
$this->prepareQrCode($this->spayd, $size, $margin)->writeFile($path);
$this->buildQrCode($size, $margin)->saveToFile($path);
}

/** @internal */
protected function prepareQrCode(?Spayd $spayd, ?int $size, ?int $margin): QrCode
protected function buildQrCode(?int $size, ?int $margin): ResultInterface
{
if ($spayd !== null) {
$this->qrCode->setText($spayd->generate());
}
$this->qrCodeBuilder->data($this->spayd->generate());

if ($size !== null) {
$this->qrCode->setSize($size);
$this->qrCodeBuilder->size($size);
}

if ($margin !== null) {
$this->qrCode->setMargin($margin);
$this->qrCodeBuilder->margin($margin);
}

return $this->qrCode;
return $this->qrCodeBuilder->build();
}

private function getAmount(Money $money): string
Expand Down
1 change: 1 addition & 0 deletions src/SpaydQrInterface.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function setInvoice(
?string $buyerVatIdentificationNumber,
?string $description
): self;
/** @todo create own enum of writers */
public function setWriter(WriterInterface $writer): self;

public function getContentType(): string;
Expand Down
2 changes: 1 addition & 1 deletion tests/ExamplesTest/readme_1.html
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAASwAAAEsCAIAAAD2HxkiAAAACXBIWXMAAA7EAAAOxAGVKw4bAAAHzUlEQVR4nO3dwXLjNhBFUSql//9lZ+GqZBYWNYbAfg3wnHUsUzTvhFUNgo+vr68DyHkex/F4PNKH8ZGBf0fOv3LZP0xNDmPM9IMf+8Clr97vL/VP+jDg7kQIYSKEMBFCmAghTIQQJkIIEyGEPdMHcKHpY9ziufDSY2j+3vsIO6zb2PhyXHohyNxr44orbYmr1+0ohIkQwkQIYSKEMBFCmAghTIQQNj6sv2KQ1WGqc9TO6JaYB75SefBzr41WV+/OK2ZOTkqTv8ESO0QsvZxgCW5HIUyEECZCCBMhhIkQwkQIYSKEsJ3nhE0GWcOH0WRngCancWM7Rziscjw9/Xc1mchPX2mwMbejECZCCBMhhIkQwkQIYSKEMBFCmDnhD2441F764Fe3c4Rj2w1UPpw+90eGP1CBWW5HIUyEECZCCBMhhIkQwkQIYSKEsJ3nhNNnd1ccSZNncAkaj7DJeyOaWH0UXrYIoezT+vyut9yOQpgIIUyEECZCCBMhhIkQwkQIYe/nhEuMueKK97pv/kdp8mD0289sYucVM31ULouxmGY5bkchTIQQJkIIEyGEiRDCRAhhIoQwc8IKlRP5XX9qY49Wjxiva+MLq8n0f+ML1e0ohIkQwkQIYSKEMBFCmAghTIQQ9jw6zbiajKRObDytaq7JqwSu2BbAipmwPpfCXAO/q88/tcXcjkKYCCFMhBAmQggTIYSJEMJECGHmhDcyNojrvz5h9W0BPoqwbCBb/B6CgV83/Uod+8CTn1p9FF65mqp4LYTbUQgTIYSJEMJECGEihDARQpgIIeySYX3xC9zLpsl9RlKV+hxJcwPP/n97vv0vpiu77DaeXDcx98qZvj5huouuKLejECZCCBMhhIkQwkQIYSKEMBFC2A5P1g8PSQc+cLqlJ5b9D77/tgDHRRFe8c37ryxpcoTTtzto8r2a++SadzsKYSKEMBFCmAghTIQQJkIIEyGEXfXO+umjwj6blt/Nludw+l7am7yzvs+D8HPH0/1X7Vxx5ivfWb/EspgTbkchTIQQJkIIEyGEiRDCRAhhIoSwq+aEzTe0Pzd9YUCT77WrspnqRb+o0bD+ROVF3OQxc91ebfoZ9s56WJUIIUyEECZCCBMhhIkQwkQIYWvMCac/B12sbIq45VPwxerP4fsI+1/ic01/c/rqYZRdAE22RDl3xdlwOwphIoQwEUKYCCFMhBAmQggTIYS9nxOWPSO/xJvim0zJlzhXW7oih+f5f9HnD7D0moF194TvcwGMGTgb9Tm4HYUwEUKYCCFMhBAmQggTIYSJEMIC2+BPf310kwF6c6vvTjBmiWug0fYWfdYM9L8itzzCJi8gqOd2FMJECGEihDARQpgIIUyEECZCCHse6z8VXvmBHpllwKs/9PfldNWwfvpotfkHXjE97zCR77OC4pUrjrB4YYDbUQgTIYSJEMJECGEihDARQpgIISzwZP3SH9hkOPZK88PjR4/ziXDxw85Nnp6uPIwmS3A6LAyo1GqzD7ejECZCCBMhhIkQwkQIYSKEMBFCWKMduPto8kb4DrO7e07/p79z4f0766eb/rDz9Muxydj9npd4E01WhhxuRyFOhBAmQggTIYSJEMJECGEihLBew/ql52bTx+5Ln43++pze6gj7bKveYbbe52y8MnyEZe+sH+PJeuB/IoQwEUKYCCFMhBAmQggTIYRVv7O+yfjrRP8jvELzB/zHNHl1wlu9VsycaPIcdNlhLLGZwNKmn+HhD3Q7CmEihDARQpgIIUyEECZCCBMhhH00J1x6yt//4Nedki9t+MIYXvDwPsImU/ITzR/ibqL/uwmWOO1X5OB2FMJECGEihDARQpgIIUyEECZCCFvmod4bmju+W3q1Qx9XfOvxCK/Ywr1sXFs8F+6w5f49DZz5yp3/v7kdhTARQpgIIUyEECZCCBMhhIkQwh5fX19j04/VB1lj32vXs8Gfpv+VP32yfjrX8efKrpLKdRe3vQDcjkKYCCFMhBAmQggTIYSJEMJECGH3fbJ+bCq16yxr1++1hOcx+kRw/13Qm7zOvv8xLLFIaO7pveLgPVkPqxIhhIkQwkQIYSKEMBFCmAgh7HmsP6jtMKA7MX3b5uJ3fTe/PPq8+fzCd9bzp+bBj6nf+H1RV7z64XA7CnEihDARQpgIIUyEECZCCBMhhJkT/s66b36/4heNfebdpovH6xP1fSreR9jhlDX5Y/fZZL5S84PvcH0en83x3Y5CmAghTIQQJkIIEyGEiRDCRAhh48P6VnsY/2iJjaWnW/34X9n1ex1WzPzWrun2f6nBxtyOQpgIIUyEECZCCBMhhIkQwkQIYfedE3pn/Z+Gt3Cf+Iv6KD7I+0Z4omwi32Si3SeMshNS/JXPv5fbUQgTIYSJEMJECGEihDARQpgIIcycsMLAKLzPtgCVI7W5W633mX+eu2+EA3Phi15Z3sHcfwvGfqTVAP1H08/GN7ejECZCCBMhhIkQwkQIYSKEMBFC2H3nhAP6jMKnH0nlYTR5lHm6gbPxt++sP/95/tN/3Ub/1TkDh7EBt6MQJkIIEyGEiRDCRAhhIoQwEULY+zlhnzHXXE3m3ZWaLAwYU3YY9d/XipnfKXsCvXiAXvaBxZY4DLejECZCCBMhhIkQwkQIYSKEMBFC2KPJIAVuy/8JIexfsTb0V5fR64oAAAAASUVORK5CYII=">
<img src="data:image/png;base64,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">
125 changes: 65 additions & 60 deletions tests/SpaydQrTest.php
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace PetrKnap\SpaydQr\Test;

use Endroid\QrCode\QrCode;
use Endroid\QrCode\Builder\Builder;
use Endroid\QrCode\Builder\BuilderInterface;
use Endroid\QrCode\Writer\Result\ResultInterface;
use Endroid\QrCode\Writer\SvgWriter;
use Endroid\QrCode\Writer\WriterInterface;
use Money\Money;
Expand Down Expand Up @@ -30,16 +32,13 @@ public function testFactoryWorks()
public function testSetWriterWorks()
{
$writer = $this->getMockBuilder(WriterInterface::class)->getMock();
$qrCode = $this->getMockBuilder(QrCode::class)
->disableOriginalConstructor()
->setMethods(['setWriter'])
->getMock();
$qrCode->expects($this->once())
->method('setWriter')
$qrCodeBuilder = $this->getMockBuilder(BuilderInterface::class)->getMock();
$qrCodeBuilder->expects($this->once())
->method('writer')
->with($writer)
->willReturnSelf();

$this->getSpaydQr(null, $qrCode)->setWriter($writer);
$this->getSpaydQr(null, $qrCodeBuilder)->setWriter($writer);
}

public function testSetVariableSymbolWorks()
Expand Down Expand Up @@ -97,17 +96,18 @@ public function testGetContentTypeWorks()
{
$expectedContentType = 'Expected content type';

$qrCode = $this->getMockBuilder(QrCode::class)
->disableOriginalConstructor()
->setMethods(['getContentType'])
->getMock();
$qrCode->expects($this->once())
->method('getContentType')
$qrCodeBuilder = $this->getMockBuilder(BuilderInterface::class)->getMock();
$qrCodeResult = $this->getMockBuilder(ResultInterface::class)->getMock();
$qrCodeBuilder->expects($this->once())
->method('build')
->willReturn($qrCodeResult);
$qrCodeResult->expects($this->once())
->method('getMimeType')
->willReturn($expectedContentType);

$this->assertEquals(
$expectedContentType,
$this->getSpaydQr(null, $qrCode)->getContentType()
$this->getSpaydQr(null, $qrCodeBuilder)->getContentType()
);
}

Expand All @@ -125,26 +125,27 @@ public function testGetContentWorks(?int $expectedSize, ?int $expectedMargin)
->method('generate')
->willReturn($expectedSPayD);

$qrCode = $this->getMockBuilder(QrCode::class)
->disableOriginalConstructor()
->setMethods(['setSize', 'setMargin', 'setText', 'writeString'])
->getMock();
$qrCode->expects($this->once())
->method('setSize')
$qrCodeBuilder = $this->getMockBuilder(BuilderInterface::class)->getMock();
$qrCodeResult = $this->getMockBuilder(ResultInterface::class)->getMock();
$qrCodeBuilder->expects($this->once())
->method('size')
->with($expectedSize ?: SpaydQr::QR_SIZE);
$qrCode->expects($this->once())
->method('setMargin')
$qrCodeBuilder->expects($this->once())
->method('margin')
->with($expectedMargin ?: SpaydQr::QR_MARGIN);
$qrCode->expects($this->once())
->method('setText')
$qrCodeBuilder->expects($this->once())
->method('data')
->with($expectedSPayD);
$qrCode->expects($this->once())
->method('writeString')
$qrCodeBuilder->expects($this->once())
->method('build')
->willReturn($qrCodeResult);
$qrCodeResult->expects($this->once())
->method('getString')
->willReturn($expectedContent);

$this->assertEquals(
$expectedContent,
$this->getSpaydQr($spayd, $qrCode)->getContent(...$this->trimArgs([$expectedSize, $expectedMargin]))
$this->getSpaydQr($spayd, $qrCodeBuilder)->getContent(...$this->trimArgs([$expectedSize, $expectedMargin]))
);
}

Expand All @@ -171,26 +172,27 @@ public function testGetDataUriWorks(?int $expectedSize, ?int $expectedMargin)
->method('generate')
->willReturn($expectedSPayD);

$qrCode = $this->getMockBuilder(QrCode::class)
->disableOriginalConstructor()
->setMethods(['setSize', 'setMargin', 'setText', 'writeDataUri'])
->getMock();
$qrCode->expects($this->once())
->method('setSize')
$qrCodeBuilder = $this->getMockBuilder(BuilderInterface::class)->getMock();
$qrCodeResult = $this->getMockBuilder(ResultInterface::class)->getMock();
$qrCodeBuilder->expects($this->once())
->method('size')
->with($expectedSize ?: SpaydQr::QR_SIZE);
$qrCode->expects($this->once())
->method('setMargin')
$qrCodeBuilder->expects($this->once())
->method('margin')
->with($expectedMargin ?: SpaydQr::QR_MARGIN);
$qrCode->expects($this->once())
->method('setText')
$qrCodeBuilder->expects($this->once())
->method('data')
->with($expectedSPayD);
$qrCode->expects($this->once())
->method('writeDataUri')
$qrCodeBuilder->expects($this->once())
->method('build')
->willReturn($qrCodeResult);
$qrCodeResult->expects($this->once())
->method('getDataUri')
->willReturn($expectedDataUri);

$this->assertEquals(
$expectedDataUri,
$this->getSpaydQr($spayd, $qrCode)->getDataUri(...$this->trimArgs([$expectedSize, $expectedMargin]))
$this->getSpaydQr($spayd, $qrCodeBuilder)->getDataUri(...$this->trimArgs([$expectedSize, $expectedMargin]))
);
}

Expand All @@ -213,24 +215,25 @@ public function testWriteFileWorks(?int $expectedSize, ?int $expectedMargin)
->method('generate')
->willReturn($expectedSPayD);

$qrCode = $this->getMockBuilder(QrCode::class)
->disableOriginalConstructor()
->setMethods(['setSize', 'setMargin', 'setText', 'writeFile'])
->getMock();
$qrCode->expects($this->once())
->method('setSize')
$qrCodeBuilder = $this->getMockBuilder(BuilderInterface::class)->getMock();
$qrCodeResult = $this->getMockBuilder(ResultInterface::class)->getMock();
$qrCodeBuilder->expects($this->once())
->method('size')
->with($expectedSize ?: SpaydQr::QR_SIZE);
$qrCode->expects($this->once())
->method('setMargin')
$qrCodeBuilder->expects($this->once())
->method('margin')
->with($expectedMargin ?: SpaydQr::QR_MARGIN);
$qrCode->expects($this->once())
->method('setText')
$qrCodeBuilder->expects($this->once())
->method('data')
->with($expectedSPayD);
$qrCode->expects($this->once())
->method('writeFile')
$qrCodeBuilder->expects($this->once())
->method('build')
->willReturn($qrCodeResult);
$qrCodeResult->expects($this->once())
->method('saveToFile')
->with($expectedPath);

$this->getSpaydQr($spayd, $qrCode)->writeFile(...$this->trimArgs([$expectedPath, $expectedSize, $expectedMargin]));
$this->getSpaydQr($spayd, $qrCodeBuilder)->writeFile(...$this->trimArgs([$expectedPath, $expectedSize, $expectedMargin]));
}

public function dataWriteFileWorks()
Expand All @@ -240,7 +243,7 @@ public function dataWriteFileWorks()

public function testEndToEnd()
{
$spaydQr = $this->getSpaydQr(new Spayd(), new QrCode())
$spaydQr = $this->getSpaydQr(null, null)
->setWriter(new SvgWriter())
->setVariableSymbol(123)
->setInvoice(
Expand All @@ -254,14 +257,14 @@ public function testEndToEnd()
);

$this->assertNotEmpty($spaydQr->getSpayd()->generate());
$this->assertNotEmpty($spaydQr->getQrCode()->getData());
$this->assertNotEmpty($spaydQr->getQrCodeBuilder()->build()->getDataUri());
}

private function getSpaydQr(?Spayd $spayd, ?QrCode $qrCode)
private function getSpaydQr(?Spayd $spayd, ?BuilderInterface $qrCodeBuilder)
{
return new class (
$spayd ?: new Spayd(),
$qrCode ?: new QrCode(),
$qrCodeBuilder ?: Builder::create(),
self::IBAN,
Money::EUR(100)
) extends SpaydQr {
Expand All @@ -275,9 +278,11 @@ public function getSpayd(): Spayd
return $this->spayd;
}

public function getQrCode(): QrCode
public function getQrCodeBuilder(): BuilderInterface
{
return $this->prepareQrCode($this->spayd, null, null);
$this->buildQrCode(null, null);

return $this->qrCodeBuilder;
}
};
}
Expand Down

0 comments on commit 1e613a8

Please sign in to comment.