Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = tab
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true

Expand Down
17 changes: 8 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,17 @@ Only PayBySquare document type is currently supported.

## Requirements

This library uses `xz` system executable (`/usr/bin/xz`) for lzma compression/decompression.
Any suggestions how to remove this dependency are welcome.

This library uses `xz` system executable (`/usr/bin/xz`) for lzma compression/decompression. Path should be set in BySquare constructor.

## Instalation

`composer require peterbodnar.com/bsqr`
`composer require depesr/php-bsqr`


## Define a PayBySquare document

```php
use com\peterbodnar\bsqr;
use bsqr;

$document = (new bsqr\model\Payment())
->setDueDate("0000-00-00") // YYYY-MM-DD
Expand All @@ -34,7 +32,7 @@ According to the specification, document can contain invoice ID, multiple paymen
payments can contain multiple bank accounts, extensions, etc.

```php
use com\peterbodnar\bsqr;
use bsqr;

$document = (new bsqr\model\Pay())
->setInvoiceId("1234567890")
Expand All @@ -59,7 +57,7 @@ $document = (new bsqr\model\Pay())
## Render document to svg including BySqure logo and border

```php
use com\peterbodnar\bsqr;
use bsqr;

$bysquare = new bsqr\BySquare();

Expand All @@ -70,7 +68,7 @@ $svg = (string) $bysquare->render($document);
## Get bsqr data only

```php
use com\peterbodnar\bsqr;
use bsqr;

$bsqrCoder = new bsqr\utils\BsqrCoder();

Expand All @@ -82,7 +80,7 @@ Use any qr-code library to encode/render data to qr matrix/image.
## Parse bsqr data

```php
use com\peterbodnar\bsqr;
use bsqr;

$bsqrCoder = new bsqr\utils\BsqrCoder();

Expand All @@ -92,6 +90,7 @@ $document = $bsqrCoder->parse($bsqrData);

## Links

- https://github.com/prog/php-bsqr
- https://www.sbaonline.sk/projekt/projekty-z-oblasti-platobnych-sluzieb/
- https://bsqr.co/schema/
- http://www.bysquare.com/
18 changes: 7 additions & 11 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
{
"name": "peterbodnar.com/bsqr",
"name": "depesr/php-bsqr",
"description": "By Square document encoding, parsing and rendering utilities",
"keywords": ["bysquare", "paybysquare"],
"license": ["BSD-3-Clause", "GPL-2.0", "GPL-3.0"],
"autoload": {"psr-4": {"com\\peterbodnar\\bsqr\\": "src/"}},
"autoload": {"psr-4": {"bsqr\\": "src/"}},
"require": {
"php": "^5.4 || ^7.0",
"peterbodnar.com/base32": "^1.0",
"peterbodnar.com/cmd": "^1.0",
"peterbodnar.com/mx2svg": "^1.0",
"peterbodnar.com/qrcoder": "^1.0"
"php": ">=8.0",
"ext-imagick": "*",
"bacon/bacon-qr-code": "^v3"
},
"require-dev": {
"nette/tester": "^1.7"
}
}
"version": "1.0"
}
24 changes: 24 additions & 0 deletions example/test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

use bsqr\BySquare;
use bsqr\model\Pay;
use bsqr\model\Payment;

require_once '../vendor/autoload.php';

$document = (new Pay())
->setInvoiceId("1234567890")
->addPayment(
(new Payment())
->setDueDate("2024-09-20")
->setAmount(123.45, "EUR")
->setSymbols("1234567890", null)
->addBankAccount("SK3112000000198742637543", "XXXXXXXXXXX")
->setNote("Add note")
);
$lzmaPath = BySquare::LZMA_PATH_HOMEBREW;
$bysquare = new BySquare($lzmaPath);

$svg = (string)$bysquare->render($document);

echo $svg;
94 changes: 94 additions & 0 deletions src/Base32.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

namespace bsqr;



/**
* Base 32 encoder / decoder
*/
class Base32 {


const CHARS_RFC4648 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";


/** @var string */
protected $alphabet;


/**
* @param string $alphabet ~ Alphabet.
*/
public function __construct($alphabet = self::CHARS_RFC4648) {
$this->alphabet = $alphabet;
}


/**
* @param string $alphabet ~ Alphabet.
*/
public function setAlphabet($alphabet) {
$this->alphabet = $alphabet;
}


/**
* Encode data.
*
* @param string $data ~ Data to encode.
* @return string
*/
public function encode($data) {
$hexData = bin2hex($data);
$hexLen = strlen($hexData);
$binData = "";
for ($i=0; $i<$hexLen; $i++) {
$binData .= str_pad(base_convert($hexData[$i], 16, 2), 4, "0", STR_PAD_LEFT);
}
$binLen = strlen($binData);
$rem = $binLen % 5;
if ($rem > 0) {
$pad = 5 - $rem;
$binData .= str_repeat("0", $pad);
$binLen += $pad;
}
$reslen = $binLen / 5;
$result = str_repeat("_", $reslen);
for ($i=0; $i<$reslen; $i += 1) {
$result[$i] = $this->alphabet[bindec(substr($binData, $i * 5, 5))];
}
return $result;
}


/**
* @param string $data
* @return string
* @throws Base32Exception
*/
public function decode($data) {
$dataLen = strlen($data);
$binData = "";
for ($i=0; $i<$dataLen; $i++) {
$ord = strpos($this->alphabet, $data[$i]);
if (FALSE === $ord) {
$charCode = "0x" . bin2hex($data[$i]);
throw new Base32Exception("Invalid input char ({$charCode}) at index {$i}");
}
$binData .= str_pad(decbin($ord), 5, "0", STR_PAD_LEFT);
}
$binLen = strlen($binData);
$hexLen = floor($binLen / 8) * 2;
$hexData = str_repeat("_", $hexLen);
for ($i=0; $i<$hexLen; $i++) {
$hexData[$i] = base_convert(substr($binData, $i * 4, 4), 2, 16);
}
return hex2bin($hexData);
}

}



class Base32Exception extends \Exception { }
26 changes: 13 additions & 13 deletions src/BySquare.php
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
<?php

namespace com\peterbodnar\bsqr;

use com\peterbodnar\bsqr\model;
use com\peterbodnar\bsqr\utils\BsqrCoder;
use com\peterbodnar\bsqr\utils\BsqrCoderException;
use com\peterbodnar\bsqr\utils\BsqrRenderer;
use com\peterbodnar\mx2svg\MxToSvg;
use com\peterbodnar\qrcoder\QrCoder;
use com\peterbodnar\qrcoder\QrCoderException;
use com\peterbodnar\svg\Svg;
namespace bsqr;

use bsqr\mx2svg\MxToSvg;
use bsqr\qrcoder\QrCoder;
use bsqr\qrcoder\QrCoderException;
use bsqr\svg\Svg;
use bsqr\utils\BsqrCoder;
use bsqr\utils\BsqrCoderException;
use bsqr\utils\BsqrRenderer;


/**
* Bysquare facade to encode and render bysqr document
*/
class BySquare {

const LZMA_PATH = '/usr/bin/xz';
const LZMA_PATH_HOMEBREW = '/opt/homebrew/bin/xz';

const LOGO_BOTTOM = BsqrRenderer::LOGO_BOTTOM;
const LOGO_RIGHT = BsqrRenderer::LOGO_RIGHT;
Expand All @@ -35,8 +34,8 @@ class BySquare {
protected $bsqrRenderer;


public function __construct() {
$this->bsqrCoder = new BsqrCoder();
public function __construct(string $lzmaPath = self::LZMA_PATH) {
$this->bsqrCoder = new BsqrCoder($lzmaPath);
$this->qrCoder = new QrCoder();
$this->mx2svg = new MxToSvg();
$this->bsqrRenderer = new BsqrRenderer();
Expand Down Expand Up @@ -70,6 +69,7 @@ public function render(model\Document $document) {
} catch (QrCoderException $ex) {
throw new BySquareException("Error while encoding data to qr-code matrix: " . $ex->getMessage(), 0, $ex);
}
$this->bsqrRenderer->setQrMatrixSize($qrMatrix->getRows(), $qrMatrix->getColumns());
$this->bsqrRenderer->setQrCodeSvg($qrSvg);
$this->bsqrRenderer->setQuiteAreaRatio(4 / $qrMatrix->getRows());
if ($document instanceof model\Pay) {
Expand Down
92 changes: 92 additions & 0 deletions src/Command.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace bsqr;



/**
* External command wrapper
*/
class Command {


/** @var string ~ Path to executable. */
protected $command;


/**
* @param string $command ~ Path to executable.
*/
public function __construct($command) {
$this->command = $command;
}


/**
* Execute command.
*
* @param string[] $arguments ~ Command line arguments.
* @param string|null $inputData ~ Input data.
* @return CommandResult
* @throws CommandException
*/
public function execute(array $arguments = [], $inputData = null) {
$cmd = escapeshellcmd($this->command);
foreach ($arguments as $name => $arg) {
if (is_string($name)) {
$arg = $name . "=" . $arg;
}
$cmd .= " " . escapeshellarg($arg);
}

$process = proc_open($cmd, [
0 => ["pipe", "r"],
1 => ["pipe", "w"],
2 => ["pipe", "w"],
], $pipes);
if (!is_resource($process)) {
throw new CommandException("Can not open process \"" . $cmd . "\"");
}

if (null !== $inputData) {
fwrite($pipes[0], $inputData);
}
fclose($pipes[0]);
$stdOut = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$stdErr = stream_get_contents($pipes[2]);
fclose($pipes[2]);
$exitCode = proc_close($process);

$result = new CommandResult();
$result->stdOut = $stdOut;
$result->stdErr = $stdErr;
$result->exitCode = $exitCode;
return $result;
}

}



/**
* Command Execution Result
*/
class CommandResult {


/** @var string */
public $stdOut;
/** @var string */
public $stdErr;
/** @var int */
public $exitCode;

}



/**
* Command Exception
*/
class CommandException extends \Exception { }
2 changes: 1 addition & 1 deletion src/Exception.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace com\peterbodnar\bsqr;
namespace bsqr;



Expand Down
2 changes: 1 addition & 1 deletion src/model/BankAccount.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace com\peterbodnar\bsqr\model;
namespace bsqr\model;



Expand Down
2 changes: 1 addition & 1 deletion src/model/DirectDebitExt.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace com\peterbodnar\bsqr\model;
namespace bsqr\model;



Expand Down
2 changes: 1 addition & 1 deletion src/model/Document.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace com\peterbodnar\bsqr\model;
namespace bsqr\model;



Expand Down
Loading