mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-21 00:52:33 -04:00
port totp mfa from streams with some adjustions
This commit is contained in:
72
Zotlabs/Module/Settings/Multifactor.php
Normal file
72
Zotlabs/Module/Settings/Multifactor.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module\Settings;
|
||||
|
||||
use App;
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use Zotlabs\Lib\AConfig;
|
||||
use Zotlabs\Lib\System;
|
||||
use OTPHP\TOTP;
|
||||
use ParagonIE\ConstantTime\Base32;
|
||||
|
||||
|
||||
class Multifactor {
|
||||
public function post() {
|
||||
$account = App::get_account();
|
||||
if (!$account) {
|
||||
return;
|
||||
}
|
||||
$enable_mfa = isset($_POST['enable_mfa']) ? (int) $_POST['enable_mfa'] : false;
|
||||
AConfig::Set($account['account_id'], 'system', 'mfa_enabled', $enable_mfa);
|
||||
}
|
||||
|
||||
public function get() {
|
||||
$account = App::get_account();
|
||||
if (!$account) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if (!$account['account_external']) {
|
||||
$otp = TOTP::create();
|
||||
$otp->setLabel($account['account_email']);
|
||||
// $otp->setLabel(rawurlencode(System::get_platform_name()));
|
||||
$otp->setIssuer(rawurlencode(System::get_platform_name()));
|
||||
|
||||
$mySecret = trim(Base32::encodeUpper(random_bytes(32)), '=');
|
||||
$otp = TOTP::create($mySecret);
|
||||
q("UPDATE account set account_external = '%s' where account_id = %d",
|
||||
dbesc($otp->getSecret()),
|
||||
intval($account['account_id'])
|
||||
);
|
||||
$account['account_external'] = $otp->getSecret();
|
||||
}
|
||||
|
||||
$otp = TOTP::create($account['account_external']);
|
||||
$otp->setLabel($account['account_email']);
|
||||
$otp->setIssuer(rawurlencode(System::get_platform_name()));
|
||||
$uri = $otp->getProvisioningUri();
|
||||
return replace_macros(get_markup_template('totp_setup.tpl'),
|
||||
[
|
||||
'$form_security_token' => get_form_security_token("settings_mfa"),
|
||||
'$title' => t('Multifactor Settings'),
|
||||
'$totp_setup_text' => t('Multi-Factor Authentication Setup'),
|
||||
'$secret_text' => t('This is your generated secret. This may be used in some cases if the QR image cannot be read. Please save it.'),
|
||||
'$test_title' => t('Please enter the code from your authenticator'),
|
||||
'$qrcode' => (new QRCode())->render($uri),
|
||||
'$uri' => $uri,
|
||||
'$secret' => ($account['account_external'] ?? ''),
|
||||
'$test_pass' => t("That code is correct."),
|
||||
'$test_fail' => t("Incorrect code."),
|
||||
'$enable_mfa' => [
|
||||
'enable_mfa',
|
||||
t('Enable Multi-factor Authentication'),
|
||||
AConfig::Get($account['account_id'], 'system', 'mfa_enabled'),
|
||||
'',
|
||||
[t('No'), t('Yes')]
|
||||
],
|
||||
'$submit' => t('Submit'),
|
||||
'$test' => t('Test')
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
90
Zotlabs/Module/Totp_check.php
Normal file
90
Zotlabs/Module/Totp_check.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Zotlabs\Module;
|
||||
|
||||
use App;
|
||||
use Zotlabs\Web\Controller;
|
||||
use OTPHP\TOTP;
|
||||
|
||||
class Totp_check extends Controller {
|
||||
|
||||
public function post() {
|
||||
$retval = ['status' => false];
|
||||
$static = $_POST['totp_code_static'] ?? false;
|
||||
|
||||
if (!local_channel()) {
|
||||
if ($static) {
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
json_return_and_die($retval);
|
||||
}
|
||||
|
||||
$account = App::get_account();
|
||||
if (!$account) {
|
||||
json_return_and_die($retval);
|
||||
}
|
||||
|
||||
$secret = $account['account_external'];
|
||||
$input = (isset($_POST['totp_code'])) ? trim($_POST['totp_code']) : '';
|
||||
|
||||
if ($secret && $input) {
|
||||
$otp = TOTP::create($secret); // create TOTP object from the secret.
|
||||
if ($otp->verify($_POST['totp_code']) || $input === $secret ) {
|
||||
logger('otp_success');
|
||||
$_SESSION['2FA_VERIFIED'] = true;
|
||||
|
||||
if ($static) {
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
$retval['status'] = true;
|
||||
json_return_and_die($retval);
|
||||
}
|
||||
logger('otp_fail');
|
||||
}
|
||||
|
||||
if ($static) {
|
||||
if(empty($_SESSION['totp_try_count'])) {
|
||||
$_SESSION['totp_try_count'] = 1;
|
||||
}
|
||||
|
||||
if ($_SESSION['totp_try_count'] > 2) {
|
||||
goaway('logout');
|
||||
}
|
||||
|
||||
$_SESSION['totp_try_count']++;
|
||||
goaway(z_root());
|
||||
}
|
||||
|
||||
json_return_and_die($retval);
|
||||
}
|
||||
|
||||
public function get() {
|
||||
|
||||
if (!local_channel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$account = App::get_account();
|
||||
if (!$account) {
|
||||
return t('Account not found.');
|
||||
}
|
||||
|
||||
$id = $account['account_email'];
|
||||
|
||||
return replace_macros(get_markup_template('totp.tpl'),
|
||||
[
|
||||
'$header' => t('Multifactor Verification'),
|
||||
'$id' => $id,
|
||||
'$desc' => t('Please enter the verification key from your authenticator app'),
|
||||
//'$success' => t('Success!'),
|
||||
//'$fail' => t('Invalid code, please try again.'),
|
||||
//'$maxfails' => t('Too many invalid codes...'),
|
||||
'$submit' => t('Verify'),
|
||||
'$static' => $static
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +45,9 @@
|
||||
"blueimp/jquery-file-upload": "^10.3",
|
||||
"desandro/imagesloaded": "^4.1",
|
||||
"phpseclib/phpseclib": "~2.0",
|
||||
"jbroadway/urlify": "^1.2"
|
||||
"jbroadway/urlify": "^1.2",
|
||||
"chillerlan/php-qrcode": "^4.3",
|
||||
"spomky-labs/otphp": "^11.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.4",
|
||||
|
||||
291
composer.lock
generated
291
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "9bcd9511f1fd87b42eb4381dae723dfb",
|
||||
"content-hash": "12bbabd1d50360fa40c1bcd8d8458c2d",
|
||||
"packages": [
|
||||
{
|
||||
"name": "blueimp/jquery-file-upload",
|
||||
@@ -194,6 +194,148 @@
|
||||
},
|
||||
"time": "2022-05-31T16:12:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
"version": "4.3.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/chillerlan/php-qrcode.git",
|
||||
"reference": "2ca4bf5ae048af1981d1023ee42a0a2a9d51e51d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/2ca4bf5ae048af1981d1023ee42a0a2a9d51e51d",
|
||||
"reference": "2ca4bf5ae048af1981d1023ee42a0a2a9d51e51d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"chillerlan/php-settings-container": "^2.1.4",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phan/phan": "^5.3",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"setasign/fpdf": "^1.8.2"
|
||||
},
|
||||
"suggest": {
|
||||
"chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.",
|
||||
"setasign/fpdf": "Required to use the QR FPDF output."
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"chillerlan\\QRCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kazuhiko Arase",
|
||||
"homepage": "https://github.com/kazuhikoarase"
|
||||
},
|
||||
{
|
||||
"name": "Smiley",
|
||||
"email": "smiley@chillerlan.net",
|
||||
"homepage": "https://github.com/codemasher"
|
||||
},
|
||||
{
|
||||
"name": "Contributors",
|
||||
"homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A QR code generator. PHP 7.4+",
|
||||
"homepage": "https://github.com/chillerlan/php-qrcode",
|
||||
"keywords": [
|
||||
"phpqrcode",
|
||||
"qr",
|
||||
"qr code",
|
||||
"qrcode",
|
||||
"qrcode-generator"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/chillerlan/php-qrcode/issues",
|
||||
"source": "https://github.com/chillerlan/php-qrcode/tree/4.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://ko-fi.com/codemasher",
|
||||
"type": "ko_fi"
|
||||
}
|
||||
],
|
||||
"time": "2022-07-25T09:12:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-settings-container",
|
||||
"version": "2.1.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/chillerlan/php-settings-container.git",
|
||||
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
|
||||
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phan/phan": "^5.3",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"chillerlan\\Settings\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Smiley",
|
||||
"email": "smiley@chillerlan.net",
|
||||
"homepage": "https://github.com/codemasher"
|
||||
}
|
||||
],
|
||||
"description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+",
|
||||
"homepage": "https://github.com/chillerlan/php-settings-container",
|
||||
"keywords": [
|
||||
"PHP7",
|
||||
"Settings",
|
||||
"configuration",
|
||||
"container",
|
||||
"helper"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/chillerlan/php-settings-container/issues",
|
||||
"source": "https://github.com/chillerlan/php-settings-container"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://ko-fi.com/codemasher",
|
||||
"type": "ko_fi"
|
||||
}
|
||||
],
|
||||
"time": "2022-07-05T22:32:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "commerceguys/intl",
|
||||
"version": "v1.1.1",
|
||||
@@ -602,6 +744,73 @@
|
||||
},
|
||||
"time": "2022-09-26T12:21:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v2.6.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||
"reference": "58c3f47f650c94ec05a151692652a868995d2938"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938",
|
||||
"reference": "58c3f47f650c94ec05a151692652a868995d2938",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6|^7|^8|^9",
|
||||
"vimeo/psalm": "^1|^2|^3|^4"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ParagonIE\\ConstantTime\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com",
|
||||
"role": "Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "Steve 'Sc00bz' Thomas",
|
||||
"email": "steve@tobtu.com",
|
||||
"homepage": "https://www.tobtu.com",
|
||||
"role": "Original Developer"
|
||||
}
|
||||
],
|
||||
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
|
||||
"keywords": [
|
||||
"base16",
|
||||
"base32",
|
||||
"base32_decode",
|
||||
"base32_encode",
|
||||
"base64",
|
||||
"base64_decode",
|
||||
"base64_encode",
|
||||
"bin2hex",
|
||||
"encoding",
|
||||
"hex",
|
||||
"hex2bin",
|
||||
"rfc4648"
|
||||
],
|
||||
"support": {
|
||||
"email": "info@paragonie.com",
|
||||
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
|
||||
"source": "https://github.com/paragonie/constant_time_encoding"
|
||||
},
|
||||
"time": "2022-06-14T06:56:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pear/text_languagedetect",
|
||||
"version": "v1.0.1",
|
||||
@@ -1579,6 +1788,86 @@
|
||||
},
|
||||
"time": "2022-11-22T21:47:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spomky-labs/otphp",
|
||||
"version": "11.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Spomky-Labs/otphp.git",
|
||||
"reference": "4849ac1aa560bfc56c0d1534b0d72532da4665ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/4849ac1aa560bfc56c0d1534b0d72532da4665ab",
|
||||
"reference": "4849ac1aa560bfc56c0d1534b0d72532da4665ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"paragonie/constant_time_encoding": "^2.0",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"ekino/phpstan-banned-code": "^1.0",
|
||||
"infection/infection": "^0.26",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3",
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5.26",
|
||||
"qossmic/deptrac-shim": "^1.0",
|
||||
"rector/rector": "^0.14",
|
||||
"symfony/phpunit-bridge": "^6.1",
|
||||
"symplify/easy-coding-standard": "^11.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OTPHP\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Florent Morselli",
|
||||
"homepage": "https://github.com/Spomky"
|
||||
},
|
||||
{
|
||||
"name": "All contributors",
|
||||
"homepage": "https://github.com/Spomky-Labs/otphp/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
|
||||
"homepage": "https://github.com/Spomky-Labs/otphp",
|
||||
"keywords": [
|
||||
"FreeOTP",
|
||||
"RFC 4226",
|
||||
"RFC 6238",
|
||||
"google authenticator",
|
||||
"hotp",
|
||||
"otp",
|
||||
"totp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Spomky-Labs/otphp/issues",
|
||||
"source": "https://github.com/Spomky-Labs/otphp/tree/11.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/Spomky",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/FlorentMorselli",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"time": "2022-11-11T12:57:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.26.0",
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
*/
|
||||
|
||||
use Zotlabs\Lib\Libzot;
|
||||
use Zotlabs\Lib\AConfig;
|
||||
|
||||
require_once('include/api_auth.php');
|
||||
require_once('include/security.php');
|
||||
@@ -263,8 +264,16 @@ if((isset($_SESSION)) && (x($_SESSION, 'authenticated')) &&
|
||||
App::$session->extend_cookie();
|
||||
$login_refresh = true;
|
||||
}
|
||||
|
||||
$multiFactor = AConfig::Get(App::$account['account_id'], 'system', 'mfa_enabled');
|
||||
if ($multiFactor && empty($_SESSION['2FA_VERIFIED']) && App::$module !== 'totp_check') {
|
||||
$o = new Zotlabs\Module\Totp_check;
|
||||
echo $o->get(true);
|
||||
killme();
|
||||
}
|
||||
|
||||
$ch = (($_SESSION['uid']) ? channelx_by_n($_SESSION['uid']) : null);
|
||||
authenticate_success($r[0], null, $ch, false, false, $login_refresh);
|
||||
authenticate_success($r[0], $ch, false, false, $login_refresh);
|
||||
}
|
||||
else {
|
||||
$_SESSION['account_id'] = 0;
|
||||
|
||||
2
vendor/chillerlan/php-qrcode/.github/FUNDING.yml
vendored
Normal file
2
vendor/chillerlan/php-qrcode/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
ko_fi: codemasher
|
||||
custom: "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4"
|
||||
82
vendor/chillerlan/php-qrcode/.github/workflows/tests.yml
vendored
Normal file
82
vendor/chillerlan/php-qrcode/.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
|
||||
# https://github.com/sebastianbergmann/phpunit/blob/master/.github/workflows/ci.yml
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- v4.3.x
|
||||
pull_request:
|
||||
branches:
|
||||
- v4.3.x
|
||||
|
||||
name: "Continuous Integration"
|
||||
|
||||
jobs:
|
||||
|
||||
static-code-analysis:
|
||||
name: "Static Code Analysis"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
PHAN_ALLOW_XDEBUG: 0
|
||||
PHAN_DISABLE_XDEBUG_WARN: 1
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "7.4"
|
||||
coverage: none
|
||||
tools: pecl
|
||||
extensions: ast, gd, imagick, json, mbstring
|
||||
|
||||
- name: "Update dependencies with composer"
|
||||
run: composer update --no-interaction --no-ansi --no-progress --no-suggest
|
||||
|
||||
- name: "Run phan"
|
||||
run: php vendor/bin/phan
|
||||
|
||||
tests:
|
||||
name: "Unit Tests"
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
php-version:
|
||||
- "7.4"
|
||||
- "8.0"
|
||||
- "8.1"
|
||||
|
||||
steps:
|
||||
# - name: "Configure git to avoid issues with line endings"
|
||||
# if: matrix.os == 'windows-latest'
|
||||
# run: git config --global core.autocrlf false
|
||||
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: "Install PHP with extensions"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
coverage: pcov
|
||||
tools: pecl
|
||||
extensions: gd, imagick, json, mbstring
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: composer update --no-ansi --no-interaction --no-progress --no-suggest
|
||||
|
||||
- name: "Run tests with phpunit"
|
||||
run: php vendor/bin/phpunit --configuration=phpunit.xml
|
||||
|
||||
- name: "Send code coverage report to Codecov.io"
|
||||
uses: codecov/codecov-action@v3
|
||||
5
vendor/chillerlan/php-qrcode/.gitignore
vendored
Normal file
5
vendor/chillerlan/php-qrcode/.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.build/*
|
||||
.idea/*
|
||||
docs/*
|
||||
vendor/*
|
||||
composer.lock
|
||||
55
vendor/chillerlan/php-qrcode/.phan/config.php
vendored
Normal file
55
vendor/chillerlan/php-qrcode/.phan/config.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* This configuration will be read and overlaid on top of the
|
||||
* default configuration. Command-line arguments will be applied
|
||||
* after this file is read.
|
||||
*/
|
||||
return [
|
||||
// Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`,
|
||||
// `'7.4'`, `null`.
|
||||
// If this is set to `null`,
|
||||
// then Phan assumes the PHP version which is closest to the minor version
|
||||
// of the php executable used to execute Phan.
|
||||
//
|
||||
// Note that the **only** effect of choosing `'5.6'` is to infer
|
||||
// that functions removed in php 7.0 exist.
|
||||
// (See `backward_compatibility_checks` for additional options)
|
||||
'target_php_version' => '7.4',
|
||||
|
||||
// A list of directories that should be parsed for class and
|
||||
// method information. After excluding the directories
|
||||
// defined in exclude_analysis_directory_list, the remaining
|
||||
// files will be statically analyzed for errors.
|
||||
//
|
||||
// Thus, both first-party and third-party code being used by
|
||||
// your application should be included in this list.
|
||||
'directory_list' => [
|
||||
'examples',
|
||||
'src',
|
||||
'tests',
|
||||
'vendor',
|
||||
'.phan/stubs'
|
||||
],
|
||||
|
||||
// A regex used to match every file name that you want to
|
||||
// exclude from parsing. Actual value will exclude every
|
||||
// "test", "tests", "Test" and "Tests" folders found in
|
||||
// "vendor/" directory.
|
||||
'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@',
|
||||
|
||||
// A directory list that defines files that will be excluded
|
||||
// from static analysis, but whose class and method
|
||||
// information should be included.
|
||||
//
|
||||
// Generally, you'll want to include the directories for
|
||||
// third-party code (such as "vendor/") in this list.
|
||||
//
|
||||
// n.b.: If you'd like to parse but not analyze 3rd
|
||||
// party code, directories containing that code
|
||||
// should be added to both the `directory_list`
|
||||
// and `exclude_analysis_directory_list` arrays.
|
||||
'exclude_analysis_directory_list' => [
|
||||
'vendor/',
|
||||
'.phan/stubs'
|
||||
],
|
||||
];
|
||||
6744
vendor/chillerlan/php-qrcode/.phan/stubs/imagick.php
vendored
Normal file
6744
vendor/chillerlan/php-qrcode/.phan/stubs/imagick.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
16
vendor/chillerlan/php-qrcode/.scrutinizer.yml
vendored
Normal file
16
vendor/chillerlan/php-qrcode/.scrutinizer.yml
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
build:
|
||||
nodes:
|
||||
analysis:
|
||||
tests:
|
||||
override:
|
||||
- php-scrutinizer-run
|
||||
environment:
|
||||
php: 8.0.0
|
||||
|
||||
filter:
|
||||
excluded_paths:
|
||||
- examples/*
|
||||
- tests/*
|
||||
- vendor/*
|
||||
- .github/*
|
||||
- .phan/*
|
||||
21
vendor/chillerlan/php-qrcode/LICENSE
vendored
Normal file
21
vendor/chillerlan/php-qrcode/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Smiley <smiley@chillerlan.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
422
vendor/chillerlan/php-qrcode/README.md
vendored
Normal file
422
vendor/chillerlan/php-qrcode/README.md
vendored
Normal file
@@ -0,0 +1,422 @@
|
||||
# chillerlan/php-qrcode
|
||||
|
||||
A PHP 7.4+ QR Code library based on the [implementation](https://github.com/kazuhikoarase/qrcode-generator) by [Kazuhiko Arase](https://github.com/kazuhikoarase),
|
||||
namespaced, cleaned up, improved and other stuff.
|
||||
|
||||
**Attention:** there is now also a javascript port: [chillerlan/js-qrcode](https://github.com/chillerlan/js-qrcode).
|
||||
|
||||
[![PHP Version Support][php-badge]][php]
|
||||
[![Packagist version][packagist-badge]][packagist]
|
||||
[![License][license-badge]][license]
|
||||
[![CodeCov][coverage-badge]][coverage]
|
||||
[![Scrunitizer CI][scrutinizer-badge]][scrutinizer]
|
||||
[![Packagist downloads][downloads-badge]][downloads]<br/>
|
||||
[![Continuous Integration][gh-action-badge]][gh-action]
|
||||
|
||||
[php-badge]: https://img.shields.io/packagist/php-v/chillerlan/php-qrcode?logo=php&color=8892BF
|
||||
[php]: https://www.php.net/supported-versions.php
|
||||
[packagist-badge]: https://img.shields.io/packagist/v/chillerlan/php-qrcode.svg?logo=packagist
|
||||
[packagist]: https://packagist.org/packages/chillerlan/php-qrcode
|
||||
[license-badge]: https://img.shields.io/github/license/chillerlan/php-qrcode.svg
|
||||
[license]: https://github.com/chillerlan/php-qrcode/blob/main/LICENSE
|
||||
[coverage-badge]: https://img.shields.io/codecov/c/github/chillerlan/php-qrcode.svg?logo=codecov
|
||||
[coverage]: https://codecov.io/github/chillerlan/php-qrcode
|
||||
[scrutinizer-badge]: https://img.shields.io/scrutinizer/g/chillerlan/php-qrcode.svg?logo=scrutinizer
|
||||
[scrutinizer]: https://scrutinizer-ci.com/g/chillerlan/php-qrcode
|
||||
[downloads-badge]: https://img.shields.io/packagist/dt/chillerlan/php-qrcode.svg?logo=packagist
|
||||
[downloads]: https://packagist.org/packages/chillerlan/php-qrcode/stats
|
||||
[gh-action-badge]: https://github.com/chillerlan/php-qrcode/workflows/Continuous%20Integration/badge.svg
|
||||
[gh-action]: https://github.com/chillerlan/php-qrcode/actions?query=workflow%3A%22Continuous+Integration%22+branch%3Av4.3.x
|
||||
|
||||
# Documentation
|
||||
|
||||
## Requirements
|
||||
- PHP 7.4+
|
||||
- `ext-mbstring`
|
||||
- optional:
|
||||
- `ext-json`, `ext-gd`
|
||||
- `ext-imagick` with [ImageMagick](https://imagemagick.org) installed
|
||||
- [`setasign/fpdf`](https://github.com/setasign/fpdf) for the PDF output module
|
||||
|
||||
## Installation
|
||||
**requires [composer](https://getcomposer.org)**
|
||||
|
||||
via terminal: `composer require chillerlan/php-qrcode`
|
||||
|
||||
*composer.json*
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"chillerlan/php-qrcode": "v4.3.x-dev"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: replace `v4.3.x-dev` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^4.3` - see [releases](https://github.com/chillerlan/php-qrcode/releases) for valid versions.
|
||||
For PHP version ...
|
||||
- 7.4+ use `^4.3`
|
||||
- 7.2+ use `^3.4.1` (v3.4.1 also supports PHP8)
|
||||
- 7.0+ use `^2.0`
|
||||
- 5.6+ use `^1.0` (please let PHP 5 die!)
|
||||
|
||||
In case you want to keep using `v4.3.x-dev`, specify the hash of a commit to avoid running into unforseen issues like so: `v4.3.x-dev#c115f7bc51d466ccb24c544e88329804aad8c2a0`
|
||||
|
||||
PSA: [PHP 7.0 - 7.3 are EOL](https://www.php.net/supported-versions.php) and therefore the respective `QRCode` versions are also no longer supported!
|
||||
|
||||
## Quickstart
|
||||
We want to encode this URI for a mobile authenticator into a QRcode image:
|
||||
```php
|
||||
$data = 'otpauth://totp/test?secret=B3JX4VCVJDVNXNZ5&issuer=chillerlan.net';
|
||||
|
||||
// quick and simple:
|
||||
echo '<img src="'.(new QRCode)->render($data).'" alt="QR Code" />';
|
||||
```
|
||||
|
||||
<p align="center">
|
||||
<img alt="QR codes are awesome!" src="https://raw.githubusercontent.com/chillerlan/php-qrcode/v4.3.x/examples/example_image.png">
|
||||
<img alt="QR codes are awesome!" src="https://raw.githubusercontent.com/chillerlan/php-qrcode/v4.3.x/examples/example_svg.png">
|
||||
</p>
|
||||
|
||||
Wait, what was that? Please again, slower!
|
||||
|
||||
|
||||
## Advanced usage
|
||||
|
||||
Ok, step by step. First you'll need a `QRCode` instance, which can be optionally invoked with a `QROptions` (or a [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/master/src/SettingsContainerInterface.php), respectively) object as the only parameter.
|
||||
|
||||
```php
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'outputType' => QRCode::OUTPUT_MARKUP_SVG,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
]);
|
||||
|
||||
// invoke a fresh QRCode instance
|
||||
$qrcode = new QRCode($options);
|
||||
|
||||
// and dump the output
|
||||
$qrcode->render($data);
|
||||
|
||||
// ...with additional cache file
|
||||
$qrcode->render($data, '/path/to/file.svg');
|
||||
```
|
||||
|
||||
In case you just want the raw QR code matrix, call `QRCode::getMatrix()` - this method is also called internally from `QRCode::render()`. See also [[Custom output interface]].
|
||||
|
||||
```php
|
||||
$matrix = $qrcode->getMatrix($data);
|
||||
|
||||
foreach($matrix->matrix() as $y => $row){
|
||||
foreach($row as $x => $module){
|
||||
|
||||
// get a module's value
|
||||
$value = $module;
|
||||
|
||||
// or via the matrix's getter method
|
||||
$value = $matrix->get($x, $y);
|
||||
|
||||
// boolean check a module
|
||||
if($matrix->check($x, $y)){ // if($module >> 8 > 0)
|
||||
// do stuff, the module is dark
|
||||
}
|
||||
else{
|
||||
// do other stuff, the module is light
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Have a look [in the examples folder](https://github.com/chillerlan/php-qrcode/tree/main/examples) for some more usage examples.
|
||||
|
||||
### Notes
|
||||
The QR encoder, especially the subroutines for mask pattern testing, can cause high CPU load on increased matrix size.
|
||||
You can avoid a part of this load by choosing a fast output module, like `OUTPUT_IMAGE_*` and maybe setting the mask pattern manually (which may result in unreadable QR Codes).
|
||||
Oh hey and don't forget to sanitize any user input!
|
||||
|
||||
|
||||
## Custom output interface
|
||||
|
||||
Instead of bloating your code you can simply create your own output interface by creating a `QROutputInterface` (i.e. extending `QROutputAbstract`).
|
||||
|
||||
```php
|
||||
class MyCustomOutput extends QROutputAbstract{
|
||||
|
||||
// inherited from QROutputAbstract
|
||||
protected QRMatrix $matrix; // QRMatrix
|
||||
protected int $moduleCount; // modules QRMatrix::size()
|
||||
protected QROptions $options; // MyCustomOptions or QROptions
|
||||
protected int $scale; // scale factor from options
|
||||
protected int $length; // length of the matrix ($moduleCount * $scale)
|
||||
|
||||
// ...check/set default module values (abstract method, called by the constructor)
|
||||
protected function setModuleValues():void{
|
||||
// $this->moduleValues = ...
|
||||
}
|
||||
|
||||
// QROutputInterface::dump()
|
||||
public function dump(string $file = null):string{
|
||||
$output = '';
|
||||
|
||||
for($row = 0; $row < $this->moduleCount; $row++){
|
||||
for($col = 0; $col < $this->moduleCount; $col++){
|
||||
$output .= (int)$this->matrix->check($col, $row);
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
For more examples, have a look at the [built-in output modules](https://github.com/chillerlan/php-qrcode/tree/main/src/Output).
|
||||
|
||||
In case you need additional settings for your output module, just extend `QROptions`...
|
||||
```
|
||||
class MyCustomOptions extends QROptions{
|
||||
protected string $myParam = 'defaultValue';
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
...or use the [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerInterface.php), which is the more flexible approach.
|
||||
|
||||
```php
|
||||
trait MyCustomOptionsTrait{
|
||||
protected string $myParam = 'defaultValue';
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
set the options:
|
||||
```php
|
||||
$myOptions = [
|
||||
'version' => 5,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
'outputType' => QRCode::OUTPUT_CUSTOM,
|
||||
'outputInterface' => MyCustomOutput::class,
|
||||
// your custom settings
|
||||
'myParam' => 'whatever value',
|
||||
];
|
||||
|
||||
// extends QROptions
|
||||
$myCustomOptions = new MyCustomOptions($myOptions);
|
||||
|
||||
// using the SettingsContainerInterface
|
||||
$myCustomOptions = new class($myOptions) extends SettingsContainerAbstract{
|
||||
use QROptionsTrait, MyCustomOptionsTrait;
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
You can then call `QRCode` with the custom modules...
|
||||
```php
|
||||
(new QRCode($myCustomOptions))->render($data);
|
||||
```
|
||||
...or invoke the `QROutputInterface` manually.
|
||||
```php
|
||||
$qrOutputInterface = new MyCustomOutput($myCustomOptions, (new QRCode($myCustomOptions))->getMatrix($data));
|
||||
|
||||
//dump the output, which is equivalent to QRCode::render()
|
||||
$qrOutputInterface->dump();
|
||||
```
|
||||
|
||||
### Custom module values
|
||||
|
||||
You can distinguish between different parts of the matrix, namely the several required patterns from the QR Code specification, and use them in different ways, i.e. to assign different colors for each part of the matrix (see the [image example](https://github.com/chillerlan/php-qrcode/blob/main/examples/image.php)).
|
||||
The dark value is the module value (light) shifted by 8 bits to the left: `$value = $M_TYPE << ($bool ? 8 : 0);`, where `$M_TYPE` is one of the `QRMatrix::M_*` constants.
|
||||
You can check the value for a type explicitly like...
|
||||
```php
|
||||
// for true (dark)
|
||||
($value >> 8) === $M_TYPE;
|
||||
|
||||
// for false (light)
|
||||
$value === $M_TYPE;
|
||||
```
|
||||
...or you can perform a loose check, ignoring the module value
|
||||
```php
|
||||
// for true
|
||||
($value >> 8) > 0;
|
||||
|
||||
// for false
|
||||
($value >> 8) === 0;
|
||||
```
|
||||
|
||||
See also `QRMatrix::set()`, `QRMatrix::check()` and [`QRMatrix` constants](#qrmatrix-constants).
|
||||
|
||||
To map the values and properly render the modules for the given `QROutputInterface`, it's necessary to overwrite the default values:
|
||||
```php
|
||||
$options = new QROptions;
|
||||
|
||||
// for HTML, SVG and ImageMagick
|
||||
$options->moduleValues = [
|
||||
// finder
|
||||
1536 => '#A71111', // dark (true)
|
||||
6 => '#FFBFBF', // light (false)
|
||||
// alignment
|
||||
2560 => '#A70364',
|
||||
10 => '#FFC9C9',
|
||||
// timing
|
||||
3072 => '#98005D',
|
||||
12 => '#FFB8E9',
|
||||
// format
|
||||
3584 => '#003804',
|
||||
14 => '#00FB12',
|
||||
// version
|
||||
4096 => '#650098',
|
||||
16 => '#E0B8FF',
|
||||
// data
|
||||
1024 => '#4A6000',
|
||||
4 => '#ECF9BE',
|
||||
// darkmodule
|
||||
512 => '#080063',
|
||||
// separator
|
||||
8 => '#AFBFBF',
|
||||
// quietzone
|
||||
18 => '#FFFFFF',
|
||||
];
|
||||
|
||||
// for the image output types
|
||||
$options->moduleValues = [
|
||||
512 => [0, 0, 0],
|
||||
// ...
|
||||
];
|
||||
|
||||
// for string/text output
|
||||
$options->moduleValues = [
|
||||
512 => '#',
|
||||
// ...
|
||||
];
|
||||
```
|
||||
|
||||
|
||||
## Public API
|
||||
|
||||
### `QRCode` API
|
||||
#### Methods
|
||||
method | return | description
|
||||
------ | ------ | -----------
|
||||
`__construct(QROptions $options = null)` | - | see [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerInterface.php)
|
||||
`render(string $data, string $file = null)` | mixed, `QROutputInterface::dump()` | renders a QR Code for the given `$data` and `QROptions`, saves `$file` optional
|
||||
`getMatrix(string $data)` | `QRMatrix` | returns a `QRMatrix` object for the given `$data` and current `QROptions`
|
||||
`initDataInterface(string $data)` | `QRDataInterface` | returns a fresh `QRDataInterface` for the given `$data`
|
||||
`isNumber(string $string)` | bool | checks if a string qualifies for `Number`
|
||||
`isAlphaNum(string $string)` | bool | checks if a string qualifies for `AlphaNum`
|
||||
`isKanji(string $string)` | bool | checks if a string qualifies for `Kanji`
|
||||
`isByte(string $string)` | bool | checks if a string is non-empty
|
||||
|
||||
#### Constants
|
||||
name | description
|
||||
---- | -----------
|
||||
`VERSION_AUTO` | `QROptions::$version`
|
||||
`MASK_PATTERN_AUTO` | `QROptions::$maskPattern`
|
||||
`OUTPUT_MARKUP_SVG`, `OUTPUT_MARKUP_HTML` | `QROptions::$outputType` markup
|
||||
`OUTPUT_IMAGE_PNG`, `OUTPUT_IMAGE_JPG`, `OUTPUT_IMAGE_GIF` | `QROptions::$outputType` image
|
||||
`OUTPUT_STRING_JSON`, `OUTPUT_STRING_TEXT` | `QROptions::$outputType` string
|
||||
`OUTPUT_IMAGICK` | `QROptions::$outputType` ImageMagick
|
||||
`OUTPUT_FPDF` | `QROptions::$outputType` PDF, using [FPDF](https://github.com/setasign/fpdf)
|
||||
`OUTPUT_CUSTOM` | `QROptions::$outputType`, requires `QROptions::$outputInterface`
|
||||
`ECC_L`, `ECC_M`, `ECC_Q`, `ECC_H`, | ECC-Level: 7%, 15%, 25%, 30% in `QROptions::$eccLevel`
|
||||
`DATA_NUMBER`, `DATA_ALPHANUM`, `DATA_BYTE`, `DATA_KANJI` | `QRDataInterface::$datamode`
|
||||
|
||||
|
||||
### `QRMatrix` API
|
||||
|
||||
#### Methods
|
||||
method | return | description
|
||||
------ | ------ | -----------
|
||||
`__construct(int $version, int $eclevel)` | - | -
|
||||
`init(int $maskPattern, bool $test = null)` | `QRMatrix` |
|
||||
`matrix()` | array | the internal matrix representation as a 2 dimensional array
|
||||
`version()` | int | the current QR Code version
|
||||
`eccLevel()` | int | current ECC level
|
||||
`maskPattern()` | int | the used mask pattern
|
||||
`size()` | int | the absoulute size of the matrix, including quiet zone (if set). `$version * 4 + 17 + 2 * $quietzone`
|
||||
`get(int $x, int $y)` | int | returns the value of the module
|
||||
`set(int $x, int $y, bool $value, int $M_TYPE)` | `QRMatrix` | sets the `$M_TYPE` value for the module
|
||||
`check(int $x, int $y)` | bool | checks whether a module is true (dark) or false (light)
|
||||
|
||||
#### Constants
|
||||
name | light (false) | dark (true) | description
|
||||
---- | ------------- | ----------- | -----------
|
||||
`M_NULL` | 0 | - | module not set (should never appear. if so, there's an error)
|
||||
`M_DARKMODULE` | - | 512 | once per matrix at `$xy = [8, 4 * $version + 9]`
|
||||
`M_DATA` | 4 | 1024 | the actual encoded data
|
||||
`M_FINDER` | 6 | 1536 | the 7x7 finder patterns
|
||||
`M_SEPARATOR` | 8 | - | separator lines around the finder patterns
|
||||
`M_ALIGNMENT` | 10 | 2560 | the 5x5 alignment patterns
|
||||
`M_TIMING` | 12 | 3072 | the timing pattern lines
|
||||
`M_FORMAT` | 14 | 3584 | format information pattern
|
||||
`M_VERSION` | 16 | 4096 | version information pattern
|
||||
`M_QUIETZONE` | 18 | - | margin around the QR Code
|
||||
`M_LOGO` | 20 | - | space for a logo image (not used yet)
|
||||
`M_TEST` | 255 | 65280 | test value
|
||||
|
||||
### `QROptions` API
|
||||
|
||||
#### Properties
|
||||
property | type | default | allowed | description
|
||||
-------- | ---- | ------- | ------- | -----------
|
||||
`$version` | int | `QRCode::VERSION_AUTO` | 1...40 | the [QR Code version number](http://www.qrcode.com/en/about/version.html)
|
||||
`$versionMin` | int | 1 | 1...40 | Minimum QR version (if `$version = QRCode::VERSION_AUTO`)
|
||||
`$versionMax` | int | 40 | 1...40 | Maximum QR version (if `$version = QRCode::VERSION_AUTO`)
|
||||
`$eccLevel` | int | `QRCode::ECC_L` | `QRCode::ECC_X` | Error correct level, where X = L (7%), M (15%), Q (25%), H (30%)
|
||||
`$maskPattern` | int | `QRCode::MASK_PATTERN_AUTO` | 0...7 | Mask Pattern to use
|
||||
`$addQuietzone` | bool | `true` | - | Add a "quiet zone" (margin) according to the QR code spec
|
||||
`$quietzoneSize` | int | 4 | clamped to 0 ... `$matrixSize / 2` | Size of the quiet zone
|
||||
`$dataModeOverride` | string | `null` | `Number`, `AlphaNum`, `Kanji`, `Byte` | allows overriding the data type detection
|
||||
`$outputType` | string | `QRCode::OUTPUT_IMAGE_PNG` | `QRCode::OUTPUT_*` | built-in output type
|
||||
`$outputInterface` | string | `null` | * | FQCN of the custom `QROutputInterface` if `QROptions::$outputType` is set to `QRCode::OUTPUT_CUSTOM`
|
||||
`$cachefile` | string | `null` | * | optional cache file path
|
||||
`$eol` | string | `PHP_EOL` | * | newline string (HTML, SVG, TEXT)
|
||||
`$scale` | int | 5 | * | size of a QR code pixel (SVG, IMAGE_*), HTML -> via CSS
|
||||
`$cssClass` | string | `null` | * | a common css class
|
||||
`$svgOpacity` | float | 1.0 | 0...1 |
|
||||
`$svgDefs` | string | * | * | anything between [`<defs>`](https://developer.mozilla.org/docs/Web/SVG/Element/defs)
|
||||
`$svgViewBoxSize` | int | `null` | * | a positive integer which defines width/height of the [viewBox attribute](https://css-tricks.com/scale-svg/#article-header-id-3)
|
||||
`$textDark` | string | '🔴' | * | string substitute for dark
|
||||
`$textLight` | string | '⭕' | * | string substitute for light
|
||||
`$markupDark` | string | '#000' | * | markup substitute for dark (CSS value)
|
||||
`$markupLight` | string | '#fff' | * | markup substitute for light (CSS value)
|
||||
`$imageBase64` | bool | `true` | - | whether to return the image data as base64 or raw like from `file_get_contents()`
|
||||
`$imageTransparent` | bool | `true` | - | toggle transparency (no jpeg support)
|
||||
`$imageTransparencyBG` | array | `[255, 255, 255]` | `[R, G, B]` | the RGB values for the transparent color, see [`imagecolortransparent()`](http://php.net/manual/function.imagecolortransparent.php)
|
||||
`$pngCompression` | int | -1 | -1 ... 9 | `imagepng()` compression level, -1 = auto
|
||||
`$jpegQuality` | int | 85 | 0 - 100 | `imagejpeg()` quality
|
||||
`$imagickFormat` | string | 'png' | * | ImageMagick output type, see `Imagick::setType()`
|
||||
`$imagickBG` | string | `null` | * | ImageMagick background color, see `ImagickPixel::__construct()`
|
||||
`$moduleValues` | array | `null` | * | Module values map, see [[Custom output interface]] and `QROutputInterface::DEFAULT_MODULE_VALUES`
|
||||
|
||||
|
||||
## Framework Integration
|
||||
- Drupal:
|
||||
- [Google Authenticator Login `ga_login`](https://www.drupal.org/project/ga_login)
|
||||
- Symfony
|
||||
- [phpqrcode-bundle](https://github.com/jonasarts/phpqrcode-bundle)
|
||||
- WordPress:
|
||||
- [`wp-two-factor-auth`](https://github.com/sjinks/wp-two-factor-auth)
|
||||
- [`simple-2fa`](https://wordpress.org/plugins/simple-2fa/)
|
||||
- [`wordpress-seo`](https://github.com/Yoast/wordpress-seo)
|
||||
- [`floating-share-button`](https://github.com/qriouslad/floating-share-button)
|
||||
- WoltLab Suite
|
||||
- [two-step-verification](http://pluginstore.woltlab.com/file/3007-two-step-verification/)
|
||||
- [Appwrite](https://github.com/appwrite/appwrite)
|
||||
- [Cachet](https://github.com/CachetHQ/Cachet)
|
||||
- [twill](https://github.com/area17/twill)
|
||||
- other uses: [dependents](https://github.com/chillerlan/php-qrcode/network/dependents) / [packages](https://github.com/chillerlan/php-qrcode/network/dependents?dependent_type=PACKAGE)
|
||||
|
||||
## Shameless advertising
|
||||
Hi, please check out my other projects that are way cooler than qrcodes!
|
||||
|
||||
- [php-oauth-core](https://github.com/chillerlan/php-oauth-core) - an OAuth 1/2 client library along with a bunch of [providers](https://github.com/chillerlan/php-oauth-providers)
|
||||
- [php-httpinterface](https://github.com/chillerlan/php-httpinterface) - a PSR-7/15/17/18 implemetation
|
||||
- [php-database](https://github.com/chillerlan/php-database) - a database client & querybuilder for MySQL, Postgres, SQLite, MSSQL, Firebird
|
||||
|
||||
## Disclaimer!
|
||||
I don't take responsibility for molten CPUs, misled applications, failed log-ins etc.. Use at your own risk!
|
||||
|
||||
### Trademark Notice
|
||||
|
||||
The word "QR Code" is a registered trademark of *DENSO WAVE INCORPORATED*<br>
|
||||
https://www.qrcode.com/en/faq.html#patentH2Title
|
||||
61
vendor/chillerlan/php-qrcode/composer.json
vendored
Normal file
61
vendor/chillerlan/php-qrcode/composer.json
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
"description": "A QR code generator. PHP 7.4+",
|
||||
"homepage": "https://github.com/chillerlan/php-qrcode",
|
||||
"license": "MIT",
|
||||
"minimum-stability": "stable",
|
||||
"type": "library",
|
||||
"keywords": [
|
||||
"QR code", "qrcode", "qr", "qrcode-generator", "phpqrcode"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kazuhiko Arase",
|
||||
"homepage": "https://github.com/kazuhikoarase"
|
||||
},
|
||||
{
|
||||
"name": "Smiley",
|
||||
"email": "smiley@chillerlan.net",
|
||||
"homepage": "https://github.com/codemasher"
|
||||
},
|
||||
{
|
||||
"name": "Contributors",
|
||||
"homepage":"https://github.com/chillerlan/php-qrcode/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-mbstring": "*",
|
||||
"chillerlan/php-settings-container": "^2.1.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"phan/phan": "^5.3",
|
||||
"setasign/fpdf": "^1.8.2"
|
||||
},
|
||||
"suggest": {
|
||||
"chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.",
|
||||
"setasign/fpdf": "Required to use the QR FPDF output."
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"chillerlan\\QRCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"chillerlan\\QRCodePublic\\": "public/",
|
||||
"chillerlan\\QRCodeTest\\": "tests/",
|
||||
"chillerlan\\QRCodeExamples\\": "examples/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpunit": "@php vendor/bin/phpunit",
|
||||
"phan": "@php vendor/bin/phan"
|
||||
},
|
||||
"config": {
|
||||
"lock": false,
|
||||
"sort-packages": true,
|
||||
"platform-check": true
|
||||
}
|
||||
}
|
||||
38
vendor/chillerlan/php-qrcode/examples/MyCustomOutput.php
vendored
Normal file
38
vendor/chillerlan/php-qrcode/examples/MyCustomOutput.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
* Class MyCustomOutput
|
||||
*
|
||||
* @filesource MyCustomOutput.php
|
||||
* @created 24.12.2017
|
||||
* @package chillerlan\QRCodeExamples
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\Output\QROutputAbstract;
|
||||
|
||||
class MyCustomOutput extends QROutputAbstract{
|
||||
|
||||
protected function setModuleValues():void{
|
||||
// TODO: Implement setModuleValues() method.
|
||||
}
|
||||
|
||||
public function dump(string $file = null){
|
||||
|
||||
$output = '';
|
||||
|
||||
for($row = 0; $row < $this->moduleCount; $row++){
|
||||
for($col = 0; $col < $this->moduleCount; $col++){
|
||||
$output .= (int)$this->matrix->check($col, $row);
|
||||
}
|
||||
|
||||
$output .= \PHP_EOL;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
||||
81
vendor/chillerlan/php-qrcode/examples/QRImageWithLogo.php
vendored
Normal file
81
vendor/chillerlan/php-qrcode/examples/QRImageWithLogo.php
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRImageWithLogo
|
||||
*
|
||||
* @filesource QRImageWithLogo.php
|
||||
* @created 18.11.2020
|
||||
* @package chillerlan\QRCodeExamples
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2020 smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\Output\{QRCodeOutputException, QRImage};
|
||||
|
||||
use function imagecopyresampled, imagecreatefrompng, imagesx, imagesy, is_file, is_readable;
|
||||
|
||||
/**
|
||||
* @property \chillerlan\QRCodeExamples\LogoOptions $options
|
||||
*/
|
||||
class QRImageWithLogo extends QRImage{
|
||||
|
||||
/**
|
||||
* @param string|null $file
|
||||
* @param string|null $logo
|
||||
*
|
||||
* @return string
|
||||
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
|
||||
*/
|
||||
public function dump(string $file = null, string $logo = null):string{
|
||||
// set returnResource to true to skip further processing for now
|
||||
$this->options->returnResource = true;
|
||||
|
||||
// of course you could accept other formats too (such as resource or Imagick)
|
||||
// i'm not checking for the file type either for simplicity reasons (assuming PNG)
|
||||
if(!is_file($logo) || !is_readable($logo)){
|
||||
throw new QRCodeOutputException('invalid logo');
|
||||
}
|
||||
|
||||
$this->matrix->setLogoSpace(
|
||||
$this->options->logoSpaceWidth,
|
||||
$this->options->logoSpaceHeight
|
||||
// not utilizing the position here
|
||||
);
|
||||
|
||||
// there's no need to save the result of dump() into $this->image here
|
||||
parent::dump($file);
|
||||
|
||||
$im = imagecreatefrompng($logo);
|
||||
|
||||
// get logo image size
|
||||
$w = imagesx($im);
|
||||
$h = imagesy($im);
|
||||
|
||||
// set new logo size, leave a border of 1 module (no proportional resize/centering)
|
||||
$lw = ($this->options->logoSpaceWidth - 2) * $this->options->scale;
|
||||
$lh = ($this->options->logoSpaceHeight - 2) * $this->options->scale;
|
||||
|
||||
// get the qrcode size
|
||||
$ql = $this->matrix->size() * $this->options->scale;
|
||||
|
||||
// scale the logo and copy it over. done!
|
||||
imagecopyresampled($this->image, $im, ($ql - $lw) / 2, ($ql - $lh) / 2, 0, 0, $lw, $lh, $w, $h);
|
||||
|
||||
$imageData = $this->dumpImage();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$imageData = 'data:image/'.$this->options->outputType.';base64,'.base64_encode($imageData);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
}
|
||||
100
vendor/chillerlan/php-qrcode/examples/QRImageWithText.php
vendored
Normal file
100
vendor/chillerlan/php-qrcode/examples/QRImageWithText.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRImageWithText
|
||||
*
|
||||
* example for additional text
|
||||
*
|
||||
* @link https://github.com/chillerlan/php-qrcode/issues/35
|
||||
*
|
||||
* @filesource QRImageWithText.php
|
||||
* @created 22.06.2019
|
||||
* @package chillerlan\QRCodeExamples
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2019 smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\Output\QRImage;
|
||||
|
||||
use function base64_encode, imagechar, imagecolorallocate, imagecolortransparent, imagecopymerge, imagecreatetruecolor,
|
||||
imagedestroy, imagefilledrectangle, imagefontwidth, in_array, round, str_split, strlen;
|
||||
|
||||
class QRImageWithText extends QRImage{
|
||||
|
||||
/**
|
||||
* @param string|null $file
|
||||
* @param string|null $text
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function dump(string $file = null, string $text = null):string{
|
||||
// set returnResource to true to skip further processing for now
|
||||
$this->options->returnResource = true;
|
||||
|
||||
// there's no need to save the result of dump() into $this->image here
|
||||
parent::dump($file);
|
||||
|
||||
// render text output if a string is given
|
||||
if($text !== null){
|
||||
$this->addText($text);
|
||||
}
|
||||
|
||||
$imageData = $this->dumpImage();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$imageData = 'data:image/'.$this->options->outputType.';base64,'.base64_encode($imageData);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $text
|
||||
*/
|
||||
protected function addText(string $text):void{
|
||||
// save the qrcode image
|
||||
$qrcode = $this->image;
|
||||
|
||||
// options things
|
||||
$textSize = 3; // see imagefontheight() and imagefontwidth()
|
||||
$textBG = [200, 200, 200];
|
||||
$textColor = [50, 50, 50];
|
||||
|
||||
$bgWidth = $this->length;
|
||||
$bgHeight = $bgWidth + 20; // 20px extra space
|
||||
|
||||
// create a new image with additional space
|
||||
$this->image = imagecreatetruecolor($bgWidth, $bgHeight);
|
||||
$background = imagecolorallocate($this->image, ...$textBG);
|
||||
|
||||
// allow transparency
|
||||
if($this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){
|
||||
imagecolortransparent($this->image, $background);
|
||||
}
|
||||
|
||||
// fill the background
|
||||
imagefilledrectangle($this->image, 0, 0, $bgWidth, $bgHeight, $background);
|
||||
|
||||
// copy over the qrcode
|
||||
imagecopymerge($this->image, $qrcode, 0, 0, 0, 0, $this->length, $this->length, 100);
|
||||
imagedestroy($qrcode);
|
||||
|
||||
$fontColor = imagecolorallocate($this->image, ...$textColor);
|
||||
$w = imagefontwidth($textSize);
|
||||
$x = round(($bgWidth - strlen($text) * $w) / 2);
|
||||
|
||||
// loop through the string and draw the letters
|
||||
foreach(str_split($text) as $i => $chr){
|
||||
imagechar($this->image, $textSize, (int)($i * $w + $x), $this->length, $chr, $fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
38
vendor/chillerlan/php-qrcode/examples/custom_output.php
vendored
Normal file
38
vendor/chillerlan/php-qrcode/examples/custom_output.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @filesource custom_output.php
|
||||
* @created 24.12.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
// invoke the QROutputInterface manually
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
]);
|
||||
|
||||
$qrOutputInterface = new MyCustomOutput($options, (new QRCode($options))->getMatrix($data));
|
||||
|
||||
var_dump($qrOutputInterface->dump());
|
||||
|
||||
|
||||
// or just
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
'outputType' => QRCode::OUTPUT_CUSTOM,
|
||||
'outputInterface' => MyCustomOutput::class,
|
||||
]);
|
||||
|
||||
var_dump((new QRCode($options))->render($data));
|
||||
BIN
vendor/chillerlan/php-qrcode/examples/example_image.png
vendored
Normal file
BIN
vendor/chillerlan/php-qrcode/examples/example_image.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.2 KiB |
BIN
vendor/chillerlan/php-qrcode/examples/example_svg.png
vendored
Normal file
BIN
vendor/chillerlan/php-qrcode/examples/example_svg.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
47
vendor/chillerlan/php-qrcode/examples/fpdf.php
vendored
Normal file
47
vendor/chillerlan/php-qrcode/examples/fpdf.php
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_FPDF,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
'scale' => 5,
|
||||
'imageBase64' => false,
|
||||
'moduleValues' => [
|
||||
// finder
|
||||
1536 => [0, 63, 255], // dark (true)
|
||||
6 => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
|
||||
// alignment
|
||||
2560 => [255, 0, 255],
|
||||
10 => [255, 255, 255],
|
||||
// timing
|
||||
3072 => [255, 0, 0],
|
||||
12 => [255, 255, 255],
|
||||
// format
|
||||
3584 => [67, 191, 84],
|
||||
14 => [255, 255, 255],
|
||||
// version
|
||||
4096 => [62, 174, 190],
|
||||
16 => [255, 255, 255],
|
||||
// data
|
||||
1024 => [0, 0, 0],
|
||||
4 => [255, 255, 255],
|
||||
// darkmodule
|
||||
512 => [0, 0, 0],
|
||||
// separator
|
||||
8 => [255, 255, 255],
|
||||
// quietzone
|
||||
18 => [255, 255, 255],
|
||||
],
|
||||
]);
|
||||
|
||||
\header('Content-type: application/pdf');
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
102
vendor/chillerlan/php-qrcode/examples/html.php
vendored
Normal file
102
vendor/chillerlan/php-qrcode/examples/html.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @filesource html.php
|
||||
* @created 21.12.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once '../vendor/autoload.php';
|
||||
|
||||
header('Content-Type: text/html; charset=utf-8');
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<title>QRCode test</title>
|
||||
<style>
|
||||
body{
|
||||
margin: 5em;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
div.qrcode{
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
/* rows */
|
||||
div.qrcode > div {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
/* modules */
|
||||
div.qrcode > div > span {
|
||||
display: inline-block;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
div.qrcode > div > span {
|
||||
background-color: #ccc;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="qrcode">
|
||||
<?php
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'outputType' => QRCode::OUTPUT_MARKUP_HTML,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
'moduleValues' => [
|
||||
// finder
|
||||
1536 => '#A71111', // dark (true)
|
||||
6 => '#FFBFBF', // light (false)
|
||||
// alignment
|
||||
2560 => '#A70364',
|
||||
10 => '#FFC9C9',
|
||||
// timing
|
||||
3072 => '#98005D',
|
||||
12 => '#FFB8E9',
|
||||
// format
|
||||
3584 => '#003804',
|
||||
14 => '#00FB12',
|
||||
// version
|
||||
4096 => '#650098',
|
||||
16 => '#E0B8FF',
|
||||
// data
|
||||
1024 => '#4A6000',
|
||||
4 => '#ECF9BE',
|
||||
// darkmodule
|
||||
512 => '#080063',
|
||||
// separator
|
||||
8 => '#AFBFBF',
|
||||
// quietzone
|
||||
18 => '#FFFFFF',
|
||||
],
|
||||
]);
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
|
||||
?>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
63
vendor/chillerlan/php-qrcode/examples/image.php
vendored
Normal file
63
vendor/chillerlan/php-qrcode/examples/image.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @filesource image.php
|
||||
* @created 24.12.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 10,
|
||||
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
|
||||
'eccLevel' => QRCode::ECC_H,
|
||||
'scale' => 5,
|
||||
'imageBase64' => false,
|
||||
'moduleValues' => [
|
||||
// finder
|
||||
1536 => [0, 63, 255], // dark (true)
|
||||
6 => [255, 255, 255], // light (false), white is the transparency color and is enabled by default
|
||||
5632 => [241, 28, 163], // finder dot, dark (true)
|
||||
// alignment
|
||||
2560 => [255, 0, 255],
|
||||
10 => [255, 255, 255],
|
||||
// timing
|
||||
3072 => [255, 0, 0],
|
||||
12 => [255, 255, 255],
|
||||
// format
|
||||
3584 => [67, 99, 84],
|
||||
14 => [255, 255, 255],
|
||||
// version
|
||||
4096 => [62, 174, 190],
|
||||
16 => [255, 255, 255],
|
||||
// data
|
||||
1024 => [0, 0, 0],
|
||||
4 => [255, 255, 255],
|
||||
// darkmodule
|
||||
512 => [0, 0, 0],
|
||||
// separator
|
||||
8 => [255, 255, 255],
|
||||
// quietzone
|
||||
18 => [255, 255, 255],
|
||||
// logo (requires a call to QRMatrix::setLogoSpace())
|
||||
20 => [255, 255, 255],
|
||||
],
|
||||
]);
|
||||
|
||||
header('Content-type: image/png');
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
45
vendor/chillerlan/php-qrcode/examples/imageWithLogo.php
vendored
Normal file
45
vendor/chillerlan/php-qrcode/examples/imageWithLogo.php
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @filesource imageWithLogo.php
|
||||
* @created 18.11.2020
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2020 smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
/**
|
||||
* @property int $logoSpaceWidth
|
||||
* @property int $logoSpaceHeight
|
||||
*
|
||||
* @noinspection PhpIllegalPsrClassPathInspection
|
||||
*/
|
||||
class LogoOptions extends QROptions{
|
||||
// size in QR modules, multiply with QROptions::$scale for pixel size
|
||||
protected int $logoSpaceWidth;
|
||||
protected int $logoSpaceHeight;
|
||||
}
|
||||
|
||||
$options = new LogoOptions;
|
||||
|
||||
$options->version = 7;
|
||||
$options->eccLevel = QRCode::ECC_H;
|
||||
$options->imageBase64 = false;
|
||||
$options->logoSpaceWidth = 13;
|
||||
$options->logoSpaceHeight = 13;
|
||||
$options->scale = 5;
|
||||
$options->imageTransparent = false;
|
||||
|
||||
header('Content-type: image/png');
|
||||
|
||||
$qrOutputInterface = new QRImageWithLogo($options, (new QRCode($options))->getMatrix($data));
|
||||
|
||||
// dump the output, with an additional logo
|
||||
echo $qrOutputInterface->dump(null, __DIR__.'/octocat.png');
|
||||
33
vendor/chillerlan/php-qrcode/examples/imageWithText.php
vendored
Normal file
33
vendor/chillerlan/php-qrcode/examples/imageWithText.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
/**
|
||||
* example for additional text
|
||||
* @link https://github.com/chillerlan/php-qrcode/issues/35
|
||||
*
|
||||
* @filesource imageWithText.php
|
||||
* @created 22.06.2019
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2019 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_IMAGE_PNG,
|
||||
'scale' => 3,
|
||||
'imageBase64' => false,
|
||||
]);
|
||||
|
||||
header('Content-type: image/png');
|
||||
|
||||
$qrOutputInterface = new QRImageWithText($options, (new QRCode($options))->getMatrix($data));
|
||||
|
||||
// dump the output, with additional text
|
||||
echo $qrOutputInterface->dump(null, 'example text');
|
||||
59
vendor/chillerlan/php-qrcode/examples/imagick.php
vendored
Normal file
59
vendor/chillerlan/php-qrcode/examples/imagick.php
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @filesource image.php
|
||||
* @created 24.12.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_IMAGICK,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
'scale' => 5,
|
||||
'moduleValues' => [
|
||||
// finder
|
||||
1536 => '#A71111', // dark (true)
|
||||
6 => '#FFBFBF', // light (false)
|
||||
// alignment
|
||||
2560 => '#A70364',
|
||||
10 => '#FFC9C9',
|
||||
// timing
|
||||
3072 => '#98005D',
|
||||
12 => '#FFB8E9',
|
||||
// format
|
||||
3584 => '#003804',
|
||||
14 => '#00FB12',
|
||||
// version
|
||||
4096 => '#650098',
|
||||
16 => '#E0B8FF',
|
||||
// data
|
||||
1024 => '#4A6000',
|
||||
4 => '#ECF9BE',
|
||||
// darkmodule
|
||||
512 => '#080063',
|
||||
// separator
|
||||
8 => '#DDDDDD',
|
||||
// quietzone
|
||||
18 => '#DDDDDD',
|
||||
],
|
||||
]);
|
||||
|
||||
header('Content-type: image/png');
|
||||
|
||||
echo (new QRCode($options))->render($data);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
vendor/chillerlan/php-qrcode/examples/octocat.png
vendored
Normal file
BIN
vendor/chillerlan/php-qrcode/examples/octocat.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
78
vendor/chillerlan/php-qrcode/examples/svg.php
vendored
Normal file
78
vendor/chillerlan/php-qrcode/examples/svg.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @filesource svg.php
|
||||
* @created 21.12.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
$gzip = true;
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 7,
|
||||
'outputType' => QRCode::OUTPUT_MARKUP_SVG,
|
||||
'imageBase64' => false,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
'svgViewBoxSize' => 530,
|
||||
'addQuietzone' => true,
|
||||
'cssClass' => 'my-css-class',
|
||||
'svgOpacity' => 1.0,
|
||||
'svgDefs' => '
|
||||
<linearGradient id="g2">
|
||||
<stop offset="0%" stop-color="#39F" />
|
||||
<stop offset="100%" stop-color="#F3F" />
|
||||
</linearGradient>
|
||||
<linearGradient id="g1">
|
||||
<stop offset="0%" stop-color="#F3F" />
|
||||
<stop offset="100%" stop-color="#39F" />
|
||||
</linearGradient>
|
||||
<style>rect{shape-rendering:crispEdges}</style>',
|
||||
'moduleValues' => [
|
||||
// finder
|
||||
1536 => 'url(#g1)', // dark (true)
|
||||
6 => '#fff', // light (false)
|
||||
// alignment
|
||||
2560 => 'url(#g1)',
|
||||
10 => '#fff',
|
||||
// timing
|
||||
3072 => 'url(#g1)',
|
||||
12 => '#fff',
|
||||
// format
|
||||
3584 => 'url(#g1)',
|
||||
14 => '#fff',
|
||||
// version
|
||||
4096 => 'url(#g1)',
|
||||
16 => '#fff',
|
||||
// data
|
||||
1024 => 'url(#g2)',
|
||||
4 => '#fff',
|
||||
// darkmodule
|
||||
512 => 'url(#g1)',
|
||||
// separator
|
||||
8 => '#fff',
|
||||
// quietzone
|
||||
18 => '#fff',
|
||||
],
|
||||
]);
|
||||
|
||||
$qrcode = (new QRCode($options))->render($data);
|
||||
|
||||
header('Content-type: image/svg+xml');
|
||||
|
||||
if($gzip === true){
|
||||
header('Vary: Accept-Encoding');
|
||||
header('Content-Encoding: gzip');
|
||||
$qrcode = gzencode($qrcode ,9);
|
||||
}
|
||||
echo $qrcode;
|
||||
|
||||
|
||||
68
vendor/chillerlan/php-qrcode/examples/text.php
vendored
Normal file
68
vendor/chillerlan/php-qrcode/examples/text.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
/**
|
||||
*
|
||||
* @filesource text.php
|
||||
* @created 21.12.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodeExamples;
|
||||
|
||||
use chillerlan\QRCode\{QRCode, QROptions};
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
$data = 'https://www.youtube.com/watch?v=DLzxrzFCyOs&t=43s';
|
||||
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'outputType' => QRCode::OUTPUT_STRING_TEXT,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
]);
|
||||
|
||||
// <pre> to view it in a browser
|
||||
echo '<pre style="font-size: 75%; line-height: 1;">'.(new QRCode($options))->render($data).'</pre>';
|
||||
|
||||
|
||||
// custom values
|
||||
$options = new QROptions([
|
||||
'version' => 5,
|
||||
'outputType' => QRCode::OUTPUT_STRING_TEXT,
|
||||
'eccLevel' => QRCode::ECC_L,
|
||||
'moduleValues' => [
|
||||
// finder
|
||||
1536 => 'A', // dark (true)
|
||||
6 => 'a', // light (false)
|
||||
// alignment
|
||||
2560 => 'B',
|
||||
10 => 'b',
|
||||
// timing
|
||||
3072 => 'C',
|
||||
12 => 'c',
|
||||
// format
|
||||
3584 => 'D',
|
||||
14 => 'd',
|
||||
// version
|
||||
4096 => 'E',
|
||||
16 => 'e',
|
||||
// data
|
||||
1024 => 'F',
|
||||
4 => 'f',
|
||||
// darkmodule
|
||||
512 => 'G',
|
||||
// separator
|
||||
8 => 'h',
|
||||
// quietzone
|
||||
18 => 'i',
|
||||
],
|
||||
]);
|
||||
|
||||
// <pre> to view it in a browser
|
||||
echo '<pre style="font-size: 75%; line-height: 1;">'.(new QRCode($options))->render($data).'</pre>';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
20
vendor/chillerlan/php-qrcode/phpdoc.xml
vendored
Normal file
20
vendor/chillerlan/php-qrcode/phpdoc.xml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<phpdoc>
|
||||
<parser>
|
||||
<target>docs</target>
|
||||
<encoding>utf8</encoding>
|
||||
<markers>
|
||||
<item>TODO</item>
|
||||
</markers>
|
||||
</parser>
|
||||
<transformer>
|
||||
<target>docs</target>
|
||||
</transformer>
|
||||
<files>
|
||||
<directory>src</directory>
|
||||
<directory>tests</directory>
|
||||
</files>
|
||||
<transformations>
|
||||
<template name="responsive-twig"/>
|
||||
</transformations>
|
||||
</phpdoc>
|
||||
26
vendor/chillerlan/php-qrcode/phpunit.xml
vendored
Normal file
26
vendor/chillerlan/php-qrcode/phpunit.xml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
cacheResultFile=".build/phpunit.result.cache"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">./src</directory>
|
||||
</include>
|
||||
<report>
|
||||
<clover outputFile=".build/coverage/clover.xml"/>
|
||||
<xml outputDirectory=".build/coverage/coverage-xml"/>
|
||||
</report>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="php-qrcode test suite">
|
||||
<directory suffix=".php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging>
|
||||
<junit outputFile=".build/logs/junit.xml"/>
|
||||
</logging>
|
||||
</phpunit>
|
||||
163
vendor/chillerlan/php-qrcode/public/index.html
vendored
Normal file
163
vendor/chillerlan/php-qrcode/public/index.html
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" >
|
||||
<head >
|
||||
<meta charset="UTF-8" >
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title >QR Code Generator</title >
|
||||
<style >
|
||||
body{ font-size: 20px; line-height: 1.4em; font-family: "Trebuchet MS", sans-serif; color: #000;}
|
||||
input, textarea, select{font-family: Consolas, "Liberation Mono", Courier, monospace; font-size: 75%; line-height: 1.25em; border: 1px solid #aaa; }
|
||||
input:focus, textarea:focus, select:focus{ border: 1px solid #ccc; }
|
||||
label{ cursor: pointer; }
|
||||
#qrcode-settings, div#qrcode-output{ text-align: center; }
|
||||
div#qrcode-output > div {margin: 0;padding: 0;height: 3px;}
|
||||
div#qrcode-output > div > span {display: inline-block;width: 3px;height: 3px;}
|
||||
div#qrcode-output > div > span {background-color: lightgrey;}
|
||||
</style >
|
||||
</head >
|
||||
<body >
|
||||
|
||||
<form id="qrcode-settings" >
|
||||
|
||||
<label for="inputstring" >Input String</label ><br /><textarea name="inputstring" id="inputstring" cols="80" rows="3" autocomplete="off" spellcheck="false"></textarea ><br />
|
||||
|
||||
<label for="version" >Version</label >
|
||||
<input id="version" name="version" class="options" type="number" min="1" max="40" value="5" placeholder="version" />
|
||||
|
||||
<label for="maskpattern" >Mask Pattern</label >
|
||||
<input id="maskpattern" name="maskpattern" class="options" type="number" min="-1" max="7" value="-1" placeholder="mask pattern" />
|
||||
|
||||
<label for="ecc" >ECC</label >
|
||||
<select class="options" id="ecc" name="ecc" >
|
||||
<option value="L" selected="selected" >L - 7%</option >
|
||||
<option value="M" >M - 15%</option >
|
||||
<option value="Q" >Q - 25%</option >
|
||||
<option value="H" >H - 30%</option >
|
||||
</select >
|
||||
|
||||
<br />
|
||||
|
||||
<label for="quietzone" >Quiet Zone
|
||||
<input id="quietzone" name="quietzone" class="options" type="checkbox" value="true" />
|
||||
</label >
|
||||
|
||||
<label for="quietzonesize" >size</label >
|
||||
<input id="quietzonesize" name="quietzonesize" class="options" type="number" min="0" max="100" value="4" placeholder="quiet zone" />
|
||||
|
||||
<br />
|
||||
|
||||
<label for="output_type" >Output</label >
|
||||
<select class="options" id="output_type" name="output_type" >
|
||||
<option value="html" >Markup - HTML</option >
|
||||
<option value="svg" selected="selected" >Markup - SVG</option >
|
||||
<option value="png">Image - png</option >
|
||||
<option value="jpg" >Image - jpg</option >
|
||||
<option value="gif" >Image - gif</option >
|
||||
<option value="text" >String - text</option >
|
||||
<option value="json" >String - json</option >
|
||||
</select >
|
||||
|
||||
<label for="scale" >scale</label >
|
||||
<input id="scale" name="scale" class="options" type="number" min="1" max="10" value="5" placeholder="scale" />
|
||||
|
||||
<div>Finder</div>
|
||||
<label for="m_finder_light" >
|
||||
<input type="text" id="m_finder_light" name="m_finder_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_finder_dark" >
|
||||
<input type="text" id="m_finder_dark" name="m_finder_dark" class="jscolor options" value="000000" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
|
||||
<div>Alignment</div>
|
||||
<label for="m_alignment_light" >
|
||||
<input type="text" id="m_alignment_light" name="m_alignment_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_alignment_dark" >
|
||||
<input type="text" id="m_alignment_dark" name="m_alignment_dark" class="jscolor options" value="000000" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
|
||||
<div>Timing</div>
|
||||
<label for="m_timing_light" >
|
||||
<input type="text" id="m_timing_light" name="m_timing_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_timing_dark" >
|
||||
<input type="text" id="m_timing_dark" name="m_timing_dark" class="jscolor options" value="000000" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
|
||||
<div>Format</div>
|
||||
<label for="m_format_light" >
|
||||
<input type="text" id="m_format_light" name="m_format_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_format_dark" >
|
||||
<input type="text" id="m_format_dark" name="m_format_dark" class="jscolor options" value="000000" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
|
||||
<div>Version</div>
|
||||
<label for="m_version_light" >
|
||||
<input type="text" id="m_version_light" name="m_version_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_version_dark" >
|
||||
<input type="text" id="m_version_dark" name="m_version_dark" class="jscolor options" value="000000" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
|
||||
<div>Data</div>
|
||||
<label for="m_data_light" >
|
||||
<input type="text" id="m_data_light" name="m_data_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_data_dark" >
|
||||
<input type="text" id="m_data_dark" name="m_data_dark" class="jscolor options" value="000000" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
|
||||
<div>Dark Module</div>
|
||||
<label for="m_darkmodule_light" >
|
||||
<input disabled="disabled" type="text" id="m_darkmodule_light" class="options" value="" autocomplete="off" spellcheck="false" />
|
||||
</label >
|
||||
<label for="m_darkmodule_dark" >
|
||||
<input type="text" id="m_darkmodule_dark" name="m_darkmodule_dark" class="jscolor options" value="000000" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
|
||||
<div>Separator</div>
|
||||
<label for="m_separator_light" >
|
||||
<input type="text" id="m_separator_light" name="m_separator_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_separator_dark" >
|
||||
<input disabled="disabled" type="text" id="m_separator_dark" class="options" value="" autocomplete="off" spellcheck="false" />
|
||||
</label >
|
||||
|
||||
<div>Quiet Zone</div>
|
||||
<label for="m_quietzone_light" >
|
||||
<input type="text" id="m_quietzone_light" name="m_quietzone_light" class="jscolor options" value="ffffff" autocomplete="off" spellcheck="false" minlength="6" maxlength="6" />
|
||||
</label >
|
||||
<label for="m_quietzone_dark" >
|
||||
<input disabled="disabled" type="text" id="m_quietzone_dark" class="options" value="" autocomplete="off" spellcheck="false" />
|
||||
</label >
|
||||
|
||||
<br />
|
||||
<button type="submit" >generate</button >
|
||||
</form >
|
||||
<div id="qrcode-output" ></div >
|
||||
|
||||
<div><a href="https://play.google.com/store/apps/details?id=com.google.zxing.client.android" >ZXing Barcode Scanner</a ></div>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.js" ></script >
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jscolor/2.0.4/jscolor.js" ></script >
|
||||
<script >
|
||||
((form, output, url) => {
|
||||
|
||||
$(form).observe('submit', ev => {
|
||||
Event.stop(ev);
|
||||
|
||||
new Ajax.Request(url, {
|
||||
method: 'post',
|
||||
parameters: ev.target.serialize(true),
|
||||
onUninitialized: $(output).update(),
|
||||
onLoading: $(output).update('[portlandia_screaming.gif]'),
|
||||
onFailure: response => $(output).update(response.responseJSON.error),
|
||||
onSuccess: response => $(output).update(response.responseJSON.qrcode),
|
||||
});
|
||||
|
||||
});
|
||||
})('qrcode-settings', 'qrcode-output', './qrcode.php');
|
||||
</script >
|
||||
|
||||
</body >
|
||||
</html >
|
||||
97
vendor/chillerlan/php-qrcode/public/qrcode.php
vendored
Normal file
97
vendor/chillerlan/php-qrcode/public/qrcode.php
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
/**
|
||||
* @filesource qrcode.php
|
||||
* @created 18.11.2017
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCodePublic;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
|
||||
require_once '../vendor/autoload.php';
|
||||
|
||||
try{
|
||||
|
||||
$moduleValues = [
|
||||
// finder
|
||||
1536 => $_POST['m_finder_dark'],
|
||||
6 => $_POST['m_finder_light'],
|
||||
// alignment
|
||||
2560 => $_POST['m_alignment_dark'],
|
||||
10 => $_POST['m_alignment_light'],
|
||||
// timing
|
||||
3072 => $_POST['m_timing_dark'],
|
||||
12 => $_POST['m_timing_light'],
|
||||
// format
|
||||
3584 => $_POST['m_format_dark'],
|
||||
14 => $_POST['m_format_light'],
|
||||
// version
|
||||
4096 => $_POST['m_version_dark'],
|
||||
16 => $_POST['m_version_light'],
|
||||
// data
|
||||
1024 => $_POST['m_data_dark'],
|
||||
4 => $_POST['m_data_light'],
|
||||
// darkmodule
|
||||
512 => $_POST['m_darkmodule_dark'],
|
||||
// separator
|
||||
8 => $_POST['m_separator_light'],
|
||||
// quietzone
|
||||
18 => $_POST['m_quietzone_light'],
|
||||
];
|
||||
|
||||
$moduleValues = array_map(function($v){
|
||||
if(preg_match('/[a-f\d]{6}/i', $v) === 1){
|
||||
return in_array($_POST['output_type'], ['png', 'jpg', 'gif'])
|
||||
? array_map('hexdec', str_split($v, 2))
|
||||
: '#'.$v ;
|
||||
}
|
||||
return null;
|
||||
}, $moduleValues);
|
||||
|
||||
|
||||
$ecc = in_array($_POST['ecc'], ['L', 'M', 'Q', 'H'], true) ? $_POST['ecc'] : 'L';
|
||||
|
||||
$qro = new QROptions;
|
||||
|
||||
$qro->version = (int)$_POST['version'];
|
||||
$qro->eccLevel = constant('chillerlan\\QRCode\\QRCode::ECC_'.$ecc);
|
||||
$qro->maskPattern = (int)$_POST['maskpattern'];
|
||||
$qro->addQuietzone = isset($_POST['quietzone']);
|
||||
$qro->quietzoneSize = (int)$_POST['quietzonesize'];
|
||||
$qro->moduleValues = $moduleValues;
|
||||
$qro->outputType = $_POST['output_type'];
|
||||
$qro->scale = (int)$_POST['scale'];
|
||||
$qro->imageTransparent = false;
|
||||
|
||||
$qrcode = (new QRCode($qro))->render($_POST['inputstring']);
|
||||
|
||||
if(in_array($_POST['output_type'], ['png', 'jpg', 'gif'])){
|
||||
$qrcode = '<img src="'.$qrcode.'" />';
|
||||
}
|
||||
elseif($_POST['output_type'] === 'text'){
|
||||
$qrcode = '<pre style="font-size: 75%; line-height: 1;">'.$qrcode.'</pre>';
|
||||
}
|
||||
elseif($_POST['output_type'] === 'json'){
|
||||
$qrcode = '<pre style="font-size: 75%; overflow-x: auto;">'.$qrcode.'</pre>';
|
||||
}
|
||||
|
||||
send_response(['qrcode' => $qrcode]);
|
||||
}
|
||||
// Pokémon exception handler
|
||||
catch(\Exception $e){
|
||||
header('HTTP/1.1 500 Internal Server Error');
|
||||
send_response(['error' => $e->getMessage()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $response
|
||||
*/
|
||||
function send_response(array $response){
|
||||
header('Content-type: application/json;charset=utf-8;');
|
||||
echo json_encode($response);
|
||||
exit;
|
||||
}
|
||||
60
vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php
vendored
Normal file
60
vendor/chillerlan/php-qrcode/src/Data/AlphaNum.php
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
/**
|
||||
* Class AlphaNum
|
||||
*
|
||||
* @filesource AlphaNum.php
|
||||
* @created 25.11.2015
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
|
||||
use function ord, sprintf;
|
||||
|
||||
/**
|
||||
* Alphanumeric mode: 0 to 9, A to Z, space, $ % * + - . / :
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.3.3
|
||||
* ISO/IEC 18004:2000 Section 8.4.3
|
||||
*/
|
||||
final class AlphaNum extends QRDataAbstract{
|
||||
|
||||
protected int $datamode = QRCode::DATA_ALPHANUM;
|
||||
|
||||
protected array $lengthBits = [9, 11, 13];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function write(string $data):void{
|
||||
|
||||
for($i = 0; $i + 1 < $this->strlen; $i += 2){
|
||||
$this->bitBuffer->put($this->getCharCode($data[$i]) * 45 + $this->getCharCode($data[$i + 1]), 11);
|
||||
}
|
||||
|
||||
if($i < $this->strlen){
|
||||
$this->bitBuffer->put($this->getCharCode($data[$i]), 6);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get the code for the given character
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence
|
||||
*/
|
||||
protected function getCharCode(string $chr):int{
|
||||
|
||||
if(!isset($this::CHAR_MAP_ALPHANUM[$chr])){
|
||||
throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, ord($chr)));
|
||||
}
|
||||
|
||||
return $this::CHAR_MAP_ALPHANUM[$chr];
|
||||
}
|
||||
|
||||
}
|
||||
44
vendor/chillerlan/php-qrcode/src/Data/Byte.php
vendored
Normal file
44
vendor/chillerlan/php-qrcode/src/Data/Byte.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Byte
|
||||
*
|
||||
* @filesource Byte.php
|
||||
* @created 25.11.2015
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
|
||||
use function ord;
|
||||
|
||||
/**
|
||||
* Byte mode, ISO-8859-1 or UTF-8
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.3.4
|
||||
* ISO/IEC 18004:2000 Section 8.4.4
|
||||
*/
|
||||
final class Byte extends QRDataAbstract{
|
||||
|
||||
protected int $datamode = QRCode::DATA_BYTE;
|
||||
|
||||
protected array $lengthBits = [8, 16, 16];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function write(string $data):void{
|
||||
$i = 0;
|
||||
|
||||
while($i < $this->strlen){
|
||||
$this->bitBuffer->put(ord($data[$i]), 8);
|
||||
$i++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
69
vendor/chillerlan/php-qrcode/src/Data/Kanji.php
vendored
Normal file
69
vendor/chillerlan/php-qrcode/src/Data/Kanji.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Kanji
|
||||
*
|
||||
* @filesource Kanji.php
|
||||
* @created 25.11.2015
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
|
||||
use function mb_strlen, ord, sprintf, strlen;
|
||||
|
||||
/**
|
||||
* Kanji mode: double-byte characters from the Shift JIS character set
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.3.5
|
||||
* ISO/IEC 18004:2000 Section 8.4.5
|
||||
*/
|
||||
final class Kanji extends QRDataAbstract{
|
||||
|
||||
protected int $datamode = QRCode::DATA_KANJI;
|
||||
|
||||
protected array $lengthBits = [8, 10, 12];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function getLength(string $data):int{
|
||||
return mb_strlen($data, 'SJIS');
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence
|
||||
*/
|
||||
protected function write(string $data):void{
|
||||
$len = strlen($data);
|
||||
|
||||
for($i = 0; $i + 1 < $len; $i += 2){
|
||||
$c = ((0xff & ord($data[$i])) << 8) | (0xff & ord($data[$i + 1]));
|
||||
|
||||
if($c >= 0x8140 && $c <= 0x9FFC){
|
||||
$c -= 0x8140;
|
||||
}
|
||||
elseif($c >= 0xE040 && $c <= 0xEBBF){
|
||||
$c -= 0xC140;
|
||||
}
|
||||
else{
|
||||
throw new QRCodeDataException(sprintf('illegal char at %d [%d]', $i + 1, $c));
|
||||
}
|
||||
|
||||
$this->bitBuffer->put(((($c >> 8) & 0xff) * 0xC0) + ($c & 0xff), 13);
|
||||
|
||||
}
|
||||
|
||||
if($i < $len){
|
||||
throw new QRCodeDataException(sprintf('illegal char at %d', $i + 1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
203
vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php
vendored
Normal file
203
vendor/chillerlan/php-qrcode/src/Data/MaskPatternTester.php
vendored
Normal file
@@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Class MaskPatternTester
|
||||
*
|
||||
* @filesource MaskPatternTester.php
|
||||
* @created 22.11.2017
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use function abs, array_search, call_user_func_array, min;
|
||||
|
||||
/**
|
||||
* Receives a QRDataInterface object and runs the mask pattern tests on it.
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.8.2 - Evaluation of masking results
|
||||
*
|
||||
* @see http://www.thonky.com/qr-code-tutorial/data-masking
|
||||
*/
|
||||
final class MaskPatternTester{
|
||||
|
||||
/**
|
||||
* The data interface that contains the data matrix to test
|
||||
*/
|
||||
protected QRDataInterface $dataInterface;
|
||||
|
||||
/**
|
||||
* Receives the QRDataInterface
|
||||
*
|
||||
* @see \chillerlan\QRCode\QROptions::$maskPattern
|
||||
* @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern
|
||||
*/
|
||||
public function __construct(QRDataInterface $dataInterface){
|
||||
$this->dataInterface = $dataInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* shoves a QRMatrix through the MaskPatternTester to find the lowest penalty mask pattern
|
||||
*
|
||||
* @see \chillerlan\QRCode\Data\MaskPatternTester
|
||||
*/
|
||||
public function getBestMaskPattern():int{
|
||||
$penalties = [];
|
||||
|
||||
for($pattern = 0; $pattern < 8; $pattern++){
|
||||
$penalties[$pattern] = $this->testPattern($pattern);
|
||||
}
|
||||
|
||||
return array_search(min($penalties), $penalties, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the penalty for the given mask pattern
|
||||
*
|
||||
* @see \chillerlan\QRCode\QROptions::$maskPattern
|
||||
* @see \chillerlan\QRCode\Data\QRMatrix::$maskPattern
|
||||
*/
|
||||
public function testPattern(int $pattern):int{
|
||||
$matrix = $this->dataInterface->initMatrix($pattern, true);
|
||||
$penalty = 0;
|
||||
|
||||
for($level = 1; $level <= 4; $level++){
|
||||
$penalty += call_user_func_array([$this, 'testLevel'.$level], [$matrix->matrix(true), $matrix->size()]);
|
||||
}
|
||||
|
||||
return (int)$penalty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for each group of five or more same-colored modules in a row (or column)
|
||||
*/
|
||||
protected function testLevel1(array $m, int $size):int{
|
||||
$penalty = 0;
|
||||
|
||||
foreach($m as $y => $row){
|
||||
foreach($row as $x => $val){
|
||||
$count = 0;
|
||||
|
||||
for($ry = -1; $ry <= 1; $ry++){
|
||||
|
||||
if($y + $ry < 0 || $size <= $y + $ry){
|
||||
continue;
|
||||
}
|
||||
|
||||
for($rx = -1; $rx <= 1; $rx++){
|
||||
|
||||
if(($ry === 0 && $rx === 0) || (($x + $rx) < 0 || $size <= ($x + $rx))){
|
||||
continue;
|
||||
}
|
||||
|
||||
if($m[$y + $ry][$x + $rx] === $val){
|
||||
$count++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if($count > 5){
|
||||
$penalty += (3 + $count - 5);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $penalty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for each 2x2 area of same-colored modules in the matrix
|
||||
*/
|
||||
protected function testLevel2(array $m, int $size):int{
|
||||
$penalty = 0;
|
||||
|
||||
foreach($m as $y => $row){
|
||||
|
||||
if($y > $size - 2){
|
||||
break;
|
||||
}
|
||||
|
||||
foreach($row as $x => $val){
|
||||
|
||||
if($x > $size - 2){
|
||||
break;
|
||||
}
|
||||
|
||||
if(
|
||||
$val === $m[$y][$x + 1]
|
||||
&& $val === $m[$y + 1][$x]
|
||||
&& $val === $m[$y + 1][$x + 1]
|
||||
){
|
||||
$penalty++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 3 * $penalty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if there are patterns that look similar to the finder patterns (1:1:3:1:1 ratio)
|
||||
*/
|
||||
protected function testLevel3(array $m, int $size):int{
|
||||
$penalties = 0;
|
||||
|
||||
foreach($m as $y => $row){
|
||||
foreach($row as $x => $val){
|
||||
|
||||
if(
|
||||
$x + 6 < $size
|
||||
&& $val
|
||||
&& !$m[$y][$x + 1]
|
||||
&& $m[$y][$x + 2]
|
||||
&& $m[$y][$x + 3]
|
||||
&& $m[$y][$x + 4]
|
||||
&& !$m[$y][$x + 5]
|
||||
&& $m[$y][$x + 6]
|
||||
){
|
||||
$penalties++;
|
||||
}
|
||||
|
||||
if(
|
||||
$y + 6 < $size
|
||||
&& $val
|
||||
&& !$m[$y + 1][$x]
|
||||
&& $m[$y + 2][$x]
|
||||
&& $m[$y + 3][$x]
|
||||
&& $m[$y + 4][$x]
|
||||
&& !$m[$y + 5][$x]
|
||||
&& $m[$y + 6][$x]
|
||||
){
|
||||
$penalties++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $penalties * 40;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if more than half of the modules are dark or light, with a larger penalty for a larger difference
|
||||
*/
|
||||
protected function testLevel4(array $m, int $size):float{
|
||||
$count = 0;
|
||||
|
||||
foreach($m as $y => $row){
|
||||
foreach($row as $x => $val){
|
||||
if($val){
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (abs(100 * $count / $size / $size - 50) / 5) * 10;
|
||||
}
|
||||
|
||||
}
|
||||
77
vendor/chillerlan/php-qrcode/src/Data/Number.php
vendored
Normal file
77
vendor/chillerlan/php-qrcode/src/Data/Number.php
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Number
|
||||
*
|
||||
* @filesource Number.php
|
||||
* @created 26.11.2015
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
|
||||
use function ord, sprintf, str_split, substr;
|
||||
|
||||
/**
|
||||
* Numeric mode: decimal digits 0 to 9
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.3.2
|
||||
* ISO/IEC 18004:2000 Section 8.4.2
|
||||
*/
|
||||
final class Number extends QRDataAbstract{
|
||||
|
||||
protected int $datamode = QRCode::DATA_NUMBER;
|
||||
|
||||
protected array $lengthBits = [10, 12, 14];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected function write(string $data):void{
|
||||
$i = 0;
|
||||
|
||||
while($i + 2 < $this->strlen){
|
||||
$this->bitBuffer->put($this->parseInt(substr($data, $i, 3)), 10);
|
||||
$i += 3;
|
||||
}
|
||||
|
||||
if($i < $this->strlen){
|
||||
|
||||
if($this->strlen - $i === 1){
|
||||
$this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 1)), 4);
|
||||
}
|
||||
elseif($this->strlen - $i === 2){
|
||||
$this->bitBuffer->put($this->parseInt(substr($data, $i, $i + 2)), 7);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* get the code for the given numeric string
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException on an illegal character occurence
|
||||
*/
|
||||
protected function parseInt(string $string):int{
|
||||
$num = 0;
|
||||
|
||||
foreach(str_split($string) as $chr){
|
||||
$c = ord($chr);
|
||||
|
||||
if(!isset($this::CHAR_MAP_NUMBER[$chr])){
|
||||
throw new QRCodeDataException(sprintf('illegal char: "%s" [%d]', $chr, $c));
|
||||
}
|
||||
|
||||
$c = $c - 48; // ord('0')
|
||||
$num = $num * 10 + $c;
|
||||
}
|
||||
|
||||
return $num;
|
||||
}
|
||||
|
||||
}
|
||||
17
vendor/chillerlan/php-qrcode/src/Data/QRCodeDataException.php
vendored
Normal file
17
vendor/chillerlan/php-qrcode/src/Data/QRCodeDataException.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRCodeDataException
|
||||
*
|
||||
* @filesource QRCodeDataException.php
|
||||
* @created 09.12.2015
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use chillerlan\QRCode\QRCodeException;
|
||||
|
||||
class QRCodeDataException extends QRCodeException{}
|
||||
311
vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php
vendored
Normal file
311
vendor/chillerlan/php-qrcode/src/Data/QRDataAbstract.php
vendored
Normal file
@@ -0,0 +1,311 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRDataAbstract
|
||||
*
|
||||
* @filesource QRDataAbstract.php
|
||||
* @created 25.11.2015
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\Helpers\{BitBuffer, Polynomial};
|
||||
use chillerlan\Settings\SettingsContainerInterface;
|
||||
|
||||
use function array_fill, array_merge, count, max, mb_convert_encoding, mb_detect_encoding, range, sprintf, strlen;
|
||||
|
||||
/**
|
||||
* Processes the binary data and maps it on a matrix which is then being returned
|
||||
*/
|
||||
abstract class QRDataAbstract implements QRDataInterface{
|
||||
|
||||
/**
|
||||
* the string byte count
|
||||
*/
|
||||
protected ?int $strlen = null;
|
||||
|
||||
/**
|
||||
* the current data mode: Num, Alphanum, Kanji, Byte
|
||||
*/
|
||||
protected int $datamode;
|
||||
|
||||
/**
|
||||
* mode length bits for the version breakpoints 1-9, 10-26 and 27-40
|
||||
*
|
||||
* ISO/IEC 18004:2000 Table 3 - Number of bits in Character Count Indicator
|
||||
*/
|
||||
protected array $lengthBits = [0, 0, 0];
|
||||
|
||||
/**
|
||||
* current QR Code version
|
||||
*/
|
||||
protected int $version;
|
||||
|
||||
/**
|
||||
* ECC temp data
|
||||
*/
|
||||
protected array $ecdata;
|
||||
|
||||
/**
|
||||
* ECC temp data
|
||||
*/
|
||||
protected array $dcdata;
|
||||
|
||||
/**
|
||||
* the options instance
|
||||
*
|
||||
* @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions
|
||||
*/
|
||||
protected SettingsContainerInterface $options;
|
||||
|
||||
/**
|
||||
* a BitBuffer instance
|
||||
*/
|
||||
protected BitBuffer $bitBuffer;
|
||||
|
||||
/**
|
||||
* QRDataInterface constructor.
|
||||
*/
|
||||
public function __construct(SettingsContainerInterface $options, string $data = null){
|
||||
$this->options = $options;
|
||||
|
||||
if($data !== null){
|
||||
$this->setData($data);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function setData(string $data):QRDataInterface{
|
||||
|
||||
if($this->datamode === QRCode::DATA_KANJI){
|
||||
$data = mb_convert_encoding($data, 'SJIS', mb_detect_encoding($data));
|
||||
}
|
||||
|
||||
$this->strlen = $this->getLength($data);
|
||||
$this->version = $this->options->version === QRCode::VERSION_AUTO
|
||||
? $this->getMinimumVersion()
|
||||
: $this->options->version;
|
||||
|
||||
$this->writeBitBuffer($data);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function initMatrix(int $maskPattern, bool $test = null):QRMatrix{
|
||||
return (new QRMatrix($this->version, $this->options->eccLevel))
|
||||
->init($maskPattern, $test)
|
||||
->mapData($this->maskECC(), $maskPattern)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the length bits for the version breakpoints 1-9, 10-26 and 27-40
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function getLengthBits():int{
|
||||
|
||||
foreach([9, 26, 40] as $key => $breakpoint){
|
||||
if($this->version <= $breakpoint){
|
||||
return $this->lengthBits[$key];
|
||||
}
|
||||
}
|
||||
|
||||
throw new QRCodeDataException(sprintf('invalid version number: %d', $this->version));
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the byte count of the $data string
|
||||
*/
|
||||
protected function getLength(string $data):int{
|
||||
return strlen($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the minimum version number for the given string
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
*/
|
||||
protected function getMinimumVersion():int{
|
||||
$maxlength = 0;
|
||||
|
||||
// guess the version number within the given range
|
||||
$dataMode = QRCode::DATA_MODES[$this->datamode];
|
||||
$eccMode = QRCode::ECC_MODES[$this->options->eccLevel];
|
||||
|
||||
foreach(range($this->options->versionMin, $this->options->versionMax) as $version){
|
||||
$maxlength = $this::MAX_LENGTH[$version][$dataMode][$eccMode];
|
||||
|
||||
if($this->strlen <= $maxlength){
|
||||
return $version;
|
||||
}
|
||||
}
|
||||
|
||||
throw new QRCodeDataException(sprintf('data exceeds %d characters', $maxlength));
|
||||
}
|
||||
|
||||
/**
|
||||
* writes the actual data string to the BitBuffer
|
||||
*
|
||||
* @see \chillerlan\QRCode\Data\QRDataAbstract::writeBitBuffer()
|
||||
*/
|
||||
abstract protected function write(string $data):void;
|
||||
|
||||
/**
|
||||
* creates a BitBuffer and writes the string data to it
|
||||
*
|
||||
* @throws \chillerlan\QRCode\QRCodeException on data overflow
|
||||
*/
|
||||
protected function writeBitBuffer(string $data):void{
|
||||
$this->bitBuffer = new BitBuffer;
|
||||
|
||||
$MAX_BITS = $this::MAX_BITS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]];
|
||||
|
||||
$this->bitBuffer
|
||||
->put($this->datamode, 4)
|
||||
->put($this->strlen, $this->getLengthBits())
|
||||
;
|
||||
|
||||
$this->write($data);
|
||||
|
||||
// overflow, likely caused due to invalid version setting
|
||||
if($this->bitBuffer->getLength() > $MAX_BITS){
|
||||
throw new QRCodeDataException(sprintf('code length overflow. (%d > %d bit)', $this->bitBuffer->getLength(), $MAX_BITS));
|
||||
}
|
||||
|
||||
// add terminator (ISO/IEC 18004:2000 Table 2)
|
||||
if($this->bitBuffer->getLength() + 4 <= $MAX_BITS){
|
||||
$this->bitBuffer->put(0, 4);
|
||||
}
|
||||
|
||||
// padding
|
||||
while($this->bitBuffer->getLength() % 8 !== 0){
|
||||
$this->bitBuffer->putBit(false);
|
||||
}
|
||||
|
||||
// padding
|
||||
while(true){
|
||||
|
||||
if($this->bitBuffer->getLength() >= $MAX_BITS){
|
||||
break;
|
||||
}
|
||||
|
||||
$this->bitBuffer->put(0xEC, 8);
|
||||
|
||||
if($this->bitBuffer->getLength() >= $MAX_BITS){
|
||||
break;
|
||||
}
|
||||
|
||||
$this->bitBuffer->put(0x11, 8);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* ECC masking
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.5 ff
|
||||
*
|
||||
* @see http://www.thonky.com/qr-code-tutorial/error-correction-coding
|
||||
*/
|
||||
protected function maskECC():array{
|
||||
[$l1, $l2, $b1, $b2] = $this::RSBLOCKS[$this->version][QRCode::ECC_MODES[$this->options->eccLevel]];
|
||||
|
||||
$rsBlocks = array_fill(0, $l1, [$b1, $b2]);
|
||||
$rsCount = $l1 + $l2;
|
||||
$this->ecdata = array_fill(0, $rsCount, []);
|
||||
$this->dcdata = $this->ecdata;
|
||||
|
||||
if($l2 > 0){
|
||||
$rsBlocks = array_merge($rsBlocks, array_fill(0, $l2, [$b1 + 1, $b2 + 1]));
|
||||
}
|
||||
|
||||
$totalCodeCount = 0;
|
||||
$maxDcCount = 0;
|
||||
$maxEcCount = 0;
|
||||
$offset = 0;
|
||||
|
||||
$bitBuffer = $this->bitBuffer->getBuffer();
|
||||
|
||||
foreach($rsBlocks as $key => $block){
|
||||
[$rsBlockTotal, $dcCount] = $block;
|
||||
|
||||
$ecCount = $rsBlockTotal - $dcCount;
|
||||
$maxDcCount = max($maxDcCount, $dcCount);
|
||||
$maxEcCount = max($maxEcCount, $ecCount);
|
||||
$this->dcdata[$key] = array_fill(0, $dcCount, null);
|
||||
|
||||
foreach($this->dcdata[$key] as $a => $_z){
|
||||
$this->dcdata[$key][$a] = 0xff & $bitBuffer[$a + $offset];
|
||||
}
|
||||
|
||||
[$num, $add] = $this->poly($key, $ecCount);
|
||||
|
||||
foreach($this->ecdata[$key] as $c => $_){
|
||||
$modIndex = $c + $add;
|
||||
$this->ecdata[$key][$c] = $modIndex >= 0 ? $num[$modIndex] : 0;
|
||||
}
|
||||
|
||||
$offset += $dcCount;
|
||||
$totalCodeCount += $rsBlockTotal;
|
||||
}
|
||||
|
||||
$data = array_fill(0, $totalCodeCount, null);
|
||||
$index = 0;
|
||||
|
||||
$mask = function(array $arr, int $count) use (&$data, &$index, $rsCount):void{
|
||||
for($x = 0; $x < $count; $x++){
|
||||
for($y = 0; $y < $rsCount; $y++){
|
||||
if($x < count($arr[$y])){
|
||||
$data[$index] = $arr[$y][$x];
|
||||
$index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$mask($this->dcdata, $maxDcCount);
|
||||
$mask($this->ecdata, $maxEcCount);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* helper method for the polynomial operations
|
||||
*/
|
||||
protected function poly(int $key, int $count):array{
|
||||
$rsPoly = new Polynomial;
|
||||
$modPoly = new Polynomial;
|
||||
|
||||
for($i = 0; $i < $count; $i++){
|
||||
$modPoly->setNum([1, $modPoly->gexp($i)]);
|
||||
$rsPoly->multiply($modPoly->getNum());
|
||||
}
|
||||
|
||||
$rsPolyCount = count($rsPoly->getNum());
|
||||
|
||||
$modPoly
|
||||
->setNum($this->dcdata[$key], $rsPolyCount - 1)
|
||||
->mod($rsPoly->getNum())
|
||||
;
|
||||
|
||||
$this->ecdata[$key] = array_fill(0, $rsPolyCount - 1, null);
|
||||
$num = $modPoly->getNum();
|
||||
|
||||
return [
|
||||
$num,
|
||||
count($num) - count($this->ecdata[$key]),
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
200
vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php
vendored
Normal file
200
vendor/chillerlan/php-qrcode/src/Data/QRDataInterface.php
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
<?php
|
||||
/**
|
||||
* Interface QRDataInterface
|
||||
*
|
||||
* @filesource QRDataInterface.php
|
||||
* @created 01.12.2015
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
/**
|
||||
* Specifies the methods reqired for the data modules (Number, Alphanum, Byte and Kanji)
|
||||
* and holds version information in several constants
|
||||
*/
|
||||
interface QRDataInterface{
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
const CHAR_MAP_NUMBER = [
|
||||
'0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7, '8' => 8, '9' => 9,
|
||||
];
|
||||
|
||||
/**
|
||||
* ISO/IEC 18004:2000 Table 5
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
const CHAR_MAP_ALPHANUM = [
|
||||
'0' => 0, '1' => 1, '2' => 2, '3' => 3, '4' => 4, '5' => 5, '6' => 6, '7' => 7,
|
||||
'8' => 8, '9' => 9, 'A' => 10, 'B' => 11, 'C' => 12, 'D' => 13, 'E' => 14, 'F' => 15,
|
||||
'G' => 16, 'H' => 17, 'I' => 18, 'J' => 19, 'K' => 20, 'L' => 21, 'M' => 22, 'N' => 23,
|
||||
'O' => 24, 'P' => 25, 'Q' => 26, 'R' => 27, 'S' => 28, 'T' => 29, 'U' => 30, 'V' => 31,
|
||||
'W' => 32, 'X' => 33, 'Y' => 34, 'Z' => 35, ' ' => 36, '$' => 37, '%' => 38, '*' => 39,
|
||||
'+' => 40, '-' => 41, '.' => 42, '/' => 43, ':' => 44,
|
||||
];
|
||||
|
||||
/**
|
||||
* ISO/IEC 18004:2000 Tables 7-11 - Number of symbol characters and input data capacity for versions 1 to 40
|
||||
*
|
||||
* @see http://www.qrcode.com/en/about/version.html
|
||||
*
|
||||
* @var int [][][]
|
||||
*/
|
||||
const MAX_LENGTH =[
|
||||
// v => [NUMERIC => [L, M, Q, H ], ALPHANUM => [L, M, Q, H], BINARY => [L, M, Q, H ], KANJI => [L, M, Q, H ]] // modules
|
||||
1 => [[ 41, 34, 27, 17], [ 25, 20, 16, 10], [ 17, 14, 11, 7], [ 10, 8, 7, 4]], // 21
|
||||
2 => [[ 77, 63, 48, 34], [ 47, 38, 29, 20], [ 32, 26, 20, 14], [ 20, 16, 12, 8]], // 25
|
||||
3 => [[ 127, 101, 77, 58], [ 77, 61, 47, 35], [ 53, 42, 32, 24], [ 32, 26, 20, 15]], // 29
|
||||
4 => [[ 187, 149, 111, 82], [ 114, 90, 67, 50], [ 78, 62, 46, 34], [ 48, 38, 28, 21]], // 33
|
||||
5 => [[ 255, 202, 144, 106], [ 154, 122, 87, 64], [ 106, 84, 60, 44], [ 65, 52, 37, 27]], // 37
|
||||
6 => [[ 322, 255, 178, 139], [ 195, 154, 108, 84], [ 134, 106, 74, 58], [ 82, 65, 45, 36]], // 41
|
||||
7 => [[ 370, 293, 207, 154], [ 224, 178, 125, 93], [ 154, 122, 86, 64], [ 95, 75, 53, 39]], // 45
|
||||
8 => [[ 461, 365, 259, 202], [ 279, 221, 157, 122], [ 192, 152, 108, 84], [ 118, 93, 66, 52]], // 49
|
||||
9 => [[ 552, 432, 312, 235], [ 335, 262, 189, 143], [ 230, 180, 130, 98], [ 141, 111, 80, 60]], // 53
|
||||
10 => [[ 652, 513, 364, 288], [ 395, 311, 221, 174], [ 271, 213, 151, 119], [ 167, 131, 93, 74]], // 57
|
||||
11 => [[ 772, 604, 427, 331], [ 468, 366, 259, 200], [ 321, 251, 177, 137], [ 198, 155, 109, 85]], // 61
|
||||
12 => [[ 883, 691, 489, 374], [ 535, 419, 296, 227], [ 367, 287, 203, 155], [ 226, 177, 125, 96]], // 65
|
||||
13 => [[1022, 796, 580, 427], [ 619, 483, 352, 259], [ 425, 331, 241, 177], [ 262, 204, 149, 109]], // 69 NICE!
|
||||
14 => [[1101, 871, 621, 468], [ 667, 528, 376, 283], [ 458, 362, 258, 194], [ 282, 223, 159, 120]], // 73
|
||||
15 => [[1250, 991, 703, 530], [ 758, 600, 426, 321], [ 520, 412, 292, 220], [ 320, 254, 180, 136]], // 77
|
||||
16 => [[1408, 1082, 775, 602], [ 854, 656, 470, 365], [ 586, 450, 322, 250], [ 361, 277, 198, 154]], // 81
|
||||
17 => [[1548, 1212, 876, 674], [ 938, 734, 531, 408], [ 644, 504, 364, 280], [ 397, 310, 224, 173]], // 85
|
||||
18 => [[1725, 1346, 948, 746], [1046, 816, 574, 452], [ 718, 560, 394, 310], [ 442, 345, 243, 191]], // 89
|
||||
19 => [[1903, 1500, 1063, 813], [1153, 909, 644, 493], [ 792, 624, 442, 338], [ 488, 384, 272, 208]], // 93
|
||||
20 => [[2061, 1600, 1159, 919], [1249, 970, 702, 557], [ 858, 666, 482, 382], [ 528, 410, 297, 235]], // 97
|
||||
21 => [[2232, 1708, 1224, 969], [1352, 1035, 742, 587], [ 929, 711, 509, 403], [ 572, 438, 314, 248]], // 101
|
||||
22 => [[2409, 1872, 1358, 1056], [1460, 1134, 823, 640], [1003, 779, 565, 439], [ 618, 480, 348, 270]], // 105
|
||||
23 => [[2620, 2059, 1468, 1108], [1588, 1248, 890, 672], [1091, 857, 611, 461], [ 672, 528, 376, 284]], // 109
|
||||
24 => [[2812, 2188, 1588, 1228], [1704, 1326, 963, 744], [1171, 911, 661, 511], [ 721, 561, 407, 315]], // 113
|
||||
25 => [[3057, 2395, 1718, 1286], [1853, 1451, 1041, 779], [1273, 997, 715, 535], [ 784, 614, 440, 330]], // 117
|
||||
26 => [[3283, 2544, 1804, 1425], [1990, 1542, 1094, 864], [1367, 1059, 751, 593], [ 842, 652, 462, 365]], // 121
|
||||
27 => [[3517, 2701, 1933, 1501], [2132, 1637, 1172, 910], [1465, 1125, 805, 625], [ 902, 692, 496, 385]], // 125
|
||||
28 => [[3669, 2857, 2085, 1581], [2223, 1732, 1263, 958], [1528, 1190, 868, 658], [ 940, 732, 534, 405]], // 129
|
||||
29 => [[3909, 3035, 2181, 1677], [2369, 1839, 1322, 1016], [1628, 1264, 908, 698], [1002, 778, 559, 430]], // 133
|
||||
30 => [[4158, 3289, 2358, 1782], [2520, 1994, 1429, 1080], [1732, 1370, 982, 742], [1066, 843, 604, 457]], // 137
|
||||
31 => [[4417, 3486, 2473, 1897], [2677, 2113, 1499, 1150], [1840, 1452, 1030, 790], [1132, 894, 634, 486]], // 141
|
||||
32 => [[4686, 3693, 2670, 2022], [2840, 2238, 1618, 1226], [1952, 1538, 1112, 842], [1201, 947, 684, 518]], // 145
|
||||
33 => [[4965, 3909, 2805, 2157], [3009, 2369, 1700, 1307], [2068, 1628, 1168, 898], [1273, 1002, 719, 553]], // 149
|
||||
34 => [[5253, 4134, 2949, 2301], [3183, 2506, 1787, 1394], [2188, 1722, 1228, 958], [1347, 1060, 756, 590]], // 153
|
||||
35 => [[5529, 4343, 3081, 2361], [3351, 2632, 1867, 1431], [2303, 1809, 1283, 983], [1417, 1113, 790, 605]], // 157
|
||||
36 => [[5836, 4588, 3244, 2524], [3537, 2780, 1966, 1530], [2431, 1911, 1351, 1051], [1496, 1176, 832, 647]], // 161
|
||||
37 => [[6153, 4775, 3417, 2625], [3729, 2894, 2071, 1591], [2563, 1989, 1423, 1093], [1577, 1224, 876, 673]], // 165
|
||||
38 => [[6479, 5039, 3599, 2735], [3927, 3054, 2181, 1658], [2699, 2099, 1499, 1139], [1661, 1292, 923, 701]], // 169
|
||||
39 => [[6743, 5313, 3791, 2927], [4087, 3220, 2298, 1774], [2809, 2213, 1579, 1219], [1729, 1362, 972, 750]], // 173
|
||||
40 => [[7089, 5596, 3993, 3057], [4296, 3391, 2420, 1852], [2953, 2331, 1663, 1273], [1817, 1435, 1024, 784]], // 177
|
||||
];
|
||||
|
||||
/**
|
||||
* ISO/IEC 18004:2000 Tables 7-11 - Number of symbol characters and input data capacity for versions 1 to 40
|
||||
*
|
||||
* @var int [][]
|
||||
*/
|
||||
const MAX_BITS = [
|
||||
// version => [L, M, Q, H ]
|
||||
1 => [ 152, 128, 104, 72],
|
||||
2 => [ 272, 224, 176, 128],
|
||||
3 => [ 440, 352, 272, 208],
|
||||
4 => [ 640, 512, 384, 288],
|
||||
5 => [ 864, 688, 496, 368],
|
||||
6 => [ 1088, 864, 608, 480],
|
||||
7 => [ 1248, 992, 704, 528],
|
||||
8 => [ 1552, 1232, 880, 688],
|
||||
9 => [ 1856, 1456, 1056, 800],
|
||||
10 => [ 2192, 1728, 1232, 976],
|
||||
11 => [ 2592, 2032, 1440, 1120],
|
||||
12 => [ 2960, 2320, 1648, 1264],
|
||||
13 => [ 3424, 2672, 1952, 1440],
|
||||
14 => [ 3688, 2920, 2088, 1576],
|
||||
15 => [ 4184, 3320, 2360, 1784],
|
||||
16 => [ 4712, 3624, 2600, 2024],
|
||||
17 => [ 5176, 4056, 2936, 2264],
|
||||
18 => [ 5768, 4504, 3176, 2504],
|
||||
19 => [ 6360, 5016, 3560, 2728],
|
||||
20 => [ 6888, 5352, 3880, 3080],
|
||||
21 => [ 7456, 5712, 4096, 3248],
|
||||
22 => [ 8048, 6256, 4544, 3536],
|
||||
23 => [ 8752, 6880, 4912, 3712],
|
||||
24 => [ 9392, 7312, 5312, 4112],
|
||||
25 => [10208, 8000, 5744, 4304],
|
||||
26 => [10960, 8496, 6032, 4768],
|
||||
27 => [11744, 9024, 6464, 5024],
|
||||
28 => [12248, 9544, 6968, 5288],
|
||||
29 => [13048, 10136, 7288, 5608],
|
||||
30 => [13880, 10984, 7880, 5960],
|
||||
31 => [14744, 11640, 8264, 6344],
|
||||
32 => [15640, 12328, 8920, 6760],
|
||||
33 => [16568, 13048, 9368, 7208],
|
||||
34 => [17528, 13800, 9848, 7688],
|
||||
35 => [18448, 14496, 10288, 7888],
|
||||
36 => [19472, 15312, 10832, 8432],
|
||||
37 => [20528, 15936, 11408, 8768],
|
||||
38 => [21616, 16816, 12016, 9136],
|
||||
39 => [22496, 17728, 12656, 9776],
|
||||
40 => [23648, 18672, 13328, 10208],
|
||||
];
|
||||
|
||||
/**
|
||||
* @see http://www.thonky.com/qr-code-tutorial/error-correction-table
|
||||
*
|
||||
* @var int [][][]
|
||||
*/
|
||||
const RSBLOCKS = [
|
||||
1 => [[ 1, 0, 26, 19], [ 1, 0, 26, 16], [ 1, 0, 26, 13], [ 1, 0, 26, 9]],
|
||||
2 => [[ 1, 0, 44, 34], [ 1, 0, 44, 28], [ 1, 0, 44, 22], [ 1, 0, 44, 16]],
|
||||
3 => [[ 1, 0, 70, 55], [ 1, 0, 70, 44], [ 2, 0, 35, 17], [ 2, 0, 35, 13]],
|
||||
4 => [[ 1, 0, 100, 80], [ 2, 0, 50, 32], [ 2, 0, 50, 24], [ 4, 0, 25, 9]],
|
||||
5 => [[ 1, 0, 134, 108], [ 2, 0, 67, 43], [ 2, 2, 33, 15], [ 2, 2, 33, 11]],
|
||||
6 => [[ 2, 0, 86, 68], [ 4, 0, 43, 27], [ 4, 0, 43, 19], [ 4, 0, 43, 15]],
|
||||
7 => [[ 2, 0, 98, 78], [ 4, 0, 49, 31], [ 2, 4, 32, 14], [ 4, 1, 39, 13]],
|
||||
8 => [[ 2, 0, 121, 97], [ 2, 2, 60, 38], [ 4, 2, 40, 18], [ 4, 2, 40, 14]],
|
||||
9 => [[ 2, 0, 146, 116], [ 3, 2, 58, 36], [ 4, 4, 36, 16], [ 4, 4, 36, 12]],
|
||||
10 => [[ 2, 2, 86, 68], [ 4, 1, 69, 43], [ 6, 2, 43, 19], [ 6, 2, 43, 15]],
|
||||
11 => [[ 4, 0, 101, 81], [ 1, 4, 80, 50], [ 4, 4, 50, 22], [ 3, 8, 36, 12]],
|
||||
12 => [[ 2, 2, 116, 92], [ 6, 2, 58, 36], [ 4, 6, 46, 20], [ 7, 4, 42, 14]],
|
||||
13 => [[ 4, 0, 133, 107], [ 8, 1, 59, 37], [ 8, 4, 44, 20], [12, 4, 33, 11]],
|
||||
14 => [[ 3, 1, 145, 115], [ 4, 5, 64, 40], [11, 5, 36, 16], [11, 5, 36, 12]],
|
||||
15 => [[ 5, 1, 109, 87], [ 5, 5, 65, 41], [ 5, 7, 54, 24], [11, 7, 36, 12]],
|
||||
16 => [[ 5, 1, 122, 98], [ 7, 3, 73, 45], [15, 2, 43, 19], [ 3, 13, 45, 15]],
|
||||
17 => [[ 1, 5, 135, 107], [10, 1, 74, 46], [ 1, 15, 50, 22], [ 2, 17, 42, 14]],
|
||||
18 => [[ 5, 1, 150, 120], [ 9, 4, 69, 43], [17, 1, 50, 22], [ 2, 19, 42, 14]],
|
||||
19 => [[ 3, 4, 141, 113], [ 3, 11, 70, 44], [17, 4, 47, 21], [ 9, 16, 39, 13]],
|
||||
20 => [[ 3, 5, 135, 107], [ 3, 13, 67, 41], [15, 5, 54, 24], [15, 10, 43, 15]],
|
||||
21 => [[ 4, 4, 144, 116], [17, 0, 68, 42], [17, 6, 50, 22], [19, 6, 46, 16]],
|
||||
22 => [[ 2, 7, 139, 111], [17, 0, 74, 46], [ 7, 16, 54, 24], [34, 0, 37, 13]],
|
||||
23 => [[ 4, 5, 151, 121], [ 4, 14, 75, 47], [11, 14, 54, 24], [16, 14, 45, 15]],
|
||||
24 => [[ 6, 4, 147, 117], [ 6, 14, 73, 45], [11, 16, 54, 24], [30, 2, 46, 16]],
|
||||
25 => [[ 8, 4, 132, 106], [ 8, 13, 75, 47], [ 7, 22, 54, 24], [22, 13, 45, 15]],
|
||||
26 => [[10, 2, 142, 114], [19, 4, 74, 46], [28, 6, 50, 22], [33, 4, 46, 16]],
|
||||
27 => [[ 8, 4, 152, 122], [22, 3, 73, 45], [ 8, 26, 53, 23], [12, 28, 45, 15]],
|
||||
28 => [[ 3, 10, 147, 117], [ 3, 23, 73, 45], [ 4, 31, 54, 24], [11, 31, 45, 15]],
|
||||
29 => [[ 7, 7, 146, 116], [21, 7, 73, 45], [ 1, 37, 53, 23], [19, 26, 45, 15]],
|
||||
30 => [[ 5, 10, 145, 115], [19, 10, 75, 47], [15, 25, 54, 24], [23, 25, 45, 15]],
|
||||
31 => [[13, 3, 145, 115], [ 2, 29, 74, 46], [42, 1, 54, 24], [23, 28, 45, 15]],
|
||||
32 => [[17, 0, 145, 115], [10, 23, 74, 46], [10, 35, 54, 24], [19, 35, 45, 15]],
|
||||
33 => [[17, 1, 145, 115], [14, 21, 74, 46], [29, 19, 54, 24], [11, 46, 45, 15]],
|
||||
34 => [[13, 6, 145, 115], [14, 23, 74, 46], [44, 7, 54, 24], [59, 1, 46, 16]],
|
||||
35 => [[12, 7, 151, 121], [12, 26, 75, 47], [39, 14, 54, 24], [22, 41, 45, 15]],
|
||||
36 => [[ 6, 14, 151, 121], [ 6, 34, 75, 47], [46, 10, 54, 24], [ 2, 64, 45, 15]],
|
||||
37 => [[17, 4, 152, 122], [29, 14, 74, 46], [49, 10, 54, 24], [24, 46, 45, 15]],
|
||||
38 => [[ 4, 18, 152, 122], [13, 32, 74, 46], [48, 14, 54, 24], [42, 32, 45, 15]],
|
||||
39 => [[20, 4, 147, 117], [40, 7, 75, 47], [43, 22, 54, 24], [10, 67, 45, 15]],
|
||||
40 => [[19, 6, 148, 118], [18, 31, 75, 47], [34, 34, 54, 24], [20, 61, 45, 15]],
|
||||
];
|
||||
|
||||
/**
|
||||
* Sets the data string (internally called by the constructor)
|
||||
*/
|
||||
public function setData(string $data):QRDataInterface;
|
||||
|
||||
/**
|
||||
* returns a fresh matrix object with the data written for the given $maskPattern
|
||||
*/
|
||||
public function initMatrix(int $maskPattern, bool $test = null):QRMatrix;
|
||||
|
||||
}
|
||||
740
vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php
vendored
Executable file
740
vendor/chillerlan/php-qrcode/src/Data/QRMatrix.php
vendored
Executable file
@@ -0,0 +1,740 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRMatrix
|
||||
*
|
||||
* @filesource QRMatrix.php
|
||||
* @created 15.11.2017
|
||||
* @package chillerlan\QRCode\Data
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2017 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Data;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
use Closure;
|
||||
|
||||
use function array_fill, array_key_exists, array_push, array_unshift, count, floor, in_array, max, min, range;
|
||||
|
||||
/**
|
||||
* Holds a numerical representation of the final QR Code;
|
||||
* maps the ECC coded binary data and applies the mask pattern
|
||||
*
|
||||
* @see http://www.thonky.com/qr-code-tutorial/format-version-information
|
||||
*/
|
||||
final class QRMatrix{
|
||||
|
||||
/** @var int */
|
||||
public const M_NULL = 0x00;
|
||||
/** @var int */
|
||||
public const M_DARKMODULE = 0x02;
|
||||
/** @var int */
|
||||
public const M_DATA = 0x04;
|
||||
/** @var int */
|
||||
public const M_FINDER = 0x06;
|
||||
/** @var int */
|
||||
public const M_SEPARATOR = 0x08;
|
||||
/** @var int */
|
||||
public const M_ALIGNMENT = 0x0a;
|
||||
/** @var int */
|
||||
public const M_TIMING = 0x0c;
|
||||
/** @var int */
|
||||
public const M_FORMAT = 0x0e;
|
||||
/** @var int */
|
||||
public const M_VERSION = 0x10;
|
||||
/** @var int */
|
||||
public const M_QUIETZONE = 0x12;
|
||||
/** @var int */
|
||||
public const M_LOGO = 0x14;
|
||||
/** @var int */
|
||||
public const M_FINDER_DOT = 0x16;
|
||||
/** @var int */
|
||||
public const M_TEST = 0xff;
|
||||
|
||||
/**
|
||||
* ISO/IEC 18004:2000 Annex E, Table E.1 - Row/column coordinates of center module of Alignment Patterns
|
||||
*
|
||||
* version -> pattern
|
||||
*
|
||||
* @var int[][]
|
||||
*/
|
||||
protected const alignmentPattern = [
|
||||
1 => [],
|
||||
2 => [6, 18],
|
||||
3 => [6, 22],
|
||||
4 => [6, 26],
|
||||
5 => [6, 30],
|
||||
6 => [6, 34],
|
||||
7 => [6, 22, 38],
|
||||
8 => [6, 24, 42],
|
||||
9 => [6, 26, 46],
|
||||
10 => [6, 28, 50],
|
||||
11 => [6, 30, 54],
|
||||
12 => [6, 32, 58],
|
||||
13 => [6, 34, 62],
|
||||
14 => [6, 26, 46, 66],
|
||||
15 => [6, 26, 48, 70],
|
||||
16 => [6, 26, 50, 74],
|
||||
17 => [6, 30, 54, 78],
|
||||
18 => [6, 30, 56, 82],
|
||||
19 => [6, 30, 58, 86],
|
||||
20 => [6, 34, 62, 90],
|
||||
21 => [6, 28, 50, 72, 94],
|
||||
22 => [6, 26, 50, 74, 98],
|
||||
23 => [6, 30, 54, 78, 102],
|
||||
24 => [6, 28, 54, 80, 106],
|
||||
25 => [6, 32, 58, 84, 110],
|
||||
26 => [6, 30, 58, 86, 114],
|
||||
27 => [6, 34, 62, 90, 118],
|
||||
28 => [6, 26, 50, 74, 98, 122],
|
||||
29 => [6, 30, 54, 78, 102, 126],
|
||||
30 => [6, 26, 52, 78, 104, 130],
|
||||
31 => [6, 30, 56, 82, 108, 134],
|
||||
32 => [6, 34, 60, 86, 112, 138],
|
||||
33 => [6, 30, 58, 86, 114, 142],
|
||||
34 => [6, 34, 62, 90, 118, 146],
|
||||
35 => [6, 30, 54, 78, 102, 126, 150],
|
||||
36 => [6, 24, 50, 76, 102, 128, 154],
|
||||
37 => [6, 28, 54, 80, 106, 132, 158],
|
||||
38 => [6, 32, 58, 84, 110, 136, 162],
|
||||
39 => [6, 26, 54, 82, 110, 138, 166],
|
||||
40 => [6, 30, 58, 86, 114, 142, 170],
|
||||
];
|
||||
|
||||
/**
|
||||
* ISO/IEC 18004:2000 Annex D, Table D.1 - Version information bit stream for each version
|
||||
*
|
||||
* no version pattern for QR Codes < 7
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
protected const versionPattern = [
|
||||
7 => 0b000111110010010100,
|
||||
8 => 0b001000010110111100,
|
||||
9 => 0b001001101010011001,
|
||||
10 => 0b001010010011010011,
|
||||
11 => 0b001011101111110110,
|
||||
12 => 0b001100011101100010,
|
||||
13 => 0b001101100001000111,
|
||||
14 => 0b001110011000001101,
|
||||
15 => 0b001111100100101000,
|
||||
16 => 0b010000101101111000,
|
||||
17 => 0b010001010001011101,
|
||||
18 => 0b010010101000010111,
|
||||
19 => 0b010011010100110010,
|
||||
20 => 0b010100100110100110,
|
||||
21 => 0b010101011010000011,
|
||||
22 => 0b010110100011001001,
|
||||
23 => 0b010111011111101100,
|
||||
24 => 0b011000111011000100,
|
||||
25 => 0b011001000111100001,
|
||||
26 => 0b011010111110101011,
|
||||
27 => 0b011011000010001110,
|
||||
28 => 0b011100110000011010,
|
||||
29 => 0b011101001100111111,
|
||||
30 => 0b011110110101110101,
|
||||
31 => 0b011111001001010000,
|
||||
32 => 0b100000100111010101,
|
||||
33 => 0b100001011011110000,
|
||||
34 => 0b100010100010111010,
|
||||
35 => 0b100011011110011111,
|
||||
36 => 0b100100101100001011,
|
||||
37 => 0b100101010000101110,
|
||||
38 => 0b100110101001100100,
|
||||
39 => 0b100111010101000001,
|
||||
40 => 0b101000110001101001,
|
||||
];
|
||||
|
||||
/**
|
||||
* ISO/IEC 18004:2000 Section 8.9 - Format Information
|
||||
*
|
||||
* ECC level -> mask pattern
|
||||
*
|
||||
* @var int[][]
|
||||
*/
|
||||
protected const formatPattern = [
|
||||
[ // L
|
||||
0b111011111000100,
|
||||
0b111001011110011,
|
||||
0b111110110101010,
|
||||
0b111100010011101,
|
||||
0b110011000101111,
|
||||
0b110001100011000,
|
||||
0b110110001000001,
|
||||
0b110100101110110,
|
||||
],
|
||||
[ // M
|
||||
0b101010000010010,
|
||||
0b101000100100101,
|
||||
0b101111001111100,
|
||||
0b101101101001011,
|
||||
0b100010111111001,
|
||||
0b100000011001110,
|
||||
0b100111110010111,
|
||||
0b100101010100000,
|
||||
],
|
||||
[ // Q
|
||||
0b011010101011111,
|
||||
0b011000001101000,
|
||||
0b011111100110001,
|
||||
0b011101000000110,
|
||||
0b010010010110100,
|
||||
0b010000110000011,
|
||||
0b010111011011010,
|
||||
0b010101111101101,
|
||||
],
|
||||
[ // H
|
||||
0b001011010001001,
|
||||
0b001001110111110,
|
||||
0b001110011100111,
|
||||
0b001100111010000,
|
||||
0b000011101100010,
|
||||
0b000001001010101,
|
||||
0b000110100001100,
|
||||
0b000100000111011,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* the current QR Code version number
|
||||
*/
|
||||
protected int $version;
|
||||
|
||||
/**
|
||||
* the current ECC level
|
||||
*/
|
||||
protected int $eclevel;
|
||||
|
||||
/**
|
||||
* the used mask pattern, set via QRMatrix::mapData()
|
||||
*/
|
||||
protected int $maskPattern = QRCode::MASK_PATTERN_AUTO;
|
||||
|
||||
/**
|
||||
* the size (side length) of the matrix
|
||||
*/
|
||||
protected int $moduleCount;
|
||||
|
||||
/**
|
||||
* the actual matrix data array
|
||||
*
|
||||
* @var int[][]
|
||||
*/
|
||||
protected array $matrix;
|
||||
|
||||
/**
|
||||
* QRMatrix constructor.
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
*/
|
||||
public function __construct(int $version, int $eclevel){
|
||||
|
||||
if(!in_array($version, range(1, 40), true)){
|
||||
throw new QRCodeDataException('invalid QR Code version');
|
||||
}
|
||||
|
||||
if(!array_key_exists($eclevel, QRCode::ECC_MODES)){
|
||||
throw new QRCodeDataException('invalid ecc level');
|
||||
}
|
||||
|
||||
$this->version = $version;
|
||||
$this->eclevel = $eclevel;
|
||||
$this->moduleCount = $this->version * 4 + 17;
|
||||
$this->matrix = array_fill(0, $this->moduleCount, array_fill(0, $this->moduleCount, $this::M_NULL));
|
||||
}
|
||||
|
||||
/**
|
||||
* shortcut to initialize the matrix
|
||||
*/
|
||||
public function init(int $maskPattern, bool $test = null):QRMatrix{
|
||||
return $this
|
||||
->setFinderPattern()
|
||||
->setSeparators()
|
||||
->setAlignmentPattern()
|
||||
->setTimingPattern()
|
||||
->setVersionNumber($test)
|
||||
->setFormatInfo($maskPattern, $test)
|
||||
->setDarkModule()
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the data matrix, returns a pure boolean representation if $boolean is set to true
|
||||
*
|
||||
* @return int[][]|bool[][]
|
||||
*/
|
||||
public function matrix(bool $boolean = false):array{
|
||||
|
||||
if(!$boolean){
|
||||
return $this->matrix;
|
||||
}
|
||||
|
||||
$matrix = [];
|
||||
|
||||
foreach($this->matrix as $y => $row){
|
||||
$matrix[$y] = [];
|
||||
|
||||
foreach($row as $x => $val){
|
||||
$matrix[$y][$x] = ($val >> 8) > 0;
|
||||
}
|
||||
}
|
||||
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current version number
|
||||
*/
|
||||
public function version():int{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current ECC level
|
||||
*/
|
||||
public function eccLevel():int{
|
||||
return $this->eclevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current mask pattern
|
||||
*/
|
||||
public function maskPattern():int{
|
||||
return $this->maskPattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absoulute size of the matrix, including quiet zone (after setting it).
|
||||
*
|
||||
* size = version * 4 + 17 [ + 2 * quietzone size]
|
||||
*/
|
||||
public function size():int{
|
||||
return $this->moduleCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the module at position [$x, $y]
|
||||
*/
|
||||
public function get(int $x, int $y):int{
|
||||
return $this->matrix[$y][$x];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the $M_TYPE value for the module at position [$x, $y]
|
||||
*
|
||||
* true => $M_TYPE << 8
|
||||
* false => $M_TYPE
|
||||
*/
|
||||
public function set(int $x, int $y, bool $value, int $M_TYPE):QRMatrix{
|
||||
$this->matrix[$y][$x] = $M_TYPE << ($value ? 8 : 0);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a module is true (dark) or false (light)
|
||||
*
|
||||
* true => $value >> 8 === $M_TYPE
|
||||
* $value >> 8 > 0
|
||||
*
|
||||
* false => $value === $M_TYPE
|
||||
* $value >> 8 === 0
|
||||
*/
|
||||
public function check(int $x, int $y):bool{
|
||||
return ($this->matrix[$y][$x] >> 8) > 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the "dark module", that is always on the same position 1x1px away from the bottom left finder
|
||||
*/
|
||||
public function setDarkModule():QRMatrix{
|
||||
$this->set(8, 4 * $this->version + 9, true, $this::M_DARKMODULE);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the 7x7 finder patterns in the corners top left/right and bottom left
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 7.3.2
|
||||
*/
|
||||
public function setFinderPattern():QRMatrix{
|
||||
|
||||
$pos = [
|
||||
[0, 0], // top left
|
||||
[$this->moduleCount - 7, 0], // bottom left
|
||||
[0, $this->moduleCount - 7], // top right
|
||||
];
|
||||
|
||||
foreach($pos as $c){
|
||||
for($y = 0; $y < 7; $y++){
|
||||
for($x = 0; $x < 7; $x++){
|
||||
// outer (dark) 7*7 square
|
||||
if($x === 0 || $x === 6 || $y === 0 || $y === 6){
|
||||
$this->set($c[0] + $y, $c[1] + $x, true, $this::M_FINDER);
|
||||
}
|
||||
// inner (light) 5*5 square
|
||||
elseif($x === 1 || $x === 5 || $y === 1 || $y === 5){
|
||||
$this->set($c[0] + $y, $c[1] + $x, false, $this::M_FINDER);
|
||||
}
|
||||
// 3*3 dot
|
||||
else{
|
||||
$this->set($c[0] + $y, $c[1] + $x, true, $this::M_FINDER_DOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the separator lines around the finder patterns
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 7.3.3
|
||||
*/
|
||||
public function setSeparators():QRMatrix{
|
||||
|
||||
$h = [
|
||||
[7, 0],
|
||||
[$this->moduleCount - 8, 0],
|
||||
[7, $this->moduleCount - 8],
|
||||
];
|
||||
|
||||
$v = [
|
||||
[7, 7],
|
||||
[$this->moduleCount - 1, 7],
|
||||
[7, $this->moduleCount - 8],
|
||||
];
|
||||
|
||||
for($c = 0; $c < 3; $c++){
|
||||
for($i = 0; $i < 8; $i++){
|
||||
$this->set($h[$c][0] , $h[$c][1] + $i, false, $this::M_SEPARATOR);
|
||||
$this->set($v[$c][0] - $i, $v[$c][1] , false, $this::M_SEPARATOR);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draws the 5x5 alignment patterns
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 7.3.5
|
||||
*/
|
||||
public function setAlignmentPattern():QRMatrix{
|
||||
|
||||
foreach($this::alignmentPattern[$this->version] as $y){
|
||||
foreach($this::alignmentPattern[$this->version] as $x){
|
||||
|
||||
// skip existing patterns
|
||||
if($this->matrix[$y][$x] !== $this::M_NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
for($ry = -2; $ry <= 2; $ry++){
|
||||
for($rx = -2; $rx <= 2; $rx++){
|
||||
$v = ($ry === 0 && $rx === 0) || $ry === 2 || $ry === -2 || $rx === 2 || $rx === -2;
|
||||
|
||||
$this->set($x + $rx, $y + $ry, $v, $this::M_ALIGNMENT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Draws the timing pattern (h/v checkered line between the finder patterns)
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 7.3.4
|
||||
*/
|
||||
public function setTimingPattern():QRMatrix{
|
||||
|
||||
foreach(range(8, $this->moduleCount - 8 - 1) as $i){
|
||||
|
||||
if($this->matrix[6][$i] !== $this::M_NULL || $this->matrix[$i][6] !== $this::M_NULL){
|
||||
continue;
|
||||
}
|
||||
|
||||
$v = $i % 2 === 0;
|
||||
|
||||
$this->set($i, 6, $v, $this::M_TIMING); // h
|
||||
$this->set(6, $i, $v, $this::M_TIMING); // v
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the version information, 2x 3x6 pixel
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.10
|
||||
*/
|
||||
public function setVersionNumber(bool $test = null):QRMatrix{
|
||||
$bits = $this::versionPattern[$this->version] ?? false;
|
||||
|
||||
if($bits !== false){
|
||||
|
||||
for($i = 0; $i < 18; $i++){
|
||||
$a = (int)floor($i / 3);
|
||||
$b = $i % 3 + $this->moduleCount - 8 - 3;
|
||||
$v = !$test && (($bits >> $i) & 1) === 1;
|
||||
|
||||
$this->set($b, $a, $v, $this::M_VERSION); // ne
|
||||
$this->set($a, $b, $v, $this::M_VERSION); // sw
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the format info along the finder patterns
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 8.9
|
||||
*/
|
||||
public function setFormatInfo(int $maskPattern, bool $test = null):QRMatrix{
|
||||
$bits = $this::formatPattern[QRCode::ECC_MODES[$this->eclevel]][$maskPattern] ?? 0;
|
||||
|
||||
for($i = 0; $i < 15; $i++){
|
||||
$v = !$test && (($bits >> $i) & 1) === 1;
|
||||
|
||||
if($i < 6){
|
||||
$this->set(8, $i, $v, $this::M_FORMAT);
|
||||
}
|
||||
elseif($i < 8){
|
||||
$this->set(8, $i + 1, $v, $this::M_FORMAT);
|
||||
}
|
||||
else{
|
||||
$this->set(8, $this->moduleCount - 15 + $i, $v, $this::M_FORMAT);
|
||||
}
|
||||
|
||||
if($i < 8){
|
||||
$this->set($this->moduleCount - $i - 1, 8, $v, $this::M_FORMAT);
|
||||
}
|
||||
elseif($i < 9){
|
||||
$this->set(15 - $i, 8, $v, $this::M_FORMAT);
|
||||
}
|
||||
else{
|
||||
$this->set(15 - $i - 1, 8, $v, $this::M_FORMAT);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->set(8, $this->moduleCount - 8, !$test, $this::M_FORMAT);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the "quiet zone" of $size around the matrix
|
||||
*
|
||||
* ISO/IEC 18004:2000 Section 7.3.7
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
*/
|
||||
public function setQuietZone(int $size = null):QRMatrix{
|
||||
|
||||
if($this->matrix[$this->moduleCount - 1][$this->moduleCount - 1] === $this::M_NULL){
|
||||
throw new QRCodeDataException('use only after writing data');
|
||||
}
|
||||
|
||||
$size = $size !== null
|
||||
? max(0, min($size, floor($this->moduleCount / 2)))
|
||||
: 4;
|
||||
|
||||
for($y = 0; $y < $this->moduleCount; $y++){
|
||||
for($i = 0; $i < $size; $i++){
|
||||
array_unshift($this->matrix[$y], $this::M_QUIETZONE);
|
||||
array_push($this->matrix[$y], $this::M_QUIETZONE);
|
||||
}
|
||||
}
|
||||
|
||||
$this->moduleCount += ($size * 2);
|
||||
|
||||
$r = array_fill(0, $this->moduleCount, $this::M_QUIETZONE);
|
||||
|
||||
for($i = 0; $i < $size; $i++){
|
||||
array_unshift($this->matrix, $r);
|
||||
array_push($this->matrix, $r);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears a space of $width * $height in order to add a logo or text.
|
||||
*
|
||||
* Additionally, the logo space can be positioned within the QR Code - respecting the main functional patterns -
|
||||
* using $startX and $startY. If either of these are null, the logo space will be centered in that direction.
|
||||
* ECC level "H" (30%) is required.
|
||||
*
|
||||
* Please note that adding a logo space minimizes the error correction capacity of the QR Code and
|
||||
* created images may become unreadable, especially when printed with a chance to receive damage.
|
||||
* Please test thoroughly before using this feature in production.
|
||||
*
|
||||
* This method should be called from within an output module (after the matrix has been filled with data).
|
||||
* Note that there is no restiction on how many times this method could be called on the same matrix instance.
|
||||
*
|
||||
* @link https://github.com/chillerlan/php-qrcode/issues/52
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
*/
|
||||
public function setLogoSpace(int $width, int $height, int $startX = null, int $startY = null):QRMatrix{
|
||||
|
||||
// for logos we operate in ECC H (30%) only
|
||||
if($this->eclevel !== QRCode::ECC_H){
|
||||
throw new QRCodeDataException('ECC level "H" required to add logo space');
|
||||
}
|
||||
|
||||
// we need uneven sizes to center the logo space, adjust if needed
|
||||
if($startX === null && ($width % 2) === 0){
|
||||
$width++;
|
||||
}
|
||||
|
||||
if($startY === null && ($height % 2) === 0){
|
||||
$height++;
|
||||
}
|
||||
|
||||
// $this->moduleCount includes the quiet zone (if created), we need the QR size here
|
||||
$length = $this->version * 4 + 17;
|
||||
|
||||
// throw if the logo space exceeds the maximum error correction capacity
|
||||
if($width * $height > floor($length * $length * 0.2)){
|
||||
throw new QRCodeDataException('logo space exceeds the maximum error correction capacity');
|
||||
}
|
||||
|
||||
// quiet zone size
|
||||
$qz = ($this->moduleCount - $length) / 2;
|
||||
// skip quiet zone and the first 9 rows/columns (finder-, mode-, version- and timing patterns)
|
||||
$start = $qz + 9;
|
||||
// skip quiet zone
|
||||
$end = $this->moduleCount - $qz;
|
||||
|
||||
// determine start coordinates
|
||||
$startX = ($startX !== null ? $startX : ($length - $width) / 2) + $qz;
|
||||
$startY = ($startY !== null ? $startY : ($length - $height) / 2) + $qz;
|
||||
|
||||
// clear the space
|
||||
foreach($this->matrix as $y => $row){
|
||||
foreach($row as $x => $val){
|
||||
// out of bounds, skip
|
||||
if($x < $start || $y < $start ||$x >= $end || $y >= $end){
|
||||
continue;
|
||||
}
|
||||
// a match
|
||||
if($x >= $startX && $x < ($startX + $width) && $y >= $startY && $y < ($startY + $height)){
|
||||
$this->set($x, $y, false, $this::M_LOGO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps the binary $data array from QRDataInterface::maskECC() on the matrix,
|
||||
* masking the data using $maskPattern (ISO/IEC 18004:2000 Section 8.8)
|
||||
*
|
||||
* @see \chillerlan\QRCode\Data\QRDataAbstract::maskECC()
|
||||
*
|
||||
* @param int[] $data
|
||||
* @param int $maskPattern
|
||||
*
|
||||
* @return \chillerlan\QRCode\Data\QRMatrix
|
||||
*/
|
||||
public function mapData(array $data, int $maskPattern):QRMatrix{
|
||||
$this->maskPattern = $maskPattern;
|
||||
$byteCount = count($data);
|
||||
$y = $this->moduleCount - 1;
|
||||
$inc = -1;
|
||||
$byteIndex = 0;
|
||||
$bitIndex = 7;
|
||||
$mask = $this->getMask($this->maskPattern);
|
||||
|
||||
for($i = $y; $i > 0; $i -= 2){
|
||||
|
||||
if($i === 6){
|
||||
$i--;
|
||||
}
|
||||
|
||||
while(true){
|
||||
for($c = 0; $c < 2; $c++){
|
||||
$x = $i - $c;
|
||||
|
||||
if($this->matrix[$y][$x] === $this::M_NULL){
|
||||
$v = false;
|
||||
|
||||
if($byteIndex < $byteCount){
|
||||
$v = (($data[$byteIndex] >> $bitIndex) & 1) === 1;
|
||||
}
|
||||
|
||||
if($mask($x, $y) === 0){
|
||||
$v = !$v;
|
||||
}
|
||||
|
||||
$this->matrix[$y][$x] = $this::M_DATA << ($v ? 8 : 0);
|
||||
$bitIndex--;
|
||||
|
||||
if($bitIndex === -1){
|
||||
$byteIndex++;
|
||||
$bitIndex = 7;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$y += $inc;
|
||||
|
||||
if($y < 0 || $this->moduleCount <= $y){
|
||||
$y -= $inc;
|
||||
$inc = -$inc;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* ISO/IEC 18004:2000 Section 8.8.1
|
||||
*
|
||||
* Note that some versions of the QR code standard have had errors in the section about mask patterns.
|
||||
* The information below has been corrected. (https://www.thonky.com/qr-code-tutorial/mask-patterns)
|
||||
*
|
||||
* @see \chillerlan\QRCode\QRMatrix::mapData()
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
*/
|
||||
protected function getMask(int $maskPattern):Closure{
|
||||
|
||||
if((0b111 & $maskPattern) !== $maskPattern){
|
||||
throw new QRCodeDataException('invalid mask pattern'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
return [
|
||||
0b000 => fn($x, $y):int => ($x + $y) % 2,
|
||||
0b001 => fn($x, $y):int => $y % 2,
|
||||
0b010 => fn($x, $y):int => $x % 3,
|
||||
0b011 => fn($x, $y):int => ($x + $y) % 3,
|
||||
0b100 => fn($x, $y):int => ((int)($y / 2) + (int)($x / 3)) % 2,
|
||||
0b101 => fn($x, $y):int => (($x * $y) % 2) + (($x * $y) % 3),
|
||||
0b110 => fn($x, $y):int => ((($x * $y) % 2) + (($x * $y) % 3)) % 2,
|
||||
0b111 => fn($x, $y):int => ((($x * $y) % 3) + (($x + $y) % 2)) % 2,
|
||||
][$maskPattern];
|
||||
}
|
||||
|
||||
}
|
||||
89
vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php
vendored
Normal file
89
vendor/chillerlan/php-qrcode/src/Helpers/BitBuffer.php
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
/**
|
||||
* Class BitBuffer
|
||||
*
|
||||
* @filesource BitBuffer.php
|
||||
* @created 25.11.2015
|
||||
* @package chillerlan\QRCode\Helpers
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Helpers;
|
||||
|
||||
use function count, floor;
|
||||
|
||||
/**
|
||||
* Holds the raw binary data
|
||||
*/
|
||||
final class BitBuffer{
|
||||
|
||||
/**
|
||||
* The buffer content
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
protected array $buffer = [];
|
||||
|
||||
/**
|
||||
* Length of the content (bits)
|
||||
*/
|
||||
protected int $length = 0;
|
||||
|
||||
/**
|
||||
* clears the buffer
|
||||
*/
|
||||
public function clear():BitBuffer{
|
||||
$this->buffer = [];
|
||||
$this->length = 0;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* appends a sequence of bits
|
||||
*/
|
||||
public function put(int $num, int $length):BitBuffer{
|
||||
|
||||
for($i = 0; $i < $length; $i++){
|
||||
$this->putBit((($num >> ($length - $i - 1)) & 1) === 1);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* appends a single bit
|
||||
*/
|
||||
public function putBit(bool $bit):BitBuffer{
|
||||
$bufIndex = floor($this->length / 8);
|
||||
|
||||
if(count($this->buffer) <= $bufIndex){
|
||||
$this->buffer[] = 0;
|
||||
}
|
||||
|
||||
if($bit === true){
|
||||
$this->buffer[(int)$bufIndex] |= (0x80 >> ($this->length % 8));
|
||||
}
|
||||
|
||||
$this->length++;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the current buffer length
|
||||
*/
|
||||
public function getLength():int{
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the buffer content
|
||||
*/
|
||||
public function getBuffer():array{
|
||||
return $this->buffer;
|
||||
}
|
||||
|
||||
}
|
||||
178
vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php
vendored
Normal file
178
vendor/chillerlan/php-qrcode/src/Helpers/Polynomial.php
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
/**
|
||||
* Class Polynomial
|
||||
*
|
||||
* @filesource Polynomial.php
|
||||
* @created 25.11.2015
|
||||
* @package chillerlan\QRCode\Helpers
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Helpers;
|
||||
|
||||
use chillerlan\QRCode\QRCodeException;
|
||||
|
||||
use function array_fill, count, sprintf;
|
||||
|
||||
/**
|
||||
* Polynomial long division helpers
|
||||
*
|
||||
* @see http://www.thonky.com/qr-code-tutorial/error-correction-coding
|
||||
*/
|
||||
final class Polynomial{
|
||||
|
||||
/**
|
||||
* @see http://www.thonky.com/qr-code-tutorial/log-antilog-table
|
||||
*/
|
||||
protected const table = [
|
||||
[ 1, 0], [ 2, 0], [ 4, 1], [ 8, 25], [ 16, 2], [ 32, 50], [ 64, 26], [128, 198],
|
||||
[ 29, 3], [ 58, 223], [116, 51], [232, 238], [205, 27], [135, 104], [ 19, 199], [ 38, 75],
|
||||
[ 76, 4], [152, 100], [ 45, 224], [ 90, 14], [180, 52], [117, 141], [234, 239], [201, 129],
|
||||
[143, 28], [ 3, 193], [ 6, 105], [ 12, 248], [ 24, 200], [ 48, 8], [ 96, 76], [192, 113],
|
||||
[157, 5], [ 39, 138], [ 78, 101], [156, 47], [ 37, 225], [ 74, 36], [148, 15], [ 53, 33],
|
||||
[106, 53], [212, 147], [181, 142], [119, 218], [238, 240], [193, 18], [159, 130], [ 35, 69],
|
||||
[ 70, 29], [140, 181], [ 5, 194], [ 10, 125], [ 20, 106], [ 40, 39], [ 80, 249], [160, 185],
|
||||
[ 93, 201], [186, 154], [105, 9], [210, 120], [185, 77], [111, 228], [222, 114], [161, 166],
|
||||
[ 95, 6], [190, 191], [ 97, 139], [194, 98], [153, 102], [ 47, 221], [ 94, 48], [188, 253],
|
||||
[101, 226], [202, 152], [137, 37], [ 15, 179], [ 30, 16], [ 60, 145], [120, 34], [240, 136],
|
||||
[253, 54], [231, 208], [211, 148], [187, 206], [107, 143], [214, 150], [177, 219], [127, 189],
|
||||
[254, 241], [225, 210], [223, 19], [163, 92], [ 91, 131], [182, 56], [113, 70], [226, 64],
|
||||
[217, 30], [175, 66], [ 67, 182], [134, 163], [ 17, 195], [ 34, 72], [ 68, 126], [136, 110],
|
||||
[ 13, 107], [ 26, 58], [ 52, 40], [104, 84], [208, 250], [189, 133], [103, 186], [206, 61],
|
||||
[129, 202], [ 31, 94], [ 62, 155], [124, 159], [248, 10], [237, 21], [199, 121], [147, 43],
|
||||
[ 59, 78], [118, 212], [236, 229], [197, 172], [151, 115], [ 51, 243], [102, 167], [204, 87],
|
||||
[133, 7], [ 23, 112], [ 46, 192], [ 92, 247], [184, 140], [109, 128], [218, 99], [169, 13],
|
||||
[ 79, 103], [158, 74], [ 33, 222], [ 66, 237], [132, 49], [ 21, 197], [ 42, 254], [ 84, 24],
|
||||
[168, 227], [ 77, 165], [154, 153], [ 41, 119], [ 82, 38], [164, 184], [ 85, 180], [170, 124],
|
||||
[ 73, 17], [146, 68], [ 57, 146], [114, 217], [228, 35], [213, 32], [183, 137], [115, 46],
|
||||
[230, 55], [209, 63], [191, 209], [ 99, 91], [198, 149], [145, 188], [ 63, 207], [126, 205],
|
||||
[252, 144], [229, 135], [215, 151], [179, 178], [123, 220], [246, 252], [241, 190], [255, 97],
|
||||
[227, 242], [219, 86], [171, 211], [ 75, 171], [150, 20], [ 49, 42], [ 98, 93], [196, 158],
|
||||
[149, 132], [ 55, 60], [110, 57], [220, 83], [165, 71], [ 87, 109], [174, 65], [ 65, 162],
|
||||
[130, 31], [ 25, 45], [ 50, 67], [100, 216], [200, 183], [141, 123], [ 7, 164], [ 14, 118],
|
||||
[ 28, 196], [ 56, 23], [112, 73], [224, 236], [221, 127], [167, 12], [ 83, 111], [166, 246],
|
||||
[ 81, 108], [162, 161], [ 89, 59], [178, 82], [121, 41], [242, 157], [249, 85], [239, 170],
|
||||
[195, 251], [155, 96], [ 43, 134], [ 86, 177], [172, 187], [ 69, 204], [138, 62], [ 9, 90],
|
||||
[ 18, 203], [ 36, 89], [ 72, 95], [144, 176], [ 61, 156], [122, 169], [244, 160], [245, 81],
|
||||
[247, 11], [243, 245], [251, 22], [235, 235], [203, 122], [139, 117], [ 11, 44], [ 22, 215],
|
||||
[ 44, 79], [ 88, 174], [176, 213], [125, 233], [250, 230], [233, 231], [207, 173], [131, 232],
|
||||
[ 27, 116], [ 54, 214], [108, 244], [216, 234], [173, 168], [ 71, 80], [142, 88], [ 1, 175],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var int[]
|
||||
*/
|
||||
protected array $num = [];
|
||||
|
||||
/**
|
||||
* Polynomial constructor.
|
||||
*/
|
||||
public function __construct(array $num = null, int $shift = null){
|
||||
$this->setNum($num ?? [1], $shift);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function getNum():array{
|
||||
return $this->num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $num
|
||||
* @param int|null $shift
|
||||
*
|
||||
* @return \chillerlan\QRCode\Helpers\Polynomial
|
||||
*/
|
||||
public function setNum(array $num, int $shift = null):Polynomial{
|
||||
$offset = 0;
|
||||
$numCount = count($num);
|
||||
|
||||
while($offset < $numCount && $num[$offset] === 0){
|
||||
$offset++;
|
||||
}
|
||||
|
||||
$this->num = array_fill(0, $numCount - $offset + ($shift ?? 0), 0);
|
||||
|
||||
for($i = 0; $i < $numCount - $offset; $i++){
|
||||
$this->num[$i] = $num[$i + $offset];
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $e
|
||||
*
|
||||
* @return \chillerlan\QRCode\Helpers\Polynomial
|
||||
*/
|
||||
public function multiply(array $e):Polynomial{
|
||||
$n = array_fill(0, count($this->num) + count($e) - 1, 0);
|
||||
|
||||
foreach($this->num as $i => $vi){
|
||||
$vi = $this->glog($vi);
|
||||
|
||||
foreach($e as $j => $vj){
|
||||
$n[$i + $j] ^= $this->gexp($vi + $this->glog($vj));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->setNum($n);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int[] $e
|
||||
*
|
||||
* @return \chillerlan\QRCode\Helpers\Polynomial
|
||||
*/
|
||||
public function mod(array $e):Polynomial{
|
||||
$n = $this->num;
|
||||
|
||||
if(count($n) - count($e) < 0){
|
||||
return $this;
|
||||
}
|
||||
|
||||
$ratio = $this->glog($n[0]) - $this->glog($e[0]);
|
||||
|
||||
foreach($e as $i => $v){
|
||||
$n[$i] ^= $this->gexp($this->glog($v) + $ratio);
|
||||
}
|
||||
|
||||
$this->setNum($n)->mod($e);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \chillerlan\QRCode\QRCodeException
|
||||
*/
|
||||
public function glog(int $n):int{
|
||||
|
||||
if($n < 1){
|
||||
throw new QRCodeException(sprintf('log(%s)', $n));
|
||||
}
|
||||
|
||||
return Polynomial::table[$n][1];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function gexp(int $n):int{
|
||||
|
||||
if($n < 0){
|
||||
$n += 255;
|
||||
}
|
||||
elseif($n >= 256){
|
||||
$n -= 255;
|
||||
}
|
||||
|
||||
return Polynomial::table[$n][0];
|
||||
}
|
||||
|
||||
}
|
||||
17
vendor/chillerlan/php-qrcode/src/Output/QRCodeOutputException.php
vendored
Normal file
17
vendor/chillerlan/php-qrcode/src/Output/QRCodeOutputException.php
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRCodeOutputException
|
||||
*
|
||||
* @filesource QRCodeOutputException.php
|
||||
* @created 09.12.2015
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\QRCodeException;
|
||||
|
||||
class QRCodeOutputException extends QRCodeException{}
|
||||
113
vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php
vendored
Normal file
113
vendor/chillerlan/php-qrcode/src/Output/QRFpdf.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRFpdf
|
||||
*
|
||||
* https://github.com/chillerlan/php-qrcode/pull/49
|
||||
*
|
||||
* @filesource QRFpdf.php
|
||||
* @created 03.06.2020
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author Maximilian Kresse
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\QRCodeException;
|
||||
use chillerlan\Settings\SettingsContainerInterface;
|
||||
use FPDF;
|
||||
|
||||
use function array_values, class_exists, count, is_array;
|
||||
|
||||
/**
|
||||
* QRFpdf output module (requires fpdf)
|
||||
*
|
||||
* @see https://github.com/Setasign/FPDF
|
||||
* @see http://www.fpdf.org/
|
||||
*/
|
||||
class QRFpdf extends QROutputAbstract{
|
||||
|
||||
public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
|
||||
|
||||
if(!class_exists(FPDF::class)){
|
||||
// @codeCoverageIgnoreStart
|
||||
throw new QRCodeException(
|
||||
'The QRFpdf output requires FPDF as dependency but the class "\FPDF" couldn\'t be found.'
|
||||
);
|
||||
// @codeCoverageIgnoreEnd
|
||||
}
|
||||
|
||||
parent::__construct($options, $matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setModuleValues():void{
|
||||
|
||||
foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
|
||||
$v = $this->options->moduleValues[$M_TYPE] ?? null;
|
||||
|
||||
if(!is_array($v) || count($v) < 3){
|
||||
$this->moduleValues[$M_TYPE] = $defaultValue
|
||||
? [0, 0, 0]
|
||||
: [255, 255, 255];
|
||||
}
|
||||
else{
|
||||
$this->moduleValues[$M_TYPE] = array_values($v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @return string|\FPDF
|
||||
*/
|
||||
public function dump(string $file = null){
|
||||
$file ??= $this->options->cachefile;
|
||||
|
||||
$fpdf = new FPDF('P', $this->options->fpdfMeasureUnit, [$this->length, $this->length]);
|
||||
$fpdf->AddPage();
|
||||
|
||||
$prevColor = null;
|
||||
|
||||
foreach($this->matrix->matrix() as $y => $row){
|
||||
|
||||
foreach($row as $x => $M_TYPE){
|
||||
/** @var int $M_TYPE */
|
||||
$color = $this->moduleValues[$M_TYPE];
|
||||
|
||||
if($prevColor === null || $prevColor !== $color){
|
||||
/** @phan-suppress-next-line PhanParamTooFewUnpack */
|
||||
$fpdf->SetFillColor(...$color);
|
||||
$prevColor = $color;
|
||||
}
|
||||
|
||||
$fpdf->Rect($x * $this->scale, $y * $this->scale, 1 * $this->scale, 1 * $this->scale, 'F');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if($this->options->returnResource){
|
||||
return $fpdf;
|
||||
}
|
||||
|
||||
$pdfData = $fpdf->Output('S');
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($pdfData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$pdfData = sprintf('data:application/pdf;base64,%s', base64_encode($pdfData));
|
||||
}
|
||||
|
||||
return $pdfData;
|
||||
}
|
||||
|
||||
}
|
||||
217
vendor/chillerlan/php-qrcode/src/Output/QRImage.php
vendored
Normal file
217
vendor/chillerlan/php-qrcode/src/Output/QRImage.php
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRImage
|
||||
*
|
||||
* @filesource QRImage.php
|
||||
* @created 05.12.2015
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\{QRCode, QRCodeException};
|
||||
use chillerlan\Settings\SettingsContainerInterface;
|
||||
use Exception;
|
||||
|
||||
use function array_values, base64_encode, call_user_func, count, extension_loaded, imagecolorallocate, imagecolortransparent,
|
||||
imagecreatetruecolor, imagedestroy, imagefilledrectangle, imagegif, imagejpeg, imagepng, in_array,
|
||||
is_array, ob_end_clean, ob_get_contents, ob_start, range, sprintf;
|
||||
|
||||
/**
|
||||
* Converts the matrix into GD images, raw or base64 output (requires ext-gd)
|
||||
*
|
||||
* @see http://php.net/manual/book.image.php
|
||||
*/
|
||||
class QRImage extends QROutputAbstract{
|
||||
|
||||
/**
|
||||
* GD image types that support transparency
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected const TRANSPARENCY_TYPES = [
|
||||
QRCode::OUTPUT_IMAGE_PNG,
|
||||
QRCode::OUTPUT_IMAGE_GIF,
|
||||
];
|
||||
|
||||
protected string $defaultMode = QRCode::OUTPUT_IMAGE_PNG;
|
||||
|
||||
/**
|
||||
* The GD image resource
|
||||
*
|
||||
* @see imagecreatetruecolor()
|
||||
* @var resource|\GdImage
|
||||
*
|
||||
* @phan-suppress PhanUndeclaredTypeProperty
|
||||
*/
|
||||
protected $image;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @throws \chillerlan\QRCode\QRCodeException
|
||||
*/
|
||||
public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
|
||||
|
||||
if(!extension_loaded('gd')){
|
||||
throw new QRCodeException('ext-gd not loaded'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
parent::__construct($options, $matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setModuleValues():void{
|
||||
|
||||
foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
|
||||
$v = $this->options->moduleValues[$M_TYPE] ?? null;
|
||||
|
||||
if(!is_array($v) || count($v) < 3){
|
||||
$this->moduleValues[$M_TYPE] = $defaultValue
|
||||
? [0, 0, 0]
|
||||
: [255, 255, 255];
|
||||
}
|
||||
else{
|
||||
$this->moduleValues[$M_TYPE] = array_values($v);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @return string|resource|\GdImage
|
||||
*
|
||||
* @phan-suppress PhanUndeclaredTypeReturnType, PhanTypeMismatchReturn
|
||||
*/
|
||||
public function dump(string $file = null){
|
||||
$file ??= $this->options->cachefile;
|
||||
|
||||
$this->image = imagecreatetruecolor($this->length, $this->length);
|
||||
|
||||
// avoid: Indirect modification of overloaded property $imageTransparencyBG has no effect
|
||||
// https://stackoverflow.com/a/10455217
|
||||
$tbg = $this->options->imageTransparencyBG;
|
||||
/** @phan-suppress-next-line PhanParamTooFewInternalUnpack */
|
||||
$background = imagecolorallocate($this->image, ...$tbg);
|
||||
|
||||
if((bool)$this->options->imageTransparent && in_array($this->options->outputType, $this::TRANSPARENCY_TYPES, true)){
|
||||
imagecolortransparent($this->image, $background);
|
||||
}
|
||||
|
||||
imagefilledrectangle($this->image, 0, 0, $this->length, $this->length, $background);
|
||||
|
||||
foreach($this->matrix->matrix() as $y => $row){
|
||||
foreach($row as $x => $M_TYPE){
|
||||
$this->setPixel($x, $y, $this->moduleValues[$M_TYPE]);
|
||||
}
|
||||
}
|
||||
|
||||
if($this->options->returnResource){
|
||||
return $this->image;
|
||||
}
|
||||
|
||||
$imageData = $this->dumpImage();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$imageData = sprintf('data:image/%s;base64,%s', $this->options->outputType, base64_encode($imageData));
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a single QR pixel with the given settings
|
||||
*/
|
||||
protected function setPixel(int $x, int $y, array $rgb):void{
|
||||
imagefilledrectangle(
|
||||
$this->image,
|
||||
$x * $this->scale,
|
||||
$y * $this->scale,
|
||||
($x + 1) * $this->scale,
|
||||
($y + 1) * $this->scale,
|
||||
/** @phan-suppress-next-line PhanParamTooFewInternalUnpack */
|
||||
imagecolorallocate($this->image, ...$rgb)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the final image by calling the desired GD output function
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
|
||||
*/
|
||||
protected function dumpImage():string{
|
||||
ob_start();
|
||||
|
||||
try{
|
||||
call_user_func([$this, $this->outputMode ?? $this->defaultMode]);
|
||||
}
|
||||
// not going to cover edge cases
|
||||
// @codeCoverageIgnoreStart
|
||||
catch(Exception $e){
|
||||
throw new QRCodeOutputException($e->getMessage());
|
||||
}
|
||||
// @codeCoverageIgnoreEnd
|
||||
|
||||
$imageData = ob_get_contents();
|
||||
imagedestroy($this->image);
|
||||
|
||||
ob_end_clean();
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* PNG output
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function png():void{
|
||||
imagepng(
|
||||
$this->image,
|
||||
null,
|
||||
in_array($this->options->pngCompression, range(-1, 9), true)
|
||||
? $this->options->pngCompression
|
||||
: -1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Jiff - like... JitHub!
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function gif():void{
|
||||
imagegif($this->image);
|
||||
}
|
||||
|
||||
/**
|
||||
* JPG output
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function jpg():void{
|
||||
imagejpeg(
|
||||
$this->image,
|
||||
null,
|
||||
in_array($this->options->jpegQuality, range(0, 100), true)
|
||||
? $this->options->jpegQuality
|
||||
: 85
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
119
vendor/chillerlan/php-qrcode/src/Output/QRImagick.php
vendored
Normal file
119
vendor/chillerlan/php-qrcode/src/Output/QRImagick.php
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRImagick
|
||||
*
|
||||
* @filesource QRImagick.php
|
||||
* @created 04.07.2018
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2018 smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
use chillerlan\QRCode\QRCodeException;
|
||||
use chillerlan\Settings\SettingsContainerInterface;
|
||||
use Imagick, ImagickDraw, ImagickPixel;
|
||||
|
||||
use function extension_loaded, is_string;
|
||||
|
||||
/**
|
||||
* ImageMagick output module (requires ext-imagick)
|
||||
*
|
||||
* @see http://php.net/manual/book.imagick.php
|
||||
* @see http://phpimagick.com
|
||||
*/
|
||||
class QRImagick extends QROutputAbstract{
|
||||
|
||||
protected Imagick $imagick;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
|
||||
|
||||
if(!extension_loaded('imagick')){
|
||||
throw new QRCodeException('ext-imagick not loaded'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
parent::__construct($options, $matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setModuleValues():void{
|
||||
|
||||
foreach($this::DEFAULT_MODULE_VALUES as $type => $defaultValue){
|
||||
$v = $this->options->moduleValues[$type] ?? null;
|
||||
|
||||
if(!is_string($v)){
|
||||
$this->moduleValues[$type] = $defaultValue
|
||||
? new ImagickPixel($this->options->markupDark)
|
||||
: new ImagickPixel($this->options->markupLight);
|
||||
}
|
||||
else{
|
||||
$this->moduleValues[$type] = new ImagickPixel($v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*
|
||||
* @return string|\Imagick
|
||||
*/
|
||||
public function dump(string $file = null){
|
||||
$file ??= $this->options->cachefile;
|
||||
$this->imagick = new Imagick;
|
||||
|
||||
$this->imagick->newImage(
|
||||
$this->length,
|
||||
$this->length,
|
||||
new ImagickPixel($this->options->imagickBG ?? 'transparent'),
|
||||
$this->options->imagickFormat
|
||||
);
|
||||
|
||||
$this->drawImage();
|
||||
|
||||
if($this->options->returnResource){
|
||||
return $this->imagick;
|
||||
}
|
||||
|
||||
$imageData = $this->imagick->getImageBlob();
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($imageData, $file);
|
||||
}
|
||||
|
||||
return $imageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the QR image via ImagickDraw
|
||||
*/
|
||||
protected function drawImage():void{
|
||||
$draw = new ImagickDraw;
|
||||
|
||||
foreach($this->matrix->matrix() as $y => $row){
|
||||
foreach($row as $x => $M_TYPE){
|
||||
$draw->setStrokeColor($this->moduleValues[$M_TYPE]);
|
||||
$draw->setFillColor($this->moduleValues[$M_TYPE]);
|
||||
$draw->rectangle(
|
||||
$x * $this->scale,
|
||||
$y * $this->scale,
|
||||
($x + 1) * $this->scale,
|
||||
($y + 1) * $this->scale
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$this->imagick->drawImage($draw);
|
||||
}
|
||||
|
||||
}
|
||||
160
vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php
vendored
Normal file
160
vendor/chillerlan/php-qrcode/src/Output/QRMarkup.php
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRMarkup
|
||||
*
|
||||
* @filesource QRMarkup.php
|
||||
* @created 17.12.2016
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2016 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
|
||||
use function is_string, sprintf, strip_tags, trim;
|
||||
|
||||
/**
|
||||
* Converts the matrix into markup types: HTML, SVG, ...
|
||||
*/
|
||||
class QRMarkup extends QROutputAbstract{
|
||||
|
||||
protected string $defaultMode = QRCode::OUTPUT_MARKUP_SVG;
|
||||
|
||||
/**
|
||||
* @see \sprintf()
|
||||
*/
|
||||
protected string $svgHeader = '<svg xmlns="http://www.w3.org/2000/svg" class="qr-svg %1$s" '.
|
||||
'style="width: 100%%; height: auto;" viewBox="0 0 %2$d %2$d">';
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setModuleValues():void{
|
||||
|
||||
foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
|
||||
$v = $this->options->moduleValues[$M_TYPE] ?? null;
|
||||
|
||||
if(!is_string($v)){
|
||||
$this->moduleValues[$M_TYPE] = $defaultValue
|
||||
? $this->options->markupDark
|
||||
: $this->options->markupLight;
|
||||
}
|
||||
else{
|
||||
$this->moduleValues[$M_TYPE] = trim(strip_tags($v), '\'"');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* HTML output
|
||||
*/
|
||||
protected function html(string $file = null):string{
|
||||
|
||||
$html = empty($this->options->cssClass)
|
||||
? '<div>'
|
||||
: '<div class="'.$this->options->cssClass.'">';
|
||||
|
||||
$html .= $this->options->eol;
|
||||
|
||||
foreach($this->matrix->matrix() as $row){
|
||||
$html .= '<div>';
|
||||
|
||||
foreach($row as $M_TYPE){
|
||||
$html .= '<span style="background: '.$this->moduleValues[$M_TYPE].';"></span>';
|
||||
}
|
||||
|
||||
$html .= '</div>'.$this->options->eol;
|
||||
}
|
||||
|
||||
$html .= '</div>'.$this->options->eol;
|
||||
|
||||
if($file !== null){
|
||||
return '<!DOCTYPE html>'.
|
||||
'<head><meta charset="UTF-8"><title>QR Code</title></head>'.
|
||||
'<body>'.$this->options->eol.$html.'</body>';
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
/**
|
||||
* SVG output
|
||||
*
|
||||
* @see https://github.com/codemasher/php-qrcode/pull/5
|
||||
*/
|
||||
protected function svg(string $file = null):string{
|
||||
$matrix = $this->matrix->matrix();
|
||||
|
||||
$svg = sprintf($this->svgHeader, $this->options->cssClass, $this->options->svgViewBoxSize ?? $this->moduleCount)
|
||||
.$this->options->eol
|
||||
.'<defs>'.$this->options->svgDefs.'</defs>'
|
||||
.$this->options->eol;
|
||||
|
||||
foreach($this->moduleValues as $M_TYPE => $value){
|
||||
$path = '';
|
||||
|
||||
foreach($matrix as $y => $row){
|
||||
//we'll combine active blocks within a single row as a lightweight compression technique
|
||||
$start = null;
|
||||
$count = 0;
|
||||
|
||||
foreach($row as $x => $module){
|
||||
|
||||
if($module === $M_TYPE){
|
||||
$count++;
|
||||
|
||||
if($start === null){
|
||||
$start = $x;
|
||||
}
|
||||
|
||||
if(isset($row[$x + 1])){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if($count > 0){
|
||||
$len = $count;
|
||||
$start ??= 0; // avoid type coercion in sprintf() - phan happy
|
||||
|
||||
$path .= sprintf('M%s %s h%s v1 h-%sZ ', $start, $y, $len, $len);
|
||||
|
||||
// reset count
|
||||
$count = 0;
|
||||
$start = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(!empty($path)){
|
||||
$svg .= sprintf(
|
||||
'<path class="qr-%s %s" stroke="transparent" fill="%s" fill-opacity="%s" d="%s" />',
|
||||
$M_TYPE, $this->options->cssClass, $value, $this->options->svgOpacity, $path
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// close svg
|
||||
$svg .= '</svg>'.$this->options->eol;
|
||||
|
||||
// if saving to file, append the correct headers
|
||||
if($file !== null){
|
||||
return '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">'.
|
||||
$this->options->eol.$svg;
|
||||
}
|
||||
|
||||
if($this->options->imageBase64){
|
||||
$svg = sprintf('data:image/svg+xml;base64,%s', base64_encode($svg));
|
||||
}
|
||||
|
||||
return $svg;
|
||||
}
|
||||
|
||||
}
|
||||
129
vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php
vendored
Normal file
129
vendor/chillerlan/php-qrcode/src/Output/QROutputAbstract.php
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QROutputAbstract
|
||||
*
|
||||
* @filesource QROutputAbstract.php
|
||||
* @created 09.12.2015
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\{Data\QRMatrix, QRCode};
|
||||
use chillerlan\Settings\SettingsContainerInterface;
|
||||
|
||||
use function call_user_func_array, dirname, file_put_contents, get_called_class, in_array, is_writable, sprintf;
|
||||
|
||||
/**
|
||||
* common output abstract
|
||||
*/
|
||||
abstract class QROutputAbstract implements QROutputInterface{
|
||||
|
||||
/**
|
||||
* the current size of the QR matrix
|
||||
*
|
||||
* @see \chillerlan\QRCode\Data\QRMatrix::size()
|
||||
*/
|
||||
protected int $moduleCount;
|
||||
|
||||
/**
|
||||
* the current output mode
|
||||
*
|
||||
* @see \chillerlan\QRCode\QROptions::$outputType
|
||||
*/
|
||||
protected string $outputMode;
|
||||
|
||||
/**
|
||||
* the default output mode of the current output module
|
||||
*/
|
||||
protected string $defaultMode;
|
||||
|
||||
/**
|
||||
* the current scaling for a QR pixel
|
||||
*
|
||||
* @see \chillerlan\QRCode\QROptions::$scale
|
||||
*/
|
||||
protected int $scale;
|
||||
|
||||
/**
|
||||
* the side length of the QR image (modules * scale)
|
||||
*/
|
||||
protected int $length;
|
||||
|
||||
/**
|
||||
* an (optional) array of color values for the several QR matrix parts
|
||||
*/
|
||||
protected array $moduleValues;
|
||||
|
||||
/**
|
||||
* the (filled) data matrix object
|
||||
*/
|
||||
protected QRMatrix $matrix;
|
||||
|
||||
/**
|
||||
* @var \chillerlan\Settings\SettingsContainerInterface|\chillerlan\QRCode\QROptions
|
||||
*/
|
||||
protected SettingsContainerInterface $options;
|
||||
|
||||
/**
|
||||
* QROutputAbstract constructor.
|
||||
*/
|
||||
public function __construct(SettingsContainerInterface $options, QRMatrix $matrix){
|
||||
$this->options = $options;
|
||||
$this->matrix = $matrix;
|
||||
$this->moduleCount = $this->matrix->size();
|
||||
$this->scale = $this->options->scale;
|
||||
$this->length = $this->moduleCount * $this->scale;
|
||||
|
||||
$class = get_called_class();
|
||||
|
||||
if(isset(QRCode::OUTPUT_MODES[$class]) && in_array($this->options->outputType, QRCode::OUTPUT_MODES[$class])){
|
||||
$this->outputMode = $this->options->outputType;
|
||||
}
|
||||
|
||||
$this->setModuleValues();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the initial module values (clean-up & defaults)
|
||||
*/
|
||||
abstract protected function setModuleValues():void;
|
||||
|
||||
/**
|
||||
* saves the qr data to a file
|
||||
*
|
||||
* @see file_put_contents()
|
||||
* @see \chillerlan\QRCode\QROptions::cachefile
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
|
||||
*/
|
||||
protected function saveToFile(string $data, string $file):bool{
|
||||
|
||||
if(!is_writable(dirname($file))){
|
||||
throw new QRCodeOutputException(sprintf('Could not write data to cache file: %s', $file));
|
||||
}
|
||||
|
||||
return (bool)file_put_contents($file, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function dump(string $file = null){
|
||||
$file ??= $this->options->cachefile;
|
||||
|
||||
// call the built-in output method with the optional file path as parameter
|
||||
// to make the called method aware if a cache file was given
|
||||
$data = call_user_func_array([$this, $this->outputMode ?? $this->defaultMode], [$file]);
|
||||
|
||||
if($file !== null){
|
||||
$this->saveToFile($data, $file);
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
||||
54
vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php
vendored
Normal file
54
vendor/chillerlan/php-qrcode/src/Output/QROutputInterface.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Interface QROutputInterface,
|
||||
*
|
||||
* @filesource QROutputInterface.php
|
||||
* @created 02.12.2015
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\Data\QRMatrix;
|
||||
|
||||
/**
|
||||
* Converts the data matrix into readable output
|
||||
*/
|
||||
interface QROutputInterface{
|
||||
|
||||
const DEFAULT_MODULE_VALUES = [
|
||||
// light
|
||||
QRMatrix::M_NULL => false, // 0
|
||||
QRMatrix::M_DATA => false, // 4
|
||||
QRMatrix::M_FINDER => false, // 6
|
||||
QRMatrix::M_SEPARATOR => false, // 8
|
||||
QRMatrix::M_ALIGNMENT => false, // 10
|
||||
QRMatrix::M_TIMING => false, // 12
|
||||
QRMatrix::M_FORMAT => false, // 14
|
||||
QRMatrix::M_VERSION => false, // 16
|
||||
QRMatrix::M_QUIETZONE => false, // 18
|
||||
QRMatrix::M_LOGO => false, // 20
|
||||
QRMatrix::M_TEST => false, // 255
|
||||
// dark
|
||||
QRMatrix::M_DARKMODULE << 8 => true, // 512
|
||||
QRMatrix::M_DATA << 8 => true, // 1024
|
||||
QRMatrix::M_FINDER << 8 => true, // 1536
|
||||
QRMatrix::M_ALIGNMENT << 8 => true, // 2560
|
||||
QRMatrix::M_TIMING << 8 => true, // 3072
|
||||
QRMatrix::M_FORMAT << 8 => true, // 3584
|
||||
QRMatrix::M_VERSION << 8 => true, // 4096
|
||||
QRMatrix::M_FINDER_DOT << 8 => true, // 5632
|
||||
QRMatrix::M_TEST << 8 => true, // 65280
|
||||
];
|
||||
|
||||
/**
|
||||
* generates the output, optionally dumps it to a file, and returns it
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function dump(string $file = null);
|
||||
|
||||
}
|
||||
76
vendor/chillerlan/php-qrcode/src/Output/QRString.php
vendored
Normal file
76
vendor/chillerlan/php-qrcode/src/Output/QRString.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRString
|
||||
*
|
||||
* @filesource QRString.php
|
||||
* @created 05.12.2015
|
||||
* @package chillerlan\QRCode\Output
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpUnusedParameterInspection
|
||||
* @noinspection PhpComposerExtensionStubsInspection
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode\Output;
|
||||
|
||||
use chillerlan\QRCode\QRCode;
|
||||
|
||||
use function implode, is_string, json_encode;
|
||||
|
||||
/**
|
||||
* Converts the matrix data into string types
|
||||
*/
|
||||
class QRString extends QROutputAbstract{
|
||||
|
||||
protected string $defaultMode = QRCode::OUTPUT_STRING_TEXT;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
protected function setModuleValues():void{
|
||||
|
||||
foreach($this::DEFAULT_MODULE_VALUES as $M_TYPE => $defaultValue){
|
||||
$v = $this->options->moduleValues[$M_TYPE] ?? null;
|
||||
|
||||
if(!is_string($v)){
|
||||
$this->moduleValues[$M_TYPE] = $defaultValue
|
||||
? $this->options->textDark
|
||||
: $this->options->textLight;
|
||||
}
|
||||
else{
|
||||
$this->moduleValues[$M_TYPE] = $v;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* string output
|
||||
*/
|
||||
protected function text(string $file = null):string{
|
||||
$str = [];
|
||||
|
||||
foreach($this->matrix->matrix() as $row){
|
||||
$r = [];
|
||||
|
||||
foreach($row as $M_TYPE){
|
||||
$r[] = $this->moduleValues[$M_TYPE];
|
||||
}
|
||||
|
||||
$str[] = implode('', $r);
|
||||
}
|
||||
|
||||
return implode($this->options->eol, $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* JSON output
|
||||
*/
|
||||
protected function json(string $file = null):string{
|
||||
return json_encode($this->matrix->matrix());
|
||||
}
|
||||
|
||||
}
|
||||
313
vendor/chillerlan/php-qrcode/src/QRCode.php
vendored
Executable file
313
vendor/chillerlan/php-qrcode/src/QRCode.php
vendored
Executable file
@@ -0,0 +1,313 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRCode
|
||||
*
|
||||
* @filesource QRCode.php
|
||||
* @created 26.11.2015
|
||||
* @package chillerlan\QRCode
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode;
|
||||
|
||||
use chillerlan\QRCode\Data\{
|
||||
AlphaNum, Byte, Kanji, MaskPatternTester, Number, QRCodeDataException, QRDataInterface, QRMatrix
|
||||
};
|
||||
use chillerlan\QRCode\Output\{
|
||||
QRCodeOutputException, QRFpdf, QRImage, QRImagick, QRMarkup, QROutputInterface, QRString
|
||||
};
|
||||
use chillerlan\Settings\SettingsContainerInterface;
|
||||
|
||||
use function call_user_func_array, class_exists, in_array, ord, strlen, strtolower, str_split;
|
||||
|
||||
/**
|
||||
* Turns a text string into a Model 2 QR Code
|
||||
*
|
||||
* @see https://github.com/kazuhikoarase/qrcode-generator/tree/master/php
|
||||
* @see http://www.qrcode.com/en/codes/model12.html
|
||||
* @see https://www.swisseduc.ch/informatik/theoretische_informatik/qr_codes/docs/qr_standard.pdf
|
||||
* @see https://en.wikipedia.org/wiki/QR_code
|
||||
* @see http://www.thonky.com/qr-code-tutorial/
|
||||
*/
|
||||
class QRCode{
|
||||
|
||||
/** @var int */
|
||||
public const VERSION_AUTO = -1;
|
||||
/** @var int */
|
||||
public const MASK_PATTERN_AUTO = -1;
|
||||
|
||||
// ISO/IEC 18004:2000 Table 2
|
||||
|
||||
/** @var int */
|
||||
public const DATA_NUMBER = 0b0001;
|
||||
/** @var int */
|
||||
public const DATA_ALPHANUM = 0b0010;
|
||||
/** @var int */
|
||||
public const DATA_BYTE = 0b0100;
|
||||
/** @var int */
|
||||
public const DATA_KANJI = 0b1000;
|
||||
|
||||
/**
|
||||
* References to the keys of the following tables:
|
||||
*
|
||||
* @see \chillerlan\QRCode\Data\QRDataInterface::MAX_LENGTH
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
public const DATA_MODES = [
|
||||
self::DATA_NUMBER => 0,
|
||||
self::DATA_ALPHANUM => 1,
|
||||
self::DATA_BYTE => 2,
|
||||
self::DATA_KANJI => 3,
|
||||
];
|
||||
|
||||
// ISO/IEC 18004:2000 Tables 12, 25
|
||||
|
||||
/** @var int */
|
||||
public const ECC_L = 0b01; // 7%.
|
||||
/** @var int */
|
||||
public const ECC_M = 0b00; // 15%.
|
||||
/** @var int */
|
||||
public const ECC_Q = 0b11; // 25%.
|
||||
/** @var int */
|
||||
public const ECC_H = 0b10; // 30%.
|
||||
|
||||
/**
|
||||
* References to the keys of the following tables:
|
||||
*
|
||||
* @see \chillerlan\QRCode\Data\QRDataInterface::MAX_BITS
|
||||
* @see \chillerlan\QRCode\Data\QRDataInterface::RSBLOCKS
|
||||
* @see \chillerlan\QRCode\Data\QRMatrix::formatPattern
|
||||
*
|
||||
* @var int[]
|
||||
*/
|
||||
public const ECC_MODES = [
|
||||
self::ECC_L => 0,
|
||||
self::ECC_M => 1,
|
||||
self::ECC_Q => 2,
|
||||
self::ECC_H => 3,
|
||||
];
|
||||
|
||||
/** @var string */
|
||||
public const OUTPUT_MARKUP_HTML = 'html';
|
||||
/** @var string */
|
||||
public const OUTPUT_MARKUP_SVG = 'svg';
|
||||
/** @var string */
|
||||
public const OUTPUT_IMAGE_PNG = 'png';
|
||||
/** @var string */
|
||||
public const OUTPUT_IMAGE_JPG = 'jpg';
|
||||
/** @var string */
|
||||
public const OUTPUT_IMAGE_GIF = 'gif';
|
||||
/** @var string */
|
||||
public const OUTPUT_STRING_JSON = 'json';
|
||||
/** @var string */
|
||||
public const OUTPUT_STRING_TEXT = 'text';
|
||||
/** @var string */
|
||||
public const OUTPUT_IMAGICK = 'imagick';
|
||||
/** @var string */
|
||||
public const OUTPUT_FPDF = 'fpdf';
|
||||
/** @var string */
|
||||
public const OUTPUT_CUSTOM = 'custom';
|
||||
|
||||
/**
|
||||
* Map of built-in output modules => capabilities
|
||||
*
|
||||
* @var string[][]
|
||||
*/
|
||||
public const OUTPUT_MODES = [
|
||||
QRMarkup::class => [
|
||||
self::OUTPUT_MARKUP_SVG,
|
||||
self::OUTPUT_MARKUP_HTML,
|
||||
],
|
||||
QRImage::class => [
|
||||
self::OUTPUT_IMAGE_PNG,
|
||||
self::OUTPUT_IMAGE_GIF,
|
||||
self::OUTPUT_IMAGE_JPG,
|
||||
],
|
||||
QRString::class => [
|
||||
self::OUTPUT_STRING_JSON,
|
||||
self::OUTPUT_STRING_TEXT,
|
||||
],
|
||||
QRImagick::class => [
|
||||
self::OUTPUT_IMAGICK,
|
||||
],
|
||||
QRFpdf::class => [
|
||||
self::OUTPUT_FPDF
|
||||
]
|
||||
];
|
||||
|
||||
/**
|
||||
* Map of data mode => interface
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected const DATA_INTERFACES = [
|
||||
'number' => Number::class,
|
||||
'alphanum' => AlphaNum::class,
|
||||
'kanji' => Kanji::class,
|
||||
'byte' => Byte::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The settings container
|
||||
*
|
||||
* @var \chillerlan\QRCode\QROptions|\chillerlan\Settings\SettingsContainerInterface
|
||||
*/
|
||||
protected SettingsContainerInterface $options;
|
||||
|
||||
/**
|
||||
* The selected data interface (Number, AlphaNum, Kanji, Byte)
|
||||
*/
|
||||
protected QRDataInterface $dataInterface;
|
||||
|
||||
/**
|
||||
* QRCode constructor.
|
||||
*
|
||||
* Sets the options instance, determines the current mb-encoding and sets it to UTF-8
|
||||
*/
|
||||
public function __construct(SettingsContainerInterface $options = null){
|
||||
$this->options = $options ?? new QROptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders a QR Code for the given $data and QROptions
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function render(string $data, string $file = null){
|
||||
return $this->initOutputInterface($data)->dump($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a QRMatrix object for the given $data and current QROptions
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
*/
|
||||
public function getMatrix(string $data):QRMatrix{
|
||||
|
||||
if(empty($data)){
|
||||
throw new QRCodeDataException('QRCode::getMatrix() No data given.');
|
||||
}
|
||||
|
||||
$this->dataInterface = $this->initDataInterface($data);
|
||||
|
||||
$maskPattern = $this->options->maskPattern === $this::MASK_PATTERN_AUTO
|
||||
? (new MaskPatternTester($this->dataInterface))->getBestMaskPattern()
|
||||
: $this->options->maskPattern;
|
||||
|
||||
$matrix = $this->dataInterface->initMatrix($maskPattern);
|
||||
|
||||
if((bool)$this->options->addQuietzone){
|
||||
$matrix->setQuietZone($this->options->quietzoneSize);
|
||||
}
|
||||
|
||||
return $matrix;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a fresh QRDataInterface for the given $data
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Data\QRCodeDataException
|
||||
*/
|
||||
public function initDataInterface(string $data):QRDataInterface{
|
||||
|
||||
// allow forcing the data mode
|
||||
// see https://github.com/chillerlan/php-qrcode/issues/39
|
||||
$interface = $this::DATA_INTERFACES[strtolower($this->options->dataModeOverride)] ?? null;
|
||||
|
||||
if($interface !== null){
|
||||
return new $interface($this->options, $data);
|
||||
}
|
||||
|
||||
foreach($this::DATA_INTERFACES as $mode => $dataInterface){
|
||||
|
||||
if(call_user_func_array([$this, 'is'.$mode], [$data])){
|
||||
return new $dataInterface($this->options, $data);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw new QRCodeDataException('invalid data type'); // @codeCoverageIgnore
|
||||
}
|
||||
|
||||
/**
|
||||
* returns a fresh (built-in) QROutputInterface
|
||||
*
|
||||
* @throws \chillerlan\QRCode\Output\QRCodeOutputException
|
||||
*/
|
||||
protected function initOutputInterface(string $data):QROutputInterface{
|
||||
|
||||
if($this->options->outputType === $this::OUTPUT_CUSTOM && class_exists($this->options->outputInterface)){
|
||||
/** @phan-suppress-next-line PhanTypeExpectedObjectOrClassName */
|
||||
return new $this->options->outputInterface($this->options, $this->getMatrix($data));
|
||||
}
|
||||
|
||||
foreach($this::OUTPUT_MODES as $outputInterface => $modes){
|
||||
|
||||
if(in_array($this->options->outputType, $modes, true) && class_exists($outputInterface)){
|
||||
return new $outputInterface($this->options, $this->getMatrix($data));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw new QRCodeOutputException('invalid output type');
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if a string qualifies as numeric
|
||||
*/
|
||||
public function isNumber(string $string):bool{
|
||||
return $this->checkString($string, QRDataInterface::CHAR_MAP_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if a string qualifies as alphanumeric
|
||||
*/
|
||||
public function isAlphaNum(string $string):bool{
|
||||
return $this->checkString($string, QRDataInterface::CHAR_MAP_ALPHANUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* checks is a given $string matches the characters of a given $charmap, returns false on the first invalid occurence.
|
||||
*/
|
||||
protected function checkString(string $string, array $charmap):bool{
|
||||
|
||||
foreach(str_split($string) as $chr){
|
||||
if(!isset($charmap[$chr])){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* checks if a string qualifies as Kanji
|
||||
*/
|
||||
public function isKanji(string $string):bool{
|
||||
$i = 0;
|
||||
$len = strlen($string);
|
||||
|
||||
while($i + 1 < $len){
|
||||
$c = ((0xff & ord($string[$i])) << 8) | (0xff & ord($string[$i + 1]));
|
||||
|
||||
if(!($c >= 0x8140 && $c <= 0x9FFC) && !($c >= 0xE040 && $c <= 0xEBBF)){
|
||||
return false;
|
||||
}
|
||||
|
||||
$i += 2;
|
||||
}
|
||||
|
||||
return $i >= $len;
|
||||
}
|
||||
|
||||
/**
|
||||
* a dummy
|
||||
*/
|
||||
public function isByte(string $data):bool{
|
||||
return $data !== '';
|
||||
}
|
||||
|
||||
}
|
||||
20
vendor/chillerlan/php-qrcode/src/QRCodeException.php
vendored
Normal file
20
vendor/chillerlan/php-qrcode/src/QRCodeException.php
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QRCodeException
|
||||
*
|
||||
* @filesource QRCodeException.php
|
||||
* @created 27.11.2015
|
||||
* @package chillerlan\QRCode
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode;
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* An exception container
|
||||
*/
|
||||
class QRCodeException extends Exception{}
|
||||
54
vendor/chillerlan/php-qrcode/src/QROptions.php
vendored
Normal file
54
vendor/chillerlan/php-qrcode/src/QROptions.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* Class QROptions
|
||||
*
|
||||
* @filesource QROptions.php
|
||||
* @created 08.12.2015
|
||||
* @package chillerlan\QRCode
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2015 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode;
|
||||
|
||||
use chillerlan\Settings\SettingsContainerAbstract;
|
||||
|
||||
/**
|
||||
* The QRCode settings container
|
||||
*
|
||||
* @property int $version
|
||||
* @property int $versionMin
|
||||
* @property int $versionMax
|
||||
* @property int $eccLevel
|
||||
* @property int $maskPattern
|
||||
* @property bool $addQuietzone
|
||||
* @property int $quietzoneSize
|
||||
* @property string|null $dataModeOverride
|
||||
* @property string $outputType
|
||||
* @property string|null $outputInterface
|
||||
* @property string|null $cachefile
|
||||
* @property string $eol
|
||||
* @property int $scale
|
||||
* @property string $cssClass
|
||||
* @property float $svgOpacity
|
||||
* @property string $svgDefs
|
||||
* @property int $svgViewBoxSize
|
||||
* @property string $textDark
|
||||
* @property string $textLight
|
||||
* @property string $markupDark
|
||||
* @property string $markupLight
|
||||
* @property bool $returnResource
|
||||
* @property bool $imageBase64
|
||||
* @property bool $imageTransparent
|
||||
* @property array $imageTransparencyBG
|
||||
* @property int $pngCompression
|
||||
* @property int $jpegQuality
|
||||
* @property string $imagickFormat
|
||||
* @property string|null $imagickBG
|
||||
* @property string $fpdfMeasureUnit
|
||||
* @property array|null $moduleValues
|
||||
*/
|
||||
class QROptions extends SettingsContainerAbstract{
|
||||
use QROptionsTrait;
|
||||
}
|
||||
341
vendor/chillerlan/php-qrcode/src/QROptionsTrait.php
vendored
Normal file
341
vendor/chillerlan/php-qrcode/src/QROptionsTrait.php
vendored
Normal file
@@ -0,0 +1,341 @@
|
||||
<?php
|
||||
/**
|
||||
* Trait QROptionsTrait
|
||||
*
|
||||
* @filesource QROptionsTrait.php
|
||||
* @created 10.03.2018
|
||||
* @package chillerlan\QRCode
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2018 smiley
|
||||
* @license MIT
|
||||
*
|
||||
* @noinspection PhpUnused
|
||||
*/
|
||||
|
||||
namespace chillerlan\QRCode;
|
||||
|
||||
use function array_values, count, in_array, is_numeric, max, min, sprintf, strtolower;
|
||||
|
||||
/**
|
||||
* The QRCode plug-in settings & setter functionality
|
||||
*/
|
||||
trait QROptionsTrait{
|
||||
|
||||
/**
|
||||
* QR Code version number
|
||||
*
|
||||
* [1 ... 40] or QRCode::VERSION_AUTO
|
||||
*/
|
||||
protected int $version = QRCode::VERSION_AUTO;
|
||||
|
||||
/**
|
||||
* Minimum QR version
|
||||
*
|
||||
* if $version = QRCode::VERSION_AUTO
|
||||
*/
|
||||
protected int $versionMin = 1;
|
||||
|
||||
/**
|
||||
* Maximum QR version
|
||||
*/
|
||||
protected int $versionMax = 40;
|
||||
|
||||
/**
|
||||
* Error correct level
|
||||
*
|
||||
* QRCode::ECC_X where X is:
|
||||
*
|
||||
* - L => 7%
|
||||
* - M => 15%
|
||||
* - Q => 25%
|
||||
* - H => 30%
|
||||
*/
|
||||
protected int $eccLevel = QRCode::ECC_L;
|
||||
|
||||
/**
|
||||
* Mask Pattern to use
|
||||
*
|
||||
* [0...7] or QRCode::MASK_PATTERN_AUTO
|
||||
*/
|
||||
protected int $maskPattern = QRCode::MASK_PATTERN_AUTO;
|
||||
|
||||
/**
|
||||
* Add a "quiet zone" (margin) according to the QR code spec
|
||||
*/
|
||||
protected bool $addQuietzone = true;
|
||||
|
||||
/**
|
||||
* Size of the quiet zone
|
||||
*
|
||||
* internally clamped to [0 ... $moduleCount / 2], defaults to 4 modules
|
||||
*/
|
||||
protected int $quietzoneSize = 4;
|
||||
|
||||
/**
|
||||
* Use this to circumvent the data mode detection and force the usage of the given mode.
|
||||
*
|
||||
* valid modes are: Number, AlphaNum, Kanji, Byte (case insensitive)
|
||||
*
|
||||
* @see https://github.com/chillerlan/php-qrcode/issues/39
|
||||
* @see https://github.com/chillerlan/php-qrcode/issues/97 (changed default value to '')
|
||||
*/
|
||||
protected string $dataModeOverride = '';
|
||||
|
||||
/**
|
||||
* The output type
|
||||
*
|
||||
* - QRCode::OUTPUT_MARKUP_XXXX where XXXX = HTML, SVG
|
||||
* - QRCode::OUTPUT_IMAGE_XXX where XXX = PNG, GIF, JPG
|
||||
* - QRCode::OUTPUT_STRING_XXXX where XXXX = TEXT, JSON
|
||||
* - QRCode::OUTPUT_CUSTOM
|
||||
*/
|
||||
protected string $outputType = QRCode::OUTPUT_IMAGE_PNG;
|
||||
|
||||
/**
|
||||
* the FQCN of the custom QROutputInterface if $outputType is set to QRCode::OUTPUT_CUSTOM
|
||||
*/
|
||||
protected ?string $outputInterface = null;
|
||||
|
||||
/**
|
||||
* /path/to/cache.file
|
||||
*/
|
||||
protected ?string $cachefile = null;
|
||||
|
||||
/**
|
||||
* newline string [HTML, SVG, TEXT]
|
||||
*/
|
||||
protected string $eol = PHP_EOL;
|
||||
|
||||
/**
|
||||
* size of a QR code pixel [SVG, IMAGE_*], HTML via CSS
|
||||
*/
|
||||
protected int $scale = 5;
|
||||
|
||||
/**
|
||||
* a common css class
|
||||
*/
|
||||
protected string $cssClass = '';
|
||||
|
||||
/**
|
||||
* SVG opacity
|
||||
*/
|
||||
protected float $svgOpacity = 1.0;
|
||||
|
||||
/**
|
||||
* anything between <defs>
|
||||
*
|
||||
* @see https://developer.mozilla.org/docs/Web/SVG/Element/defs
|
||||
*/
|
||||
protected string $svgDefs = '<style>rect{shape-rendering:crispEdges}</style>';
|
||||
|
||||
/**
|
||||
* SVG viewBox size. a single integer number which defines width/height of the viewBox attribute.
|
||||
*
|
||||
* viewBox="0 0 x x"
|
||||
*
|
||||
* @see https://css-tricks.com/scale-svg/#article-header-id-3
|
||||
*/
|
||||
protected ?int $svgViewBoxSize = null;
|
||||
|
||||
/**
|
||||
* string substitute for dark
|
||||
*/
|
||||
protected string $textDark = '🔴';
|
||||
|
||||
/**
|
||||
* string substitute for light
|
||||
*/
|
||||
protected string $textLight = '⭕';
|
||||
|
||||
/**
|
||||
* markup substitute for dark (CSS value)
|
||||
*/
|
||||
protected string $markupDark = '#000';
|
||||
|
||||
/**
|
||||
* markup substitute for light (CSS value)
|
||||
*/
|
||||
protected string $markupLight = '#fff';
|
||||
|
||||
/**
|
||||
* Return the image resource instead of a render if applicable.
|
||||
* This option overrides other output options, such as $cachefile and $imageBase64.
|
||||
*
|
||||
* Supported by the following modules:
|
||||
*
|
||||
* - QRImage: resource (PHP < 8), GdImage
|
||||
* - QRImagick: Imagick
|
||||
* - QRFpdf: FPDF
|
||||
*
|
||||
* @see \chillerlan\QRCode\Output\QROutputInterface::dump()
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected bool $returnResource = false;
|
||||
|
||||
/**
|
||||
* toggle base64 or raw image data
|
||||
*/
|
||||
protected bool $imageBase64 = true;
|
||||
|
||||
/**
|
||||
* toggle transparency, not supported by jpg
|
||||
*/
|
||||
protected bool $imageTransparent = true;
|
||||
|
||||
/**
|
||||
* @see imagecolortransparent()
|
||||
*
|
||||
* [R, G, B]
|
||||
*/
|
||||
protected array $imageTransparencyBG = [255, 255, 255];
|
||||
|
||||
/**
|
||||
* @see imagepng()
|
||||
*/
|
||||
protected int $pngCompression = -1;
|
||||
|
||||
/**
|
||||
* @see imagejpeg()
|
||||
*/
|
||||
protected int $jpegQuality = 85;
|
||||
|
||||
/**
|
||||
* Imagick output format
|
||||
*
|
||||
* @see \Imagick::setType()
|
||||
*/
|
||||
protected string $imagickFormat = 'png';
|
||||
|
||||
/**
|
||||
* Imagick background color (defaults to "transparent")
|
||||
*
|
||||
* @see \ImagickPixel::__construct()
|
||||
*/
|
||||
protected ?string $imagickBG = null;
|
||||
|
||||
/**
|
||||
* Measurement unit for FPDF output: pt, mm, cm, in (defaults to "pt")
|
||||
*
|
||||
* @see \FPDF::__construct()
|
||||
*/
|
||||
protected string $fpdfMeasureUnit = 'pt';
|
||||
|
||||
/**
|
||||
* Module values map
|
||||
*
|
||||
* - HTML, IMAGICK: #ABCDEF, cssname, rgb(), rgba()...
|
||||
* - IMAGE: [63, 127, 255] // R, G, B
|
||||
*/
|
||||
protected ?array $moduleValues = null;
|
||||
|
||||
/**
|
||||
* clamp min/max version number
|
||||
*/
|
||||
protected function setMinMaxVersion(int $versionMin, int $versionMax):void{
|
||||
$min = max(1, min(40, $versionMin));
|
||||
$max = max(1, min(40, $versionMax));
|
||||
|
||||
$this->versionMin = min($min, $max);
|
||||
$this->versionMax = max($min, $max);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the minimum version number
|
||||
*/
|
||||
protected function set_versionMin(int $version):void{
|
||||
$this->setMinMaxVersion($version, $this->versionMax);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the maximum version number
|
||||
*/
|
||||
protected function set_versionMax(int $version):void{
|
||||
$this->setMinMaxVersion($this->versionMin, $version);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the error correction level
|
||||
*
|
||||
* @throws \chillerlan\QRCode\QRCodeException
|
||||
*/
|
||||
protected function set_eccLevel(int $eccLevel):void{
|
||||
|
||||
if(!isset(QRCode::ECC_MODES[$eccLevel])){
|
||||
throw new QRCodeException(sprintf('Invalid error correct level: %s', $eccLevel));
|
||||
}
|
||||
|
||||
$this->eccLevel = $eccLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* sets/clamps the mask pattern
|
||||
*/
|
||||
protected function set_maskPattern(int $maskPattern):void{
|
||||
|
||||
if($maskPattern !== QRCode::MASK_PATTERN_AUTO){
|
||||
$this->maskPattern = max(0, min(7, $maskPattern));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the transparency background color
|
||||
*
|
||||
* @throws \chillerlan\QRCode\QRCodeException
|
||||
*/
|
||||
protected function set_imageTransparencyBG(array $imageTransparencyBG):void{
|
||||
|
||||
// invalid value - set to white as default
|
||||
if(count($imageTransparencyBG) < 3){
|
||||
$this->imageTransparencyBG = [255, 255, 255];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach($imageTransparencyBG as $k => $v){
|
||||
|
||||
// cut off exceeding items
|
||||
if($k > 2){
|
||||
break;
|
||||
}
|
||||
|
||||
if(!is_numeric($v)){
|
||||
throw new QRCodeException('Invalid RGB value.');
|
||||
}
|
||||
|
||||
// clamp the values
|
||||
$this->imageTransparencyBG[$k] = max(0, min(255, (int)$v));
|
||||
}
|
||||
|
||||
// use the array values to not run into errors with the spread operator (...$arr)
|
||||
$this->imageTransparencyBG = array_values($this->imageTransparencyBG);
|
||||
}
|
||||
|
||||
/**
|
||||
* sets/clamps the version number
|
||||
*/
|
||||
protected function set_version(int $version):void{
|
||||
|
||||
if($version !== QRCode::VERSION_AUTO){
|
||||
$this->version = max(1, min(40, $version));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* sets the FPDF measurement unit
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
protected function set_fpdfMeasureUnit(string $unit):void{
|
||||
$unit = strtolower($unit);
|
||||
|
||||
if(in_array($unit, ['cm', 'in', 'mm', 'pt'], true)){
|
||||
$this->fpdfMeasureUnit = $unit;
|
||||
}
|
||||
|
||||
// @todo throw or ignore silently?
|
||||
}
|
||||
|
||||
}
|
||||
2
vendor/chillerlan/php-settings-container/.github/FUNDING.yml
vendored
Normal file
2
vendor/chillerlan/php-settings-container/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
ko_fi: codemasher
|
||||
custom: "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4"
|
||||
105
vendor/chillerlan/php-settings-container/.github/workflows/tests.yml
vendored
Normal file
105
vendor/chillerlan/php-settings-container/.github/workflows/tests.yml
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
|
||||
# https://github.com/sebastianbergmann/phpunit/blob/master/.github/workflows/ci.yml
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
|
||||
|
||||
name: "CI"
|
||||
|
||||
jobs:
|
||||
|
||||
static-code-analysis:
|
||||
name: "Static Code Analysis"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
PHAN_ALLOW_XDEBUG: 0
|
||||
PHAN_DISABLE_XDEBUG_WARN: 1
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "7.4"
|
||||
tools: pecl
|
||||
coverage: none
|
||||
extensions: ast, json
|
||||
|
||||
- name: "Update dependencies with composer"
|
||||
run: composer update --no-interaction --no-ansi --no-progress --no-suggest
|
||||
|
||||
- name: "Run phan"
|
||||
run: php vendor/bin/phan
|
||||
|
||||
build-docs:
|
||||
name: "Build and publish Docs"
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: "Checkout sources"
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: "Install PHP"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: "8.1"
|
||||
coverage: none
|
||||
tools: phpDocumentor
|
||||
extensions: json
|
||||
|
||||
- name: "Build Docs"
|
||||
run: phpdoc --config=phpdoc.xml
|
||||
|
||||
- name: "Publish Docs to gh-pages"
|
||||
uses: JamesIves/github-pages-deploy-action@v4.3.4
|
||||
with:
|
||||
branch: gh-pages
|
||||
folder: docs
|
||||
clean: true
|
||||
|
||||
tests:
|
||||
name: "Unit Tests"
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
php-version:
|
||||
- "7.4"
|
||||
- "8.0"
|
||||
- "8.1"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: "Install PHP with extensions"
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php-version }}
|
||||
coverage: pcov
|
||||
extensions: json
|
||||
|
||||
- name: "Install dependencies with composer"
|
||||
run: composer update --no-ansi --no-interaction --no-progress --no-suggest
|
||||
|
||||
- name: "Run tests with phpunit"
|
||||
run: php vendor/phpunit/phpunit/phpunit --configuration=phpunit.xml
|
||||
|
||||
- name: "Send code coverage report to Codecov.io"
|
||||
uses: codecov/codecov-action@v3
|
||||
4
vendor/chillerlan/php-settings-container/.gitignore
vendored
Normal file
4
vendor/chillerlan/php-settings-container/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
/.build
|
||||
/.idea
|
||||
/vendor
|
||||
composer.lock
|
||||
54
vendor/chillerlan/php-settings-container/.phan/config.php
vendored
Normal file
54
vendor/chillerlan/php-settings-container/.phan/config.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
/**
|
||||
* This configuration will be read and overlaid on top of the
|
||||
* default configuration. Command-line arguments will be applied
|
||||
* after this file is read.
|
||||
*/
|
||||
return [
|
||||
// Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`,
|
||||
// `'7.4'`, `null`.
|
||||
// If this is set to `null`,
|
||||
// then Phan assumes the PHP version which is closest to the minor version
|
||||
// of the php executable used to execute Phan.
|
||||
//
|
||||
// Note that the **only** effect of choosing `'5.6'` is to infer
|
||||
// that functions removed in php 7.0 exist.
|
||||
// (See `backward_compatibility_checks` for additional options)
|
||||
'target_php_version' => '7.4',
|
||||
|
||||
// A list of directories that should be parsed for class and
|
||||
// method information. After excluding the directories
|
||||
// defined in exclude_analysis_directory_list, the remaining
|
||||
// files will be statically analyzed for errors.
|
||||
//
|
||||
// Thus, both first-party and third-party code being used by
|
||||
// your application should be included in this list.
|
||||
'directory_list' => [
|
||||
'examples',
|
||||
'src',
|
||||
'tests',
|
||||
'vendor',
|
||||
],
|
||||
|
||||
// A regex used to match every file name that you want to
|
||||
// exclude from parsing. Actual value will exclude every
|
||||
// "test", "tests", "Test" and "Tests" folders found in
|
||||
// "vendor/" directory.
|
||||
'exclude_file_regex' => '@^vendor/.*/(tests?|Tests?)/@',
|
||||
|
||||
// A directory list that defines files that will be excluded
|
||||
// from static analysis, but whose class and method
|
||||
// information should be included.
|
||||
//
|
||||
// Generally, you'll want to include the directories for
|
||||
// third-party code (such as "vendor/") in this list.
|
||||
//
|
||||
// n.b.: If you'd like to parse but not analyze 3rd
|
||||
// party code, directories containing that code
|
||||
// should be added to both the `directory_list`
|
||||
// and `exclude_analysis_directory_list` arrays.
|
||||
'exclude_analysis_directory_list' => [
|
||||
'tests',
|
||||
'vendor',
|
||||
],
|
||||
];
|
||||
14
vendor/chillerlan/php-settings-container/.scrutinizer.yml
vendored
Normal file
14
vendor/chillerlan/php-settings-container/.scrutinizer.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
build:
|
||||
nodes:
|
||||
analysis:
|
||||
tests:
|
||||
override:
|
||||
- php-scrutinizer-run
|
||||
environment:
|
||||
php: 8.0.0
|
||||
|
||||
filter:
|
||||
excluded_paths:
|
||||
- examples/*
|
||||
- tests/*
|
||||
- vendor/*
|
||||
21
vendor/chillerlan/php-settings-container/LICENSE
vendored
Normal file
21
vendor/chillerlan/php-settings-container/LICENSE
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2018 Smiley <smiley@chillerlan.net>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
156
vendor/chillerlan/php-settings-container/README.md
vendored
Normal file
156
vendor/chillerlan/php-settings-container/README.md
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
# chillerlan/php-settings-container
|
||||
|
||||
A container class for immutable settings objects. Not a DI container. PHP 7.4+
|
||||
- [`SettingsContainerInterface`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerInterface.php) provides immutable properties with magic getter & setter and some fancy - decouple configuration logic from your application!
|
||||
|
||||
[![PHP Version Support][php-badge]][php]
|
||||
[![version][packagist-badge]][packagist]
|
||||
[![license][license-badge]][license]
|
||||
[![Coverage][coverage-badge]][coverage]
|
||||
[![Scrunitizer][scrutinizer-badge]][scrutinizer]
|
||||
[![Packagist downloads][downloads-badge]][downloads]
|
||||
[![Continuous Integration][gh-action-badge]][gh-action]
|
||||
|
||||
[php-badge]: https://img.shields.io/packagist/php-v/chillerlan/php-settings-container?logo=php&color=8892BF
|
||||
[php]: https://www.php.net/supported-versions.php
|
||||
[packagist-badge]: https://img.shields.io/packagist/v/chillerlan/php-settings-container.svg?logo=packagist
|
||||
[packagist]: https://packagist.org/packages/chillerlan/php-settings-container
|
||||
[license-badge]: https://img.shields.io/github/license/chillerlan/php-settings-container.svg
|
||||
[license]: https://github.com/chillerlan/php-settings-container/blob/main/LICENSE
|
||||
[coverage-badge]: https://img.shields.io/codecov/c/github/chillerlan/php-settings-container.svg?logo=codecov
|
||||
[coverage]: https://codecov.io/github/chillerlan/php-settings-container
|
||||
[scrutinizer-badge]: https://img.shields.io/scrutinizer/g/chillerlan/php-settings-container.svg?logo=scrutinizer
|
||||
[scrutinizer]: https://scrutinizer-ci.com/g/chillerlan/php-settings-container
|
||||
[downloads-badge]: https://img.shields.io/packagist/dt/chillerlan/php-settings-container.svg?logo=packagist
|
||||
[downloads]: https://packagist.org/packages/chillerlan/php-settings-container/stats
|
||||
[gh-action-badge]: https://github.com/chillerlan/php-settings-container/workflows/CI/badge.svg
|
||||
[gh-action]: https://github.com/chillerlan/php-settings-container/actions?query=workflow%3A%22CI%22
|
||||
|
||||
## Documentation
|
||||
|
||||
### Installation
|
||||
**requires [composer](https://getcomposer.org)**
|
||||
|
||||
*composer.json* (note: replace `dev-main` with a [version constraint](https://getcomposer.org/doc/articles/versions.md#writing-version-constraints), e.g. `^2.1` - see [releases](https://github.com/chillerlan/php-settings-container/releases) for valid versions)
|
||||
```json
|
||||
{
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"chillerlan/php-settings-container": "dev-main"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Profit!
|
||||
|
||||
## Usage
|
||||
|
||||
The `SettingsContainerInterface` (wrapped in`SettingsContainerAbstract` ) provides plug-in functionality for immutable object properties and adds some fancy, like loading/saving JSON, arrays etc.
|
||||
It takes an `iterable` as the only constructor argument and calls a method with the trait's name on invocation (`MyTrait::MyTrait()`) for each used trait.
|
||||
|
||||
### Simple usage
|
||||
```php
|
||||
class MyContainer extends SettingsContainerAbstract{
|
||||
protected $foo;
|
||||
protected $bar;
|
||||
}
|
||||
```
|
||||
Typed properties in PHP 7.4+:
|
||||
```php
|
||||
class MyContainer extends SettingsContainerAbstract{
|
||||
protected string $foo;
|
||||
protected string $bar;
|
||||
}
|
||||
```
|
||||
|
||||
```php
|
||||
// use it just like a \stdClass
|
||||
$container = new MyContainer;
|
||||
$container->foo = 'what';
|
||||
$container->bar = 'foo';
|
||||
|
||||
// which is equivalent to
|
||||
$container = new MyContainer(['bar' => 'foo', 'foo' => 'what']);
|
||||
// ...or try
|
||||
$container->fromJSON('{"foo": "what", "bar": "foo"}');
|
||||
|
||||
|
||||
// fetch all properties as array
|
||||
$container->toArray(); // -> ['foo' => 'what', 'bar' => 'foo']
|
||||
// or JSON
|
||||
$container->toJSON(); // -> {"foo": "what", "bar": "foo"}
|
||||
// JSON via JsonSerializable
|
||||
$json = json_encode($container); // -> {"foo": "what", "bar": "foo"}
|
||||
|
||||
//non-existing properties will be ignored:
|
||||
$container->nope = 'what';
|
||||
|
||||
var_dump($container->nope); // -> null
|
||||
```
|
||||
|
||||
### Advanced usage
|
||||
```php
|
||||
trait SomeOptions{
|
||||
protected $foo;
|
||||
protected $what;
|
||||
|
||||
// this method will be called in SettingsContainerAbstract::construct()
|
||||
// after the properties have been set
|
||||
protected function SomeOptions(){
|
||||
// just some constructor stuff...
|
||||
$this->foo = strtoupper($this->foo);
|
||||
}
|
||||
|
||||
// this method will be called from __set() when property $what is set
|
||||
protected function set_what(string $value){
|
||||
$this->what = md5($value);
|
||||
}
|
||||
}
|
||||
|
||||
trait MoreOptions{
|
||||
protected $bar = 'whatever'; // provide default values
|
||||
}
|
||||
```
|
||||
|
||||
```php
|
||||
$commonOptions = [
|
||||
// SomeOptions
|
||||
'foo' => 'whatever',
|
||||
// MoreOptions
|
||||
'bar' => 'nothing',
|
||||
];
|
||||
|
||||
// now plug the several library options together to a single object
|
||||
$container = new class ($commonOptions) extends SettingsContainerAbstract{
|
||||
use SomeOptions, MoreOptions;
|
||||
};
|
||||
|
||||
var_dump($container->foo); // -> WHATEVER (constructor ran strtoupper on the value)
|
||||
var_dump($container->bar); // -> nothing
|
||||
|
||||
$container->what = 'some value';
|
||||
var_dump($container->what); // -> md5 hash of "some value"
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
#### [`SettingsContainerAbstract`](https://github.com/chillerlan/php-settings-container/blob/main/src/SettingsContainerAbstract.php)
|
||||
|
||||
method | return | info
|
||||
-------- | ---- | -----------
|
||||
`__construct(iterable $properties = null)` | - | calls `construct()` internally after the properties have been set
|
||||
(protected) `construct()` | void | calls a method with trait name as replacement constructor for each used trait
|
||||
`__get(string $property)` | mixed | calls `$this->{'get_'.$property}()` if such a method exists
|
||||
`__set(string $property, $value)` | void | calls `$this->{'set_'.$property}($value)` if such a method exists
|
||||
`__isset(string $property)` | bool |
|
||||
`__unset(string $property)` | void |
|
||||
`__toString()` | string | a JSON string
|
||||
`toArray()` | array |
|
||||
`fromIterable(iterable $properties)` | `SettingsContainerInterface` |
|
||||
`toJSON(int $jsonOptions = null)` | string | accepts [JSON options constants](http://php.net/manual/json.constants.php)
|
||||
`fromJSON(string $json)` | `SettingsContainerInterface` |
|
||||
`jsonSerialize()` | mixed | implements the [`JsonSerializable`](https://www.php.net/manual/en/jsonserializable.jsonserialize.php) interface
|
||||
|
||||
## Disclaimer
|
||||
This might be either an utterly genius or completely stupid idea - you decide. However, i like it and it works.
|
||||
Also, this is not a dependency injection container. Stop using DI containers FFS.
|
||||
50
vendor/chillerlan/php-settings-container/composer.json
vendored
Normal file
50
vendor/chillerlan/php-settings-container/composer.json
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "chillerlan/php-settings-container",
|
||||
"description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+",
|
||||
"homepage": "https://github.com/chillerlan/php-settings-container",
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"minimum-stability": "stable",
|
||||
"keywords": [
|
||||
"php7", "helper", "container", "settings", "configuration"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Smiley",
|
||||
"email": "smiley@chillerlan.net",
|
||||
"homepage": "https://github.com/codemasher"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/chillerlan/php-settings-container/issues",
|
||||
"source": "https://github.com/chillerlan/php-settings-container"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.4 || ^8.0",
|
||||
"ext-json": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"phan/phan": "^5.3",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"chillerlan\\Settings\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"chillerlan\\SettingsTest\\": "tests/",
|
||||
"chillerlan\\SettingsExamples\\": "examples/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"phpunit": "@php vendor/bin/phpunit",
|
||||
"phan": "@php vendor/bin/phan"
|
||||
},
|
||||
"config": {
|
||||
"lock": false,
|
||||
"sort-packages": true,
|
||||
"platform-check": true
|
||||
}
|
||||
}
|
||||
13
vendor/chillerlan/php-settings-container/docs/Readme.md
vendored
Normal file
13
vendor/chillerlan/php-settings-container/docs/Readme.md
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# Auto generated API documentation
|
||||
|
||||
The API documentation can be auto generated with [phpDocumentor](https://www.phpdoc.org/).
|
||||
There is an [online version available](https://chillerlan.github.io/php-settings-container/) via the [gh-pages branch](https://github.com/chillerlan/php-settings-container/tree/gh-pages) that is [automatically deployed](https://github.com/chillerlan/php-settings-container/deployments) on each push to main.
|
||||
|
||||
Locally created docs will appear in this directory. If you'd like to create local docs, please follow these steps:
|
||||
|
||||
- [download phpDocumentor](https://github.com/phpDocumentor/phpDocumentor/releases) v3+ as .phar archive
|
||||
- run it in the repository root directory:
|
||||
- on Windows `c:\path\to\php.exe c:\path\to\phpDocumentor.phar --config=phpdoc.xml`
|
||||
- on Linux just `php /path/to/phpDocumentor.phar --config=phpdoc.xml`
|
||||
- open [index.html](./index.html) in a browser
|
||||
- profit!
|
||||
51
vendor/chillerlan/php-settings-container/examples/advanced.php
vendored
Normal file
51
vendor/chillerlan/php-settings-container/examples/advanced.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
/**
|
||||
* @created 28.08.2018
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2018 smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\SettingsExamples;
|
||||
|
||||
use chillerlan\Settings\SettingsContainerAbstract;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
// from library #1
|
||||
trait SomeOptions{
|
||||
protected string $foo = '';
|
||||
|
||||
// this method will be called in SettingsContainerAbstract::__construct() after the properties have been set
|
||||
protected function SomeOptions(){
|
||||
// just some constructor stuff...
|
||||
$this->foo = strtoupper($this->foo);
|
||||
}
|
||||
}
|
||||
|
||||
// from library #2
|
||||
trait MoreOptions{
|
||||
protected string $bar = 'whatever'; // provide default values
|
||||
}
|
||||
|
||||
$commonOptions = [
|
||||
// SomeOptions
|
||||
'foo' => 'whatever',
|
||||
// MoreOptions
|
||||
'bar' => 'nothing',
|
||||
];
|
||||
|
||||
// now plug the several library options together to a single object
|
||||
|
||||
/**
|
||||
* @property string $foo
|
||||
* @property string $bar
|
||||
*/
|
||||
class MySettings extends SettingsContainerAbstract{
|
||||
use SomeOptions, MoreOptions; // ...
|
||||
};
|
||||
|
||||
$container = new MySettings($commonOptions);
|
||||
|
||||
var_dump($container->foo); // -> WHATEVER (constructor ran strtoupper on the value)
|
||||
var_dump($container->bar); // -> nothing
|
||||
29
vendor/chillerlan/php-settings-container/examples/simple.php
vendored
Normal file
29
vendor/chillerlan/php-settings-container/examples/simple.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
/**
|
||||
* @created 28.08.2018
|
||||
* @author smiley <smiley@chillerlan.net>
|
||||
* @copyright 2018 smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\SettingsExamples;
|
||||
|
||||
use chillerlan\Settings\SettingsContainerAbstract;
|
||||
|
||||
require_once __DIR__.'/../vendor/autoload.php';
|
||||
|
||||
class MyContainer extends SettingsContainerAbstract{
|
||||
protected $foo;
|
||||
protected $bar;
|
||||
}
|
||||
|
||||
/** @var \chillerlan\Settings\SettingsContainerInterface $container */
|
||||
$container = new MyContainer(['foo' => 'what']);
|
||||
$container->bar = 'foo';
|
||||
|
||||
var_dump($container->toJSON()); // -> {"foo":"what","bar":"foo"}
|
||||
|
||||
// non-existing properties will be ignored:
|
||||
$container->nope = 'what';
|
||||
|
||||
var_dump($container->nope); // -> NULL
|
||||
20
vendor/chillerlan/php-settings-container/phpdoc.xml
vendored
Normal file
20
vendor/chillerlan/php-settings-container/phpdoc.xml
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<phpdoc>
|
||||
<parser>
|
||||
<target>docs</target>
|
||||
<encoding>utf8</encoding>
|
||||
<markers>
|
||||
<item>TODO</item>
|
||||
</markers>
|
||||
</parser>
|
||||
<transformer>
|
||||
<target>docs</target>
|
||||
</transformer>
|
||||
<files>
|
||||
<directory>src</directory>
|
||||
<directory>tests</directory>
|
||||
</files>
|
||||
<transformations>
|
||||
<template name="responsive-twig"/>
|
||||
</transformations>
|
||||
</phpdoc>
|
||||
26
vendor/chillerlan/php-settings-container/phpunit.xml
vendored
Normal file
26
vendor/chillerlan/php-settings-container/phpunit.xml
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
|
||||
bootstrap="vendor/autoload.php"
|
||||
cacheResultFile=".build/phpunit.result.cache"
|
||||
colors="true"
|
||||
verbose="true"
|
||||
>
|
||||
<coverage processUncoveredFiles="true">
|
||||
<include>
|
||||
<directory suffix=".php">./src</directory>
|
||||
</include>
|
||||
<report>
|
||||
<clover outputFile=".build/coverage/clover.xml"/>
|
||||
<xml outputDirectory=".build/coverage/coverage-xml"/>
|
||||
</report>
|
||||
</coverage>
|
||||
<testsuites>
|
||||
<testsuite name="php-settings-container test suite">
|
||||
<directory suffix=".php">./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<logging>
|
||||
<junit outputFile=".build/logs/junit.xml"/>
|
||||
</logging>
|
||||
</phpunit>
|
||||
162
vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php
vendored
Normal file
162
vendor/chillerlan/php-settings-container/src/SettingsContainerAbstract.php
vendored
Normal file
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
/**
|
||||
* Class SettingsContainerAbstract
|
||||
*
|
||||
* @created 28.08.2018
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2018 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\Settings;
|
||||
|
||||
use ReflectionClass, ReflectionProperty;
|
||||
|
||||
use function get_object_vars, json_decode, json_encode, method_exists, property_exists;
|
||||
use const JSON_THROW_ON_ERROR;
|
||||
|
||||
abstract class SettingsContainerAbstract implements SettingsContainerInterface{
|
||||
|
||||
/**
|
||||
* SettingsContainerAbstract constructor.
|
||||
*/
|
||||
public function __construct(iterable $properties = null){
|
||||
|
||||
if(!empty($properties)){
|
||||
$this->fromIterable($properties);
|
||||
}
|
||||
|
||||
$this->construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* calls a method with trait name as replacement constructor for each used trait
|
||||
* (remember pre-php5 classname constructors? yeah, basically this.)
|
||||
*/
|
||||
protected function construct():void{
|
||||
$traits = (new ReflectionClass($this))->getTraits();
|
||||
|
||||
foreach($traits as $trait){
|
||||
$method = $trait->getShortName();
|
||||
|
||||
if(method_exists($this, $method)){
|
||||
$this->{$method}();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __get(string $property){
|
||||
|
||||
if(!property_exists($this, $property) || $this->isPrivate($property)){
|
||||
return null;
|
||||
}
|
||||
|
||||
$method = 'get_'.$property;
|
||||
|
||||
if(method_exists($this, $method)){
|
||||
return $this->{$method}();
|
||||
}
|
||||
|
||||
return $this->{$property};
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __set(string $property, $value):void{
|
||||
|
||||
if(!property_exists($this, $property) || $this->isPrivate($property)){
|
||||
return;
|
||||
}
|
||||
|
||||
$method = 'set_'.$property;
|
||||
|
||||
if(method_exists($this, $method)){
|
||||
$this->{$method}($value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->{$property} = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __isset(string $property):bool{
|
||||
return isset($this->{$property}) && !$this->isPrivate($property);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal Checks if a property is private
|
||||
*/
|
||||
protected function isPrivate(string $property):bool{
|
||||
return (new ReflectionProperty($this, $property))->isPrivate();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __unset(string $property):void{
|
||||
|
||||
if($this->__isset($property)){
|
||||
unset($this->{$property});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function __toString():string{
|
||||
return $this->toJSON();
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function toArray():array{
|
||||
return get_object_vars($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function fromIterable(iterable $properties):SettingsContainerInterface{
|
||||
|
||||
foreach($properties as $key => $value){
|
||||
$this->__set($key, $value);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function toJSON(int $jsonOptions = null):string{
|
||||
return json_encode($this, $jsonOptions ?? 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
public function fromJSON(string $json):SettingsContainerInterface{
|
||||
$data = json_decode($json, true, 512, JSON_THROW_ON_ERROR);
|
||||
|
||||
return $this->fromIterable($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function jsonSerialize():array{
|
||||
return $this->toArray();
|
||||
}
|
||||
|
||||
}
|
||||
74
vendor/chillerlan/php-settings-container/src/SettingsContainerInterface.php
vendored
Normal file
74
vendor/chillerlan/php-settings-container/src/SettingsContainerInterface.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* Interface SettingsContainerInterface
|
||||
*
|
||||
* @created 28.08.2018
|
||||
* @author Smiley <smiley@chillerlan.net>
|
||||
* @copyright 2018 Smiley
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
namespace chillerlan\Settings;
|
||||
|
||||
use JsonSerializable;
|
||||
|
||||
/**
|
||||
* a generic container with magic getter and setter
|
||||
*/
|
||||
interface SettingsContainerInterface extends JsonSerializable{
|
||||
|
||||
/**
|
||||
* Retrieve the value of $property
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function __get(string $property);
|
||||
|
||||
/**
|
||||
* Set $property to $value while avoiding private and non-existing properties
|
||||
*
|
||||
* @param string $property
|
||||
* @param mixed $value
|
||||
*/
|
||||
public function __set(string $property, $value):void;
|
||||
|
||||
/**
|
||||
* Checks if $property is set (aka. not null), excluding private properties
|
||||
*/
|
||||
public function __isset(string $property):bool;
|
||||
|
||||
/**
|
||||
* Unsets $property while avoiding private and non-existing properties
|
||||
*/
|
||||
public function __unset(string $property):void;
|
||||
|
||||
/**
|
||||
* @see SettingsContainerInterface::toJSON()
|
||||
*/
|
||||
public function __toString():string;
|
||||
|
||||
/**
|
||||
* Returns an array representation of the settings object
|
||||
*/
|
||||
public function toArray():array;
|
||||
|
||||
/**
|
||||
* Sets properties from a given iterable
|
||||
*/
|
||||
public function fromIterable(iterable $properties):SettingsContainerInterface;
|
||||
|
||||
/**
|
||||
* Returns a JSON representation of the settings object
|
||||
* @see \json_encode()
|
||||
*/
|
||||
public function toJSON(int $jsonOptions = null):string;
|
||||
|
||||
/**
|
||||
* Sets properties from a given JSON string
|
||||
*
|
||||
* @throws \Exception
|
||||
* @throws \JsonException
|
||||
*/
|
||||
public function fromJSON(string $json):SettingsContainerInterface;
|
||||
|
||||
}
|
||||
12
vendor/composer/ClassLoader.php
vendored
12
vendor/composer/ClassLoader.php
vendored
@@ -429,7 +429,8 @@ class ClassLoader
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
(self::$includeFile)($file);
|
||||
$includeFile = self::$includeFile;
|
||||
$includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -560,7 +561,10 @@ class ClassLoader
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function initializeIncludeClosure(): void
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
private static function initializeIncludeClosure()
|
||||
{
|
||||
if (self::$includeFile !== null) {
|
||||
return;
|
||||
@@ -574,8 +578,8 @@ class ClassLoader
|
||||
* @param string $file
|
||||
* @return void
|
||||
*/
|
||||
self::$includeFile = static function($file) {
|
||||
self::$includeFile = \Closure::bind(static function($file) {
|
||||
include $file;
|
||||
};
|
||||
}, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
49
vendor/composer/autoload_classmap.php
vendored
49
vendor/composer/autoload_classmap.php
vendored
@@ -379,6 +379,27 @@ return array(
|
||||
'OAuth2\\TokenType\\Bearer' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php',
|
||||
'OAuth2\\TokenType\\Mac' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php',
|
||||
'OAuth2\\TokenType\\TokenTypeInterface' => $vendorDir . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/TokenTypeInterface.php',
|
||||
'OTPHP\\Factory' => $vendorDir . '/spomky-labs/otphp/src/Factory.php',
|
||||
'OTPHP\\FactoryInterface' => $vendorDir . '/spomky-labs/otphp/src/FactoryInterface.php',
|
||||
'OTPHP\\HOTP' => $vendorDir . '/spomky-labs/otphp/src/HOTP.php',
|
||||
'OTPHP\\HOTPInterface' => $vendorDir . '/spomky-labs/otphp/src/HOTPInterface.php',
|
||||
'OTPHP\\OTP' => $vendorDir . '/spomky-labs/otphp/src/OTP.php',
|
||||
'OTPHP\\OTPInterface' => $vendorDir . '/spomky-labs/otphp/src/OTPInterface.php',
|
||||
'OTPHP\\ParameterTrait' => $vendorDir . '/spomky-labs/otphp/src/ParameterTrait.php',
|
||||
'OTPHP\\TOTP' => $vendorDir . '/spomky-labs/otphp/src/TOTP.php',
|
||||
'OTPHP\\TOTPInterface' => $vendorDir . '/spomky-labs/otphp/src/TOTPInterface.php',
|
||||
'OTPHP\\Url' => $vendorDir . '/spomky-labs/otphp/src/Url.php',
|
||||
'ParagonIE\\ConstantTime\\Base32' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32.php',
|
||||
'ParagonIE\\ConstantTime\\Base32Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Base32Hex.php',
|
||||
'ParagonIE\\ConstantTime\\Base64' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64.php',
|
||||
'ParagonIE\\ConstantTime\\Base64DotSlash' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64DotSlash.php',
|
||||
'ParagonIE\\ConstantTime\\Base64DotSlashOrdered' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php',
|
||||
'ParagonIE\\ConstantTime\\Base64UrlSafe' => $vendorDir . '/paragonie/constant_time_encoding/src/Base64UrlSafe.php',
|
||||
'ParagonIE\\ConstantTime\\Binary' => $vendorDir . '/paragonie/constant_time_encoding/src/Binary.php',
|
||||
'ParagonIE\\ConstantTime\\EncoderInterface' => $vendorDir . '/paragonie/constant_time_encoding/src/EncoderInterface.php',
|
||||
'ParagonIE\\ConstantTime\\Encoding' => $vendorDir . '/paragonie/constant_time_encoding/src/Encoding.php',
|
||||
'ParagonIE\\ConstantTime\\Hex' => $vendorDir . '/paragonie/constant_time_encoding/src/Hex.php',
|
||||
'ParagonIE\\ConstantTime\\RFC4648' => $vendorDir . '/paragonie/constant_time_encoding/src/RFC4648.php',
|
||||
'Psr\\Log\\AbstractLogger' => $vendorDir . '/psr/log/src/AbstractLogger.php',
|
||||
'Psr\\Log\\InvalidArgumentException' => $vendorDir . '/psr/log/src/InvalidArgumentException.php',
|
||||
'Psr\\Log\\LogLevel' => $vendorDir . '/psr/log/src/LogLevel.php',
|
||||
@@ -1198,6 +1219,7 @@ return array(
|
||||
'Zotlabs\\Lib\\Libzotdir' => $baseDir . '/Zotlabs/Lib/Libzotdir.php',
|
||||
'Zotlabs\\Lib\\MarkdownSoap' => $baseDir . '/Zotlabs/Lib/MarkdownSoap.php',
|
||||
'Zotlabs\\Lib\\MessageFilter' => $baseDir . '/Zotlabs/Lib/MessageFilter.php',
|
||||
'Zotlabs\\Lib\\ObjCache' => $baseDir . '/Zotlabs/Lib/ObjCache.php',
|
||||
'Zotlabs\\Lib\\PConfig' => $baseDir . '/Zotlabs/Lib/PConfig.php',
|
||||
'Zotlabs\\Lib\\Permcat' => $baseDir . '/Zotlabs/Lib/Permcat.php',
|
||||
'Zotlabs\\Lib\\PermissionDescription' => $baseDir . '/Zotlabs/Lib/PermissionDescription.php',
|
||||
@@ -1388,6 +1410,7 @@ return array(
|
||||
'Zotlabs\\Module\\Settings\\Featured' => $baseDir . '/Zotlabs/Module/Settings/Featured.php',
|
||||
'Zotlabs\\Module\\Settings\\Features' => $baseDir . '/Zotlabs/Module/Settings/Features.php',
|
||||
'Zotlabs\\Module\\Settings\\Manage' => $baseDir . '/Zotlabs/Module/Settings/Manage.php',
|
||||
'Zotlabs\\Module\\Settings\\Multifactor' => $baseDir . '/Zotlabs/Module/Settings/Multifactor.php',
|
||||
'Zotlabs\\Module\\Settings\\Network' => $baseDir . '/Zotlabs/Module/Settings/Network.php',
|
||||
'Zotlabs\\Module\\Settings\\Photos' => $baseDir . '/Zotlabs/Module/Settings/Photos.php',
|
||||
'Zotlabs\\Module\\Settings\\Privacy' => $baseDir . '/Zotlabs/Module/Settings/Privacy.php',
|
||||
@@ -1415,6 +1438,7 @@ return array(
|
||||
'Zotlabs\\Module\\Toggle_safesearch' => $baseDir . '/Zotlabs/Module/Toggle_safesearch.php',
|
||||
'Zotlabs\\Module\\Token' => $baseDir . '/Zotlabs/Module/Token.php',
|
||||
'Zotlabs\\Module\\Tokens' => $baseDir . '/Zotlabs/Module/Tokens.php',
|
||||
'Zotlabs\\Module\\Totp_check' => $baseDir . '/Zotlabs/Module/Totp_check.php',
|
||||
'Zotlabs\\Module\\Uexport' => $baseDir . '/Zotlabs/Module/Uexport.php',
|
||||
'Zotlabs\\Module\\Update' => $baseDir . '/Zotlabs/Module/Update.php',
|
||||
'Zotlabs\\Module\\Userinfo' => $baseDir . '/Zotlabs/Module/Userinfo.php',
|
||||
@@ -1787,6 +1811,31 @@ return array(
|
||||
'Zotlabs\\Zot6\\IHandler' => $baseDir . '/Zotlabs/Zot6/IHandler.php',
|
||||
'Zotlabs\\Zot6\\Receiver' => $baseDir . '/Zotlabs/Zot6/Receiver.php',
|
||||
'Zotlabs\\Zot6\\Zot6Handler' => $baseDir . '/Zotlabs/Zot6/Zot6Handler.php',
|
||||
'chillerlan\\QRCode\\Data\\AlphaNum' => $vendorDir . '/chillerlan/php-qrcode/src/Data/AlphaNum.php',
|
||||
'chillerlan\\QRCode\\Data\\Byte' => $vendorDir . '/chillerlan/php-qrcode/src/Data/Byte.php',
|
||||
'chillerlan\\QRCode\\Data\\Kanji' => $vendorDir . '/chillerlan/php-qrcode/src/Data/Kanji.php',
|
||||
'chillerlan\\QRCode\\Data\\MaskPatternTester' => $vendorDir . '/chillerlan/php-qrcode/src/Data/MaskPatternTester.php',
|
||||
'chillerlan\\QRCode\\Data\\Number' => $vendorDir . '/chillerlan/php-qrcode/src/Data/Number.php',
|
||||
'chillerlan\\QRCode\\Data\\QRCodeDataException' => $vendorDir . '/chillerlan/php-qrcode/src/Data/QRCodeDataException.php',
|
||||
'chillerlan\\QRCode\\Data\\QRDataAbstract' => $vendorDir . '/chillerlan/php-qrcode/src/Data/QRDataAbstract.php',
|
||||
'chillerlan\\QRCode\\Data\\QRDataInterface' => $vendorDir . '/chillerlan/php-qrcode/src/Data/QRDataInterface.php',
|
||||
'chillerlan\\QRCode\\Data\\QRMatrix' => $vendorDir . '/chillerlan/php-qrcode/src/Data/QRMatrix.php',
|
||||
'chillerlan\\QRCode\\Helpers\\BitBuffer' => $vendorDir . '/chillerlan/php-qrcode/src/Helpers/BitBuffer.php',
|
||||
'chillerlan\\QRCode\\Helpers\\Polynomial' => $vendorDir . '/chillerlan/php-qrcode/src/Helpers/Polynomial.php',
|
||||
'chillerlan\\QRCode\\Output\\QRCodeOutputException' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QRCodeOutputException.php',
|
||||
'chillerlan\\QRCode\\Output\\QRFpdf' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QRFpdf.php',
|
||||
'chillerlan\\QRCode\\Output\\QRImage' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QRImage.php',
|
||||
'chillerlan\\QRCode\\Output\\QRImagick' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QRImagick.php',
|
||||
'chillerlan\\QRCode\\Output\\QRMarkup' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QRMarkup.php',
|
||||
'chillerlan\\QRCode\\Output\\QROutputAbstract' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QROutputAbstract.php',
|
||||
'chillerlan\\QRCode\\Output\\QROutputInterface' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QROutputInterface.php',
|
||||
'chillerlan\\QRCode\\Output\\QRString' => $vendorDir . '/chillerlan/php-qrcode/src/Output/QRString.php',
|
||||
'chillerlan\\QRCode\\QRCode' => $vendorDir . '/chillerlan/php-qrcode/src/QRCode.php',
|
||||
'chillerlan\\QRCode\\QRCodeException' => $vendorDir . '/chillerlan/php-qrcode/src/QRCodeException.php',
|
||||
'chillerlan\\QRCode\\QROptions' => $vendorDir . '/chillerlan/php-qrcode/src/QROptions.php',
|
||||
'chillerlan\\QRCode\\QROptionsTrait' => $vendorDir . '/chillerlan/php-qrcode/src/QROptionsTrait.php',
|
||||
'chillerlan\\Settings\\SettingsContainerAbstract' => $vendorDir . '/chillerlan/php-settings-container/src/SettingsContainerAbstract.php',
|
||||
'chillerlan\\Settings\\SettingsContainerInterface' => $vendorDir . '/chillerlan/php-settings-container/src/SettingsContainerInterface.php',
|
||||
'phpseclib\\Crypt\\AES' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php',
|
||||
'phpseclib\\Crypt\\Base' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php',
|
||||
'phpseclib\\Crypt\\Blowfish' => $vendorDir . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php',
|
||||
|
||||
4
vendor/composer/autoload_psr4.php
vendored
4
vendor/composer/autoload_psr4.php
vendored
@@ -8,6 +8,8 @@ $baseDir = dirname($vendorDir);
|
||||
return array(
|
||||
'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku', $vendorDir . '/voku/stop-words/src/voku'),
|
||||
'phpseclib\\' => array($vendorDir . '/phpseclib/phpseclib/phpseclib'),
|
||||
'chillerlan\\Settings\\' => array($vendorDir . '/chillerlan/php-settings-container/src'),
|
||||
'chillerlan\\QRCode\\' => array($vendorDir . '/chillerlan/php-qrcode/src'),
|
||||
'Zotlabs\\' => array($baseDir . '/Zotlabs'),
|
||||
'Symfony\\Polyfill\\Php81\\' => array($vendorDir . '/symfony/polyfill-php81'),
|
||||
'SimplePie\\' => array($vendorDir . '/simplepie/simplepie/src'),
|
||||
@@ -23,6 +25,8 @@ return array(
|
||||
'Ramsey\\Uuid\\' => array($vendorDir . '/ramsey/uuid/src'),
|
||||
'Ramsey\\Collection\\' => array($vendorDir . '/ramsey/collection/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/src'),
|
||||
'ParagonIE\\ConstantTime\\' => array($vendorDir . '/paragonie/constant_time_encoding/src'),
|
||||
'OTPHP\\' => array($vendorDir . '/spomky-labs/otphp/src'),
|
||||
'Michelf\\' => array($vendorDir . '/michelf/php-markdown/Michelf'),
|
||||
'League\\HTMLToMarkdown\\' => array($vendorDir . '/league/html-to-markdown/src'),
|
||||
'ID3Parser\\' => array($vendorDir . '/lukasreschke/id3parser/src'),
|
||||
|
||||
6
vendor/composer/autoload_real.php
vendored
6
vendor/composer/autoload_real.php
vendored
@@ -38,15 +38,15 @@ class ComposerAutoloaderInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
$loader->register(true);
|
||||
|
||||
$filesToLoad = \Composer\Autoload\ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d::$files;
|
||||
$requireFile = static function ($fileIdentifier, $file) {
|
||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
||||
|
||||
require $file;
|
||||
}
|
||||
};
|
||||
}, null, null);
|
||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
||||
($requireFile)($fileIdentifier, $file);
|
||||
$requireFile($fileIdentifier, $file);
|
||||
}
|
||||
|
||||
return $loader;
|
||||
|
||||
75
vendor/composer/autoload_static.php
vendored
75
vendor/composer/autoload_static.php
vendored
@@ -29,6 +29,11 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
array (
|
||||
'phpseclib\\' => 10,
|
||||
),
|
||||
'c' =>
|
||||
array (
|
||||
'chillerlan\\Settings\\' => 20,
|
||||
'chillerlan\\QRCode\\' => 18,
|
||||
),
|
||||
'Z' =>
|
||||
array (
|
||||
'Zotlabs\\' => 8,
|
||||
@@ -55,6 +60,11 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\Log\\' => 8,
|
||||
'ParagonIE\\ConstantTime\\' => 23,
|
||||
),
|
||||
'O' =>
|
||||
array (
|
||||
'OTPHP\\' => 6,
|
||||
),
|
||||
'M' =>
|
||||
array (
|
||||
@@ -92,6 +102,14 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib',
|
||||
),
|
||||
'chillerlan\\Settings\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/chillerlan/php-settings-container/src',
|
||||
),
|
||||
'chillerlan\\QRCode\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/chillerlan/php-qrcode/src',
|
||||
),
|
||||
'Zotlabs\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/../..' . '/Zotlabs',
|
||||
@@ -152,6 +170,14 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/log/src',
|
||||
),
|
||||
'ParagonIE\\ConstantTime\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src',
|
||||
),
|
||||
'OTPHP\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/spomky-labs/otphp/src',
|
||||
),
|
||||
'Michelf\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/michelf/php-markdown/Michelf',
|
||||
@@ -590,6 +616,27 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'OAuth2\\TokenType\\Bearer' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Bearer.php',
|
||||
'OAuth2\\TokenType\\Mac' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/Mac.php',
|
||||
'OAuth2\\TokenType\\TokenTypeInterface' => __DIR__ . '/..' . '/bshaffer/oauth2-server-php/src/OAuth2/TokenType/TokenTypeInterface.php',
|
||||
'OTPHP\\Factory' => __DIR__ . '/..' . '/spomky-labs/otphp/src/Factory.php',
|
||||
'OTPHP\\FactoryInterface' => __DIR__ . '/..' . '/spomky-labs/otphp/src/FactoryInterface.php',
|
||||
'OTPHP\\HOTP' => __DIR__ . '/..' . '/spomky-labs/otphp/src/HOTP.php',
|
||||
'OTPHP\\HOTPInterface' => __DIR__ . '/..' . '/spomky-labs/otphp/src/HOTPInterface.php',
|
||||
'OTPHP\\OTP' => __DIR__ . '/..' . '/spomky-labs/otphp/src/OTP.php',
|
||||
'OTPHP\\OTPInterface' => __DIR__ . '/..' . '/spomky-labs/otphp/src/OTPInterface.php',
|
||||
'OTPHP\\ParameterTrait' => __DIR__ . '/..' . '/spomky-labs/otphp/src/ParameterTrait.php',
|
||||
'OTPHP\\TOTP' => __DIR__ . '/..' . '/spomky-labs/otphp/src/TOTP.php',
|
||||
'OTPHP\\TOTPInterface' => __DIR__ . '/..' . '/spomky-labs/otphp/src/TOTPInterface.php',
|
||||
'OTPHP\\Url' => __DIR__ . '/..' . '/spomky-labs/otphp/src/Url.php',
|
||||
'ParagonIE\\ConstantTime\\Base32' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32.php',
|
||||
'ParagonIE\\ConstantTime\\Base32Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base32Hex.php',
|
||||
'ParagonIE\\ConstantTime\\Base64' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64.php',
|
||||
'ParagonIE\\ConstantTime\\Base64DotSlash' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64DotSlash.php',
|
||||
'ParagonIE\\ConstantTime\\Base64DotSlashOrdered' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php',
|
||||
'ParagonIE\\ConstantTime\\Base64UrlSafe' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Base64UrlSafe.php',
|
||||
'ParagonIE\\ConstantTime\\Binary' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Binary.php',
|
||||
'ParagonIE\\ConstantTime\\EncoderInterface' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/EncoderInterface.php',
|
||||
'ParagonIE\\ConstantTime\\Encoding' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Encoding.php',
|
||||
'ParagonIE\\ConstantTime\\Hex' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/Hex.php',
|
||||
'ParagonIE\\ConstantTime\\RFC4648' => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src/RFC4648.php',
|
||||
'Psr\\Log\\AbstractLogger' => __DIR__ . '/..' . '/psr/log/src/AbstractLogger.php',
|
||||
'Psr\\Log\\InvalidArgumentException' => __DIR__ . '/..' . '/psr/log/src/InvalidArgumentException.php',
|
||||
'Psr\\Log\\LogLevel' => __DIR__ . '/..' . '/psr/log/src/LogLevel.php',
|
||||
@@ -1409,6 +1456,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'Zotlabs\\Lib\\Libzotdir' => __DIR__ . '/../..' . '/Zotlabs/Lib/Libzotdir.php',
|
||||
'Zotlabs\\Lib\\MarkdownSoap' => __DIR__ . '/../..' . '/Zotlabs/Lib/MarkdownSoap.php',
|
||||
'Zotlabs\\Lib\\MessageFilter' => __DIR__ . '/../..' . '/Zotlabs/Lib/MessageFilter.php',
|
||||
'Zotlabs\\Lib\\ObjCache' => __DIR__ . '/../..' . '/Zotlabs/Lib/ObjCache.php',
|
||||
'Zotlabs\\Lib\\PConfig' => __DIR__ . '/../..' . '/Zotlabs/Lib/PConfig.php',
|
||||
'Zotlabs\\Lib\\Permcat' => __DIR__ . '/../..' . '/Zotlabs/Lib/Permcat.php',
|
||||
'Zotlabs\\Lib\\PermissionDescription' => __DIR__ . '/../..' . '/Zotlabs/Lib/PermissionDescription.php',
|
||||
@@ -1599,6 +1647,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'Zotlabs\\Module\\Settings\\Featured' => __DIR__ . '/../..' . '/Zotlabs/Module/Settings/Featured.php',
|
||||
'Zotlabs\\Module\\Settings\\Features' => __DIR__ . '/../..' . '/Zotlabs/Module/Settings/Features.php',
|
||||
'Zotlabs\\Module\\Settings\\Manage' => __DIR__ . '/../..' . '/Zotlabs/Module/Settings/Manage.php',
|
||||
'Zotlabs\\Module\\Settings\\Multifactor' => __DIR__ . '/../..' . '/Zotlabs/Module/Settings/Multifactor.php',
|
||||
'Zotlabs\\Module\\Settings\\Network' => __DIR__ . '/../..' . '/Zotlabs/Module/Settings/Network.php',
|
||||
'Zotlabs\\Module\\Settings\\Photos' => __DIR__ . '/../..' . '/Zotlabs/Module/Settings/Photos.php',
|
||||
'Zotlabs\\Module\\Settings\\Privacy' => __DIR__ . '/../..' . '/Zotlabs/Module/Settings/Privacy.php',
|
||||
@@ -1626,6 +1675,7 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'Zotlabs\\Module\\Toggle_safesearch' => __DIR__ . '/../..' . '/Zotlabs/Module/Toggle_safesearch.php',
|
||||
'Zotlabs\\Module\\Token' => __DIR__ . '/../..' . '/Zotlabs/Module/Token.php',
|
||||
'Zotlabs\\Module\\Tokens' => __DIR__ . '/../..' . '/Zotlabs/Module/Tokens.php',
|
||||
'Zotlabs\\Module\\Totp_check' => __DIR__ . '/../..' . '/Zotlabs/Module/Totp_check.php',
|
||||
'Zotlabs\\Module\\Uexport' => __DIR__ . '/../..' . '/Zotlabs/Module/Uexport.php',
|
||||
'Zotlabs\\Module\\Update' => __DIR__ . '/../..' . '/Zotlabs/Module/Update.php',
|
||||
'Zotlabs\\Module\\Userinfo' => __DIR__ . '/../..' . '/Zotlabs/Module/Userinfo.php',
|
||||
@@ -1998,6 +2048,31 @@ class ComposerStaticInit7b34d7e50a62201ec5d5e526a5b8b35d
|
||||
'Zotlabs\\Zot6\\IHandler' => __DIR__ . '/../..' . '/Zotlabs/Zot6/IHandler.php',
|
||||
'Zotlabs\\Zot6\\Receiver' => __DIR__ . '/../..' . '/Zotlabs/Zot6/Receiver.php',
|
||||
'Zotlabs\\Zot6\\Zot6Handler' => __DIR__ . '/../..' . '/Zotlabs/Zot6/Zot6Handler.php',
|
||||
'chillerlan\\QRCode\\Data\\AlphaNum' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/AlphaNum.php',
|
||||
'chillerlan\\QRCode\\Data\\Byte' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/Byte.php',
|
||||
'chillerlan\\QRCode\\Data\\Kanji' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/Kanji.php',
|
||||
'chillerlan\\QRCode\\Data\\MaskPatternTester' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/MaskPatternTester.php',
|
||||
'chillerlan\\QRCode\\Data\\Number' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/Number.php',
|
||||
'chillerlan\\QRCode\\Data\\QRCodeDataException' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/QRCodeDataException.php',
|
||||
'chillerlan\\QRCode\\Data\\QRDataAbstract' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/QRDataAbstract.php',
|
||||
'chillerlan\\QRCode\\Data\\QRDataInterface' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/QRDataInterface.php',
|
||||
'chillerlan\\QRCode\\Data\\QRMatrix' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Data/QRMatrix.php',
|
||||
'chillerlan\\QRCode\\Helpers\\BitBuffer' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Helpers/BitBuffer.php',
|
||||
'chillerlan\\QRCode\\Helpers\\Polynomial' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Helpers/Polynomial.php',
|
||||
'chillerlan\\QRCode\\Output\\QRCodeOutputException' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QRCodeOutputException.php',
|
||||
'chillerlan\\QRCode\\Output\\QRFpdf' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QRFpdf.php',
|
||||
'chillerlan\\QRCode\\Output\\QRImage' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QRImage.php',
|
||||
'chillerlan\\QRCode\\Output\\QRImagick' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QRImagick.php',
|
||||
'chillerlan\\QRCode\\Output\\QRMarkup' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QRMarkup.php',
|
||||
'chillerlan\\QRCode\\Output\\QROutputAbstract' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QROutputAbstract.php',
|
||||
'chillerlan\\QRCode\\Output\\QROutputInterface' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QROutputInterface.php',
|
||||
'chillerlan\\QRCode\\Output\\QRString' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/Output/QRString.php',
|
||||
'chillerlan\\QRCode\\QRCode' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/QRCode.php',
|
||||
'chillerlan\\QRCode\\QRCodeException' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/QRCodeException.php',
|
||||
'chillerlan\\QRCode\\QROptions' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/QROptions.php',
|
||||
'chillerlan\\QRCode\\QROptionsTrait' => __DIR__ . '/..' . '/chillerlan/php-qrcode/src/QROptionsTrait.php',
|
||||
'chillerlan\\Settings\\SettingsContainerAbstract' => __DIR__ . '/..' . '/chillerlan/php-settings-container/src/SettingsContainerAbstract.php',
|
||||
'chillerlan\\Settings\\SettingsContainerInterface' => __DIR__ . '/..' . '/chillerlan/php-settings-container/src/SettingsContainerInterface.php',
|
||||
'phpseclib\\Crypt\\AES' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/AES.php',
|
||||
'phpseclib\\Crypt\\Base' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Base.php',
|
||||
'phpseclib\\Crypt\\Blowfish' => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib/Crypt/Blowfish.php',
|
||||
|
||||
301
vendor/composer/installed.json
vendored
301
vendor/composer/installed.json
vendored
@@ -197,6 +197,154 @@
|
||||
},
|
||||
"install-path": "../bshaffer/oauth2-server-php"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
"version": "4.3.4",
|
||||
"version_normalized": "4.3.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/chillerlan/php-qrcode.git",
|
||||
"reference": "2ca4bf5ae048af1981d1023ee42a0a2a9d51e51d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/chillerlan/php-qrcode/zipball/2ca4bf5ae048af1981d1023ee42a0a2a9d51e51d",
|
||||
"reference": "2ca4bf5ae048af1981d1023ee42a0a2a9d51e51d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"chillerlan/php-settings-container": "^2.1.4",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phan/phan": "^5.3",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"setasign/fpdf": "^1.8.2"
|
||||
},
|
||||
"suggest": {
|
||||
"chillerlan/php-authenticator": "Yet another Google authenticator! Also creates URIs for mobile apps.",
|
||||
"setasign/fpdf": "Required to use the QR FPDF output."
|
||||
},
|
||||
"time": "2022-07-25T09:12:45+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"chillerlan\\QRCode\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Kazuhiko Arase",
|
||||
"homepage": "https://github.com/kazuhikoarase"
|
||||
},
|
||||
{
|
||||
"name": "Smiley",
|
||||
"email": "smiley@chillerlan.net",
|
||||
"homepage": "https://github.com/codemasher"
|
||||
},
|
||||
{
|
||||
"name": "Contributors",
|
||||
"homepage": "https://github.com/chillerlan/php-qrcode/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A QR code generator. PHP 7.4+",
|
||||
"homepage": "https://github.com/chillerlan/php-qrcode",
|
||||
"keywords": [
|
||||
"phpqrcode",
|
||||
"qr",
|
||||
"qr code",
|
||||
"qrcode",
|
||||
"qrcode-generator"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/chillerlan/php-qrcode/issues",
|
||||
"source": "https://github.com/chillerlan/php-qrcode/tree/4.3.4"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://ko-fi.com/codemasher",
|
||||
"type": "ko_fi"
|
||||
}
|
||||
],
|
||||
"install-path": "../chillerlan/php-qrcode"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-settings-container",
|
||||
"version": "2.1.4",
|
||||
"version_normalized": "2.1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/chillerlan/php-settings-container.git",
|
||||
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
|
||||
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.4 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phan/phan": "^5.3",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"time": "2022-07-05T22:32:14+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"chillerlan\\Settings\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Smiley",
|
||||
"email": "smiley@chillerlan.net",
|
||||
"homepage": "https://github.com/codemasher"
|
||||
}
|
||||
],
|
||||
"description": "A container class for immutable settings objects. Not a DI container. PHP 7.4+",
|
||||
"homepage": "https://github.com/chillerlan/php-settings-container",
|
||||
"keywords": [
|
||||
"PHP7",
|
||||
"Settings",
|
||||
"configuration",
|
||||
"container",
|
||||
"helper"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/chillerlan/php-settings-container/issues",
|
||||
"source": "https://github.com/chillerlan/php-settings-container"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.com/donate?hosted_button_id=WLYUNAT9ZTJZ4",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://ko-fi.com/codemasher",
|
||||
"type": "ko_fi"
|
||||
}
|
||||
],
|
||||
"install-path": "../chillerlan/php-settings-container"
|
||||
},
|
||||
{
|
||||
"name": "commerceguys/intl",
|
||||
"version": "v1.1.1",
|
||||
@@ -618,6 +766,76 @@
|
||||
},
|
||||
"install-path": "../michelf/php-markdown"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v2.6.3",
|
||||
"version_normalized": "2.6.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/paragonie/constant_time_encoding.git",
|
||||
"reference": "58c3f47f650c94ec05a151692652a868995d2938"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/paragonie/constant_time_encoding/zipball/58c3f47f650c94ec05a151692652a868995d2938",
|
||||
"reference": "58c3f47f650c94ec05a151692652a868995d2938",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6|^7|^8|^9",
|
||||
"vimeo/psalm": "^1|^2|^3|^4"
|
||||
},
|
||||
"time": "2022-06-14T06:56:20+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ParagonIE\\ConstantTime\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com",
|
||||
"role": "Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "Steve 'Sc00bz' Thomas",
|
||||
"email": "steve@tobtu.com",
|
||||
"homepage": "https://www.tobtu.com",
|
||||
"role": "Original Developer"
|
||||
}
|
||||
],
|
||||
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
|
||||
"keywords": [
|
||||
"base16",
|
||||
"base32",
|
||||
"base32_decode",
|
||||
"base32_encode",
|
||||
"base64",
|
||||
"base64_decode",
|
||||
"base64_encode",
|
||||
"bin2hex",
|
||||
"encoding",
|
||||
"hex",
|
||||
"hex2bin",
|
||||
"rfc4648"
|
||||
],
|
||||
"support": {
|
||||
"email": "info@paragonie.com",
|
||||
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
|
||||
"source": "https://github.com/paragonie/constant_time_encoding"
|
||||
},
|
||||
"install-path": "../paragonie/constant_time_encoding"
|
||||
},
|
||||
{
|
||||
"name": "pear/text_languagedetect",
|
||||
"version": "v1.0.1",
|
||||
@@ -1634,6 +1852,89 @@
|
||||
},
|
||||
"install-path": "../smarty/smarty"
|
||||
},
|
||||
{
|
||||
"name": "spomky-labs/otphp",
|
||||
"version": "11.1.0",
|
||||
"version_normalized": "11.1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Spomky-Labs/otphp.git",
|
||||
"reference": "4849ac1aa560bfc56c0d1534b0d72532da4665ab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Spomky-Labs/otphp/zipball/4849ac1aa560bfc56c0d1534b0d72532da4665ab",
|
||||
"reference": "4849ac1aa560bfc56c0d1534b0d72532da4665ab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"paragonie/constant_time_encoding": "^2.0",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"ekino/phpstan-banned-code": "^1.0",
|
||||
"infection/infection": "^0.26",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3",
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5.26",
|
||||
"qossmic/deptrac-shim": "^1.0",
|
||||
"rector/rector": "^0.14",
|
||||
"symfony/phpunit-bridge": "^6.1",
|
||||
"symplify/easy-coding-standard": "^11.0"
|
||||
},
|
||||
"time": "2022-11-11T12:57:17+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"OTPHP\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Florent Morselli",
|
||||
"homepage": "https://github.com/Spomky"
|
||||
},
|
||||
{
|
||||
"name": "All contributors",
|
||||
"homepage": "https://github.com/Spomky-Labs/otphp/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
|
||||
"homepage": "https://github.com/Spomky-Labs/otphp",
|
||||
"keywords": [
|
||||
"FreeOTP",
|
||||
"RFC 4226",
|
||||
"RFC 6238",
|
||||
"google authenticator",
|
||||
"hotp",
|
||||
"otp",
|
||||
"totp"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Spomky-Labs/otphp/issues",
|
||||
"source": "https://github.com/Spomky-Labs/otphp/tree/11.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/Spomky",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/FlorentMorselli",
|
||||
"type": "patreon"
|
||||
}
|
||||
],
|
||||
"install-path": "../spomky-labs/otphp"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php81",
|
||||
"version": "v1.26.0",
|
||||
|
||||
40
vendor/composer/installed.php
vendored
40
vendor/composer/installed.php
vendored
@@ -3,7 +3,7 @@
|
||||
'name' => 'zotlabs/hubzilla',
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => 'c3d3dc9d92d14dbcfbaf39c4cc9ad4c120812a3d',
|
||||
'reference' => 'd43a56614cd93982d19f4f82aae6e62f9ca533a9',
|
||||
'type' => 'application',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -37,6 +37,24 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'chillerlan/php-qrcode' => array(
|
||||
'pretty_version' => '4.3.4',
|
||||
'version' => '4.3.4.0',
|
||||
'reference' => '2ca4bf5ae048af1981d1023ee42a0a2a9d51e51d',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../chillerlan/php-qrcode',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'chillerlan/php-settings-container' => array(
|
||||
'pretty_version' => '2.1.4',
|
||||
'version' => '2.1.4.0',
|
||||
'reference' => '1beb7df3c14346d4344b0b2e12f6f9a74feabd4a',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../chillerlan/php-settings-container',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'commerceguys/intl' => array(
|
||||
'pretty_version' => 'v1.1.1',
|
||||
'version' => '1.1.1.0',
|
||||
@@ -100,6 +118,15 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'paragonie/constant_time_encoding' => array(
|
||||
'pretty_version' => 'v2.6.3',
|
||||
'version' => '2.6.3.0',
|
||||
'reference' => '58c3f47f650c94ec05a151692652a868995d2938',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../paragonie/constant_time_encoding',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'pear/text_languagedetect' => array(
|
||||
'pretty_version' => 'v1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
@@ -223,6 +250,15 @@
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'spomky-labs/otphp' => array(
|
||||
'pretty_version' => '11.1.0',
|
||||
'version' => '11.1.0.0',
|
||||
'reference' => '4849ac1aa560bfc56c0d1534b0d72532da4665ab',
|
||||
'type' => 'library',
|
||||
'install_path' => __DIR__ . '/../spomky-labs/otphp',
|
||||
'aliases' => array(),
|
||||
'dev_requirement' => false,
|
||||
),
|
||||
'symfony/polyfill-php81' => array(
|
||||
'pretty_version' => 'v1.26.0',
|
||||
'version' => '1.26.0.0',
|
||||
@@ -268,7 +304,7 @@
|
||||
'zotlabs/hubzilla' => array(
|
||||
'pretty_version' => 'dev-master',
|
||||
'version' => 'dev-master',
|
||||
'reference' => 'c3d3dc9d92d14dbcfbaf39c4cc9ad4c120812a3d',
|
||||
'reference' => 'd43a56614cd93982d19f4f82aae6e62f9ca533a9',
|
||||
'type' => 'application',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
4
vendor/composer/platform_check.php
vendored
4
vendor/composer/platform_check.php
vendored
@@ -4,8 +4,8 @@
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 80002)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.2". You are running ' . PHP_VERSION . '.';
|
||||
if (!(PHP_VERSION_ID >= 80100)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
|
||||
48
vendor/paragonie/constant_time_encoding/LICENSE.txt
vendored
Normal file
48
vendor/paragonie/constant_time_encoding/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 - 2022 Paragon Initiative Enterprises
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
This library was based on the work of Steve "Sc00bz" Thomas.
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Steve Thomas
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
84
vendor/paragonie/constant_time_encoding/README.md
vendored
Normal file
84
vendor/paragonie/constant_time_encoding/README.md
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
# Constant-Time Encoding
|
||||
|
||||
[](https://github.com/paragonie/constant_time_encoding/actions)
|
||||
[](https://packagist.org/packages/paragonie/constant_time_encoding)
|
||||
[](https://packagist.org/packages/paragonie/constant_time_encoding)
|
||||
[](https://packagist.org/packages/paragonie/constant_time_encoding)
|
||||
[](https://packagist.org/packages/paragonie/constant_time_encoding)
|
||||
|
||||
Based on the [constant-time base64 implementation made by Steve "Sc00bz" Thomas](https://github.com/Sc00bz/ConstTimeEncoding),
|
||||
this library aims to offer character encoding functions that do not leak
|
||||
information about what you are encoding/decoding via processor cache
|
||||
misses. Further reading on [cache-timing attacks](http://blog.ircmaxell.com/2014/11/its-all-about-time.html).
|
||||
|
||||
Our fork offers the following enchancements:
|
||||
|
||||
* `mbstring.func_overload` resistance
|
||||
* Unit tests
|
||||
* Composer- and Packagist-ready
|
||||
* Base16 encoding
|
||||
* Base32 encoding
|
||||
* Uses `pack()` and `unpack()` instead of `chr()` and `ord()`
|
||||
|
||||
## PHP Version Requirements
|
||||
|
||||
Version 2 of this library should work on **PHP 7** or newer. For PHP 5
|
||||
support, see [the v1.x branch](https://github.com/paragonie/constant_time_encoding/tree/v1.x).
|
||||
|
||||
If you are adding this as a dependency to a project intended to work on both PHP 5 and PHP 7, please set the required version to `^1|^2` instead of just `^1` or `^2`.
|
||||
|
||||
## How to Install
|
||||
|
||||
```sh
|
||||
composer require paragonie/constant_time_encoding
|
||||
```
|
||||
|
||||
## How to Use
|
||||
|
||||
```php
|
||||
use ParagonIE\ConstantTime\Encoding;
|
||||
|
||||
// possibly (if applicable):
|
||||
// require 'vendor/autoload.php';
|
||||
|
||||
$data = random_bytes(32);
|
||||
echo Encoding::base64Encode($data), "\n";
|
||||
echo Encoding::base32EncodeUpper($data), "\n";
|
||||
echo Encoding::base32Encode($data), "\n";
|
||||
echo Encoding::hexEncode($data), "\n";
|
||||
echo Encoding::hexEncodeUpper($data), "\n";
|
||||
```
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE=
|
||||
2VMKKPSHSWVCVZJ6E7SONRY3ZXCNG3GE6ZZFU7TGJSX7KUKFNLAQ====
|
||||
2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq====
|
||||
d558a53e4795aa2ae53e27e4e6c71bcdc4d36cc4f6725a7e664caff551456ac1
|
||||
D558A53E4795AA2AE53E27E4E6C71BDCC4D36CC4F6725A7E664CAFF551456AC1
|
||||
```
|
||||
|
||||
If you only need a particular variant, you can just reference the
|
||||
required class like so:
|
||||
|
||||
```php
|
||||
use ParagonIE\ConstantTime\Base64;
|
||||
use ParagonIE\ConstantTime\Base32;
|
||||
|
||||
$data = random_bytes(32);
|
||||
echo Base64::encode($data), "\n";
|
||||
echo Base32::encode($data), "\n";
|
||||
```
|
||||
|
||||
Example output:
|
||||
|
||||
```
|
||||
1VilPkeVqirlPifk5scbzcTTbMT2clp+Zkyv9VFFasE=
|
||||
2vmkkpshswvcvzj6e7sonry3zxcng3ge6zzfu7tgjsx7kukfnlaq====
|
||||
```
|
||||
|
||||
## Support Contracts
|
||||
|
||||
If your company uses this library in their products or services, you may be
|
||||
interested in [purchasing a support contract from Paragon Initiative Enterprises](https://paragonie.com/enterprise).
|
||||
56
vendor/paragonie/constant_time_encoding/composer.json
vendored
Normal file
56
vendor/paragonie/constant_time_encoding/composer.json
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"description": "Constant-time Implementations of RFC 4648 Encoding (Base-64, Base-32, Base-16)",
|
||||
"keywords": [
|
||||
"base64",
|
||||
"encoding",
|
||||
"rfc4648",
|
||||
"base32",
|
||||
"base16",
|
||||
"hex",
|
||||
"bin2hex",
|
||||
"hex2bin",
|
||||
"base64_encode",
|
||||
"base64_decode",
|
||||
"base32_encode",
|
||||
"base32_decode"
|
||||
],
|
||||
"license": "MIT",
|
||||
"type": "library",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paragon Initiative Enterprises",
|
||||
"email": "security@paragonie.com",
|
||||
"homepage": "https://paragonie.com",
|
||||
"role": "Maintainer"
|
||||
},
|
||||
{
|
||||
"name": "Steve 'Sc00bz' Thomas",
|
||||
"email": "steve@tobtu.com",
|
||||
"homepage": "https://www.tobtu.com",
|
||||
"role": "Original Developer"
|
||||
}
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/paragonie/constant_time_encoding/issues",
|
||||
"email": "info@paragonie.com",
|
||||
"source": "https://github.com/paragonie/constant_time_encoding"
|
||||
},
|
||||
"require": {
|
||||
"php": "^7|^8"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^6|^7|^8|^9",
|
||||
"vimeo/psalm": "^1|^2|^3|^4"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ParagonIE\\ConstantTime\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"ParagonIE\\ConstantTime\\Tests\\": "tests/"
|
||||
}
|
||||
}
|
||||
}
|
||||
519
vendor/paragonie/constant_time_encoding/src/Base32.php
vendored
Normal file
519
vendor/paragonie/constant_time_encoding/src/Base32.php
vendored
Normal file
@@ -0,0 +1,519 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RangeException;
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base32
|
||||
* [A-Z][2-7]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base32 implements EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Decode a Base32-encoded string into raw binary
|
||||
*
|
||||
* @param string $encodedString
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
*/
|
||||
public static function decode(string $encodedString, bool $strictPadding = false): string
|
||||
{
|
||||
return static::doDecode($encodedString, false, $strictPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode an uppercase Base32-encoded string into raw binary
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
*/
|
||||
public static function decodeUpper(string $src, bool $strictPadding = false): string
|
||||
{
|
||||
return static::doDecode($src, true, $strictPadding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into Base32 (RFC 4648)
|
||||
*
|
||||
* @param string $binString
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encode(string $binString): string
|
||||
{
|
||||
return static::doEncode($binString, false, true);
|
||||
}
|
||||
/**
|
||||
* Encode into Base32 (RFC 4648)
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encodeUnpadded(string $src): string
|
||||
{
|
||||
return static::doEncode($src, false, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into uppercase Base32 (RFC 4648)
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encodeUpper(string $src): string
|
||||
{
|
||||
return static::doEncode($src, true, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into uppercase Base32 (RFC 4648)
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encodeUpperUnpadded(string $src): string
|
||||
{
|
||||
return static::doEncode($src, true, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 96 && $src < 123) $ret += $src - 97 + 1; // -64
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 96);
|
||||
|
||||
// if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
|
||||
$ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Uppercase variant.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5BitsUpper(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 64 && $src < 91) $ret += $src - 65 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x31 && $src < 0x38) $ret += $src - 24 + 1; // -23
|
||||
$ret += (((0x31 - $src) & ($src - 0x38)) >> 8) & ($src - 23);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5Bits(int $src): string
|
||||
{
|
||||
$diff = 0x61;
|
||||
|
||||
// if ($src > 25) $ret -= 72;
|
||||
$diff -= ((25 - $src) >> 8) & 73;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* Uppercase variant.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5BitsUpper(int $src): string
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $ret -= 40;
|
||||
$diff -= ((25 - $src) >> 8) & 41;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encodedString
|
||||
* @param bool $upper
|
||||
* @return string
|
||||
*/
|
||||
public static function decodeNoPadding(string $encodedString, bool $upper = false): string
|
||||
{
|
||||
$srcLen = Binary::safeStrlen($encodedString);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if (($srcLen & 7) === 0) {
|
||||
for ($j = 0; $j < 7 && $j < $srcLen; ++$j) {
|
||||
if ($encodedString[$srcLen - $j - 1] === '=') {
|
||||
throw new InvalidArgumentException(
|
||||
"decodeNoPadding() doesn't tolerate padding"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return static::doDecode(
|
||||
$encodedString,
|
||||
$upper,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Base32 decoding
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $upper
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
* @psalm-suppress RedundantCondition
|
||||
*/
|
||||
protected static function doDecode(
|
||||
string $src,
|
||||
bool $upper = false,
|
||||
bool $strictPadding = false
|
||||
): string {
|
||||
// We do this to reduce code duplication:
|
||||
$method = $upper
|
||||
? 'decode5BitsUpper'
|
||||
: 'decode5Bits';
|
||||
|
||||
// Remove padding
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 7) === 0) {
|
||||
for ($j = 0; $j < 7; ++$j) {
|
||||
if ($src[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 7) === 1) {
|
||||
throw new RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$src = \rtrim($src, '=');
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
}
|
||||
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 8 <= $srcLen; $i += 8) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, 8));
|
||||
/** @var int $c0 */
|
||||
$c0 = static::$method($chunk[1]);
|
||||
/** @var int $c1 */
|
||||
$c1 = static::$method($chunk[2]);
|
||||
/** @var int $c2 */
|
||||
$c2 = static::$method($chunk[3]);
|
||||
/** @var int $c3 */
|
||||
$c3 = static::$method($chunk[4]);
|
||||
/** @var int $c4 */
|
||||
$c4 = static::$method($chunk[5]);
|
||||
/** @var int $c5 */
|
||||
$c5 = static::$method($chunk[6]);
|
||||
/** @var int $c6 */
|
||||
$c6 = static::$method($chunk[7]);
|
||||
/** @var int $c7 */
|
||||
$c7 = static::$method($chunk[8]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCCCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff,
|
||||
(($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff,
|
||||
(($c6 << 5) | ($c7 ) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6 | $c7) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
|
||||
/** @var int $c0 */
|
||||
$c0 = static::$method($chunk[1]);
|
||||
|
||||
if ($i + 6 < $srcLen) {
|
||||
/** @var int $c1 */
|
||||
$c1 = static::$method($chunk[2]);
|
||||
/** @var int $c2 */
|
||||
$c2 = static::$method($chunk[3]);
|
||||
/** @var int $c3 */
|
||||
$c3 = static::$method($chunk[4]);
|
||||
/** @var int $c4 */
|
||||
$c4 = static::$method($chunk[5]);
|
||||
/** @var int $c5 */
|
||||
$c5 = static::$method($chunk[6]);
|
||||
/** @var int $c6 */
|
||||
$c6 = static::$method($chunk[7]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff,
|
||||
(($c4 << 7) | ($c5 << 2) | ($c6 >> 3)) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5 | $c6) >> 8;
|
||||
if ($strictPadding) {
|
||||
$err |= ($c6 << 5) & 0xff;
|
||||
}
|
||||
} elseif ($i + 5 < $srcLen) {
|
||||
/** @var int $c1 */
|
||||
$c1 = static::$method($chunk[2]);
|
||||
/** @var int $c2 */
|
||||
$c2 = static::$method($chunk[3]);
|
||||
/** @var int $c3 */
|
||||
$c3 = static::$method($chunk[4]);
|
||||
/** @var int $c4 */
|
||||
$c4 = static::$method($chunk[5]);
|
||||
/** @var int $c5 */
|
||||
$c5 = static::$method($chunk[6]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff,
|
||||
(($c4 << 7) | ($c5 << 2) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4 | $c5) >> 8;
|
||||
} elseif ($i + 4 < $srcLen) {
|
||||
/** @var int $c1 */
|
||||
$c1 = static::$method($chunk[2]);
|
||||
/** @var int $c2 */
|
||||
$c2 = static::$method($chunk[3]);
|
||||
/** @var int $c3 */
|
||||
$c3 = static::$method($chunk[4]);
|
||||
/** @var int $c4 */
|
||||
$c4 = static::$method($chunk[5]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff,
|
||||
(($c3 << 4) | ($c4 >> 1) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3 | $c4) >> 8;
|
||||
if ($strictPadding) {
|
||||
$err |= ($c4 << 7) & 0xff;
|
||||
}
|
||||
} elseif ($i + 3 < $srcLen) {
|
||||
/** @var int $c1 */
|
||||
$c1 = static::$method($chunk[2]);
|
||||
/** @var int $c2 */
|
||||
$c2 = static::$method($chunk[3]);
|
||||
/** @var int $c3 */
|
||||
$c3 = static::$method($chunk[4]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) | ($c3 >> 4)) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
if ($strictPadding) {
|
||||
$err |= ($c3 << 4) & 0xff;
|
||||
}
|
||||
} elseif ($i + 2 < $srcLen) {
|
||||
/** @var int $c1 */
|
||||
$c1 = static::$method($chunk[2]);
|
||||
/** @var int $c2 */
|
||||
$c2 = static::$method($chunk[3]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CC',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff,
|
||||
(($c1 << 6) | ($c2 << 1) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
if ($strictPadding) {
|
||||
$err |= ($c2 << 6) & 0xff;
|
||||
}
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
/** @var int $c1 */
|
||||
$c1 = static::$method($chunk[2]);
|
||||
|
||||
$dest .= \pack(
|
||||
'C',
|
||||
(($c0 << 3) | ($c1 >> 2) ) & 0xff
|
||||
);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
if ($strictPadding) {
|
||||
$err |= ($c1 << 6) & 0xff;
|
||||
}
|
||||
} else {
|
||||
$dest .= \pack(
|
||||
'C',
|
||||
(($c0 << 3) ) & 0xff
|
||||
);
|
||||
$err |= ($c0) >> 8;
|
||||
}
|
||||
}
|
||||
$check = ($err === 0);
|
||||
if (!$check) {
|
||||
throw new RangeException(
|
||||
'Base32::doDecode() only expects characters in the correct base32 alphabet'
|
||||
);
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* Base32 Encoding
|
||||
*
|
||||
* @param string $src
|
||||
* @param bool $upper
|
||||
* @param bool $pad
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function doEncode(string $src, bool $upper = false, $pad = true): string
|
||||
{
|
||||
// We do this to reduce code duplication:
|
||||
$method = $upper
|
||||
? 'encode5BitsUpper'
|
||||
: 'encode5Bits';
|
||||
|
||||
$dest = '';
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 5 <= $srcLen; $i += 5) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, 5));
|
||||
$b0 = $chunk[1];
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$b3 = $chunk[4];
|
||||
$b4 = $chunk[5];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
|
||||
static::$method((($b2 << 1) | ($b3 >> 7)) & 31) .
|
||||
static::$method((($b3 >> 2) ) & 31) .
|
||||
static::$method((($b3 << 3) | ($b4 >> 5)) & 31) .
|
||||
static::$method( $b4 & 31);
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 3 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$b3 = $chunk[4];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
|
||||
static::$method((($b2 << 1) | ($b3 >> 7)) & 31) .
|
||||
static::$method((($b3 >> 2) ) & 31) .
|
||||
static::$method((($b3 << 3) ) & 31);
|
||||
if ($pad) {
|
||||
$dest .= '=';
|
||||
}
|
||||
} elseif ($i + 2 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) | ($b2 >> 4)) & 31) .
|
||||
static::$method((($b2 << 1) ) & 31);
|
||||
if ($pad) {
|
||||
$dest .= '===';
|
||||
}
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method((($b0 << 2) | ($b1 >> 6)) & 31) .
|
||||
static::$method((($b1 >> 1) ) & 31) .
|
||||
static::$method((($b1 << 4) ) & 31);
|
||||
if ($pad) {
|
||||
$dest .= '====';
|
||||
}
|
||||
} else {
|
||||
$dest .=
|
||||
static::$method( ($b0 >> 3) & 31) .
|
||||
static::$method( ($b0 << 2) & 31);
|
||||
if ($pad) {
|
||||
$dest .= '======';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
}
|
||||
111
vendor/paragonie/constant_time_encoding/src/Base32Hex.php
vendored
Normal file
111
vendor/paragonie/constant_time_encoding/src/Base32Hex.php
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base32Hex
|
||||
* [0-9][A-V]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base32Hex extends Base32
|
||||
{
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x77) ret += $src - 0x61 + 10 + 1; // -86
|
||||
$ret += (((0x60 - $src) & ($src - 0x77)) >> 8) & ($src - 86);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 5-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode5BitsUpper(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x30 && $src < 0x3a) ret += $src - 0x2e + 1; // -47
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src - 47);
|
||||
|
||||
// if ($src > 0x40 && $src < 0x57) ret += $src - 0x41 + 10 + 1; // -54
|
||||
$ret += (((0x40 - $src) & ($src - 0x57)) >> 8) & ($src - 54);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5Bits(int $src): string
|
||||
{
|
||||
$src += 0x30;
|
||||
|
||||
// if ($src > 0x39) $src += 0x61 - 0x3a; // 39
|
||||
$src += ((0x39 - $src) >> 8) & 39;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 5-bit integers.
|
||||
*
|
||||
* Uppercase variant.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode5BitsUpper(int $src): string
|
||||
{
|
||||
$src += 0x30;
|
||||
|
||||
// if ($src > 0x39) $src += 0x41 - 0x3a; // 7
|
||||
$src += ((0x39 - $src) >> 8) & 7;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
}
|
||||
314
vendor/paragonie/constant_time_encoding/src/Base64.php
vendored
Normal file
314
vendor/paragonie/constant_time_encoding/src/Base64.php
vendored
Normal file
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use RangeException;
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64
|
||||
* [A-Z][a-z][0-9]+/
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64 implements EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $binString
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encode(string $binString): string
|
||||
{
|
||||
return static::doEncode($binString, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into Base64, no = padding
|
||||
*
|
||||
* Base64 character set "[A-Z][a-z][0-9]+/"
|
||||
*
|
||||
* @param string $src
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encodeUnpadded(string $src): string
|
||||
{
|
||||
return static::doEncode($src, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $src
|
||||
* @param bool $pad Include = padding?
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
protected static function doEncode(string $src, bool $pad = true): string
|
||||
{
|
||||
$dest = '';
|
||||
$srcLen = Binary::safeStrlen($src);
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 3 <= $srcLen; $i += 3) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, 3));
|
||||
$b0 = $chunk[1];
|
||||
$b1 = $chunk[2];
|
||||
$b2 = $chunk[3];
|
||||
|
||||
$dest .=
|
||||
static::encode6Bits( $b0 >> 2 ) .
|
||||
static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
static::encode6Bits((($b1 << 2) | ($b2 >> 6)) & 63) .
|
||||
static::encode6Bits( $b2 & 63);
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($src, $i, $srcLen - $i));
|
||||
$b0 = $chunk[1];
|
||||
if ($i + 1 < $srcLen) {
|
||||
$b1 = $chunk[2];
|
||||
$dest .=
|
||||
static::encode6Bits($b0 >> 2) .
|
||||
static::encode6Bits((($b0 << 4) | ($b1 >> 4)) & 63) .
|
||||
static::encode6Bits(($b1 << 2) & 63);
|
||||
if ($pad) {
|
||||
$dest .= '=';
|
||||
}
|
||||
} else {
|
||||
$dest .=
|
||||
static::encode6Bits( $b0 >> 2) .
|
||||
static::encode6Bits(($b0 << 4) & 63);
|
||||
if ($pad) {
|
||||
$dest .= '==';
|
||||
}
|
||||
}
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* decode from base64 into binary
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param string $encodedString
|
||||
* @param bool $strictPadding
|
||||
* @return string
|
||||
*
|
||||
* @throws RangeException
|
||||
* @throws TypeError
|
||||
* @psalm-suppress RedundantCondition
|
||||
*/
|
||||
public static function decode(string $encodedString, bool $strictPadding = false): string
|
||||
{
|
||||
// Remove padding
|
||||
$srcLen = Binary::safeStrlen($encodedString);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ($strictPadding) {
|
||||
if (($srcLen & 3) === 0) {
|
||||
if ($encodedString[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
if ($encodedString[$srcLen - 1] === '=') {
|
||||
$srcLen--;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (($srcLen & 3) === 1) {
|
||||
throw new RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
if ($encodedString[$srcLen - 1] === '=') {
|
||||
throw new RangeException(
|
||||
'Incorrect padding'
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$encodedString = \rtrim($encodedString, '=');
|
||||
$srcLen = Binary::safeStrlen($encodedString);
|
||||
}
|
||||
|
||||
$err = 0;
|
||||
$dest = '';
|
||||
// Main loop (no padding):
|
||||
for ($i = 0; $i + 4 <= $srcLen; $i += 4) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, 4));
|
||||
$c0 = static::decode6Bits($chunk[1]);
|
||||
$c1 = static::decode6Bits($chunk[2]);
|
||||
$c2 = static::decode6Bits($chunk[3]);
|
||||
$c3 = static::decode6Bits($chunk[4]);
|
||||
|
||||
$dest .= \pack(
|
||||
'CCC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff),
|
||||
((($c2 << 6) | $c3 ) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2 | $c3) >> 8;
|
||||
}
|
||||
// The last chunk, which may have padding:
|
||||
if ($i < $srcLen) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', Binary::safeSubstr($encodedString, $i, $srcLen - $i));
|
||||
$c0 = static::decode6Bits($chunk[1]);
|
||||
|
||||
if ($i + 2 < $srcLen) {
|
||||
$c1 = static::decode6Bits($chunk[2]);
|
||||
$c2 = static::decode6Bits($chunk[3]);
|
||||
$dest .= \pack(
|
||||
'CC',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff),
|
||||
((($c1 << 4) | ($c2 >> 2)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1 | $c2) >> 8;
|
||||
if ($strictPadding) {
|
||||
$err |= ($c2 << 6) & 0xff;
|
||||
}
|
||||
} elseif ($i + 1 < $srcLen) {
|
||||
$c1 = static::decode6Bits($chunk[2]);
|
||||
$dest .= \pack(
|
||||
'C',
|
||||
((($c0 << 2) | ($c1 >> 4)) & 0xff)
|
||||
);
|
||||
$err |= ($c0 | $c1) >> 8;
|
||||
if ($strictPadding) {
|
||||
$err |= ($c1 << 4) & 0xff;
|
||||
}
|
||||
} elseif ($strictPadding) {
|
||||
$err |= 1;
|
||||
}
|
||||
}
|
||||
$check = ($err === 0);
|
||||
if (!$check) {
|
||||
throw new RangeException(
|
||||
'Base64::decode() only expects characters in the correct base64 alphabet'
|
||||
);
|
||||
}
|
||||
return $dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $encodedString
|
||||
* @return string
|
||||
*/
|
||||
public static function decodeNoPadding(string $encodedString): string
|
||||
{
|
||||
$srcLen = Binary::safeStrlen($encodedString);
|
||||
if ($srcLen === 0) {
|
||||
return '';
|
||||
}
|
||||
if (($srcLen & 3) === 0) {
|
||||
if ($encodedString[$srcLen - 1] === '=') {
|
||||
throw new InvalidArgumentException(
|
||||
"decodeNoPadding() doesn't tolerate padding"
|
||||
);
|
||||
}
|
||||
if (($srcLen & 3) > 1) {
|
||||
if ($encodedString[$srcLen - 2] === '=') {
|
||||
throw new InvalidArgumentException(
|
||||
"decodeNoPadding() doesn't tolerate padding"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
return static::decode(
|
||||
$encodedString,
|
||||
true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] + /
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2b, 0x2f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
|
||||
|
||||
// if ($src == 0x2b) $ret += 62 + 1;
|
||||
$ret += (((0x2a - $src) & ($src - 0x2c)) >> 8) & 63;
|
||||
|
||||
// if ($src == 0x2f) ret += 63 + 1;
|
||||
$ret += (((0x2e - $src) & ($src - 0x30)) >> 8) & 64;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += ((25 - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= ((51 - $src) >> 8) & 75;
|
||||
|
||||
// if ($src > 61) $diff += 0x2b - 0x30 - 10; // -15
|
||||
$diff -= ((61 - $src) >> 8) & 15;
|
||||
|
||||
// if ($src > 62) $diff += 0x2f - 0x2b - 1; // 3
|
||||
$diff += ((62 - $src) >> 8) & 3;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
}
|
||||
88
vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php
vendored
Normal file
88
vendor/paragonie/constant_time_encoding/src/Base64DotSlash.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64DotSlash
|
||||
* ./[A-Z][a-z][0-9]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64DotSlash extends Base64
|
||||
{
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* ./ [A-Z] [a-z] [0-9]
|
||||
* 0x2e-0x2f, 0x41-0x5a, 0x61-0x7a, 0x30-0x39
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x2d && $src < 0x30) ret += $src - 0x2e + 1; // -45
|
||||
$ret += (((0x2d - $src) & ($src - 0x30)) >> 8) & ($src - 45);
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 2 + 1; // -62
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 62);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 28 + 1; // -68
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 68);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) ret += $src - 0x30 + 54 + 1; // 7
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 7);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$src += 0x2e;
|
||||
|
||||
// if ($src > 0x2f) $src += 0x41 - 0x30; // 17
|
||||
$src += ((0x2f - $src) >> 8) & 17;
|
||||
|
||||
// if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
|
||||
$src += ((0x5a - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 0x7a) $src += 0x30 - 0x7b; // -75
|
||||
$src -= ((0x7a - $src) >> 8) & 75;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
}
|
||||
82
vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php
vendored
Normal file
82
vendor/paragonie/constant_time_encoding/src/Base64DotSlashOrdered.php
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64DotSlashOrdered
|
||||
* ./[0-9][A-Z][a-z]
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64DotSlashOrdered extends Base64
|
||||
{
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [.-9] [A-Z] [a-z]
|
||||
* 0x2e-0x39, 0x41-0x5a, 0x61-0x7a
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x2d && $src < 0x3a) ret += $src - 0x2e + 1; // -45
|
||||
$ret += (((0x2d - $src) & ($src - 0x3a)) >> 8) & ($src - 45);
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) ret += $src - 0x41 + 12 + 1; // -52
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 52);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) ret += $src - 0x61 + 38 + 1; // -58
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 58);
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$src += 0x2e;
|
||||
|
||||
// if ($src > 0x39) $src += 0x41 - 0x3a; // 7
|
||||
$src += ((0x39 - $src) >> 8) & 7;
|
||||
|
||||
// if ($src > 0x5a) $src += 0x61 - 0x5b; // 6
|
||||
$src += ((0x5a - $src) >> 8) & 6;
|
||||
|
||||
return \pack('C', $src);
|
||||
}
|
||||
}
|
||||
95
vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php
vendored
Normal file
95
vendor/paragonie/constant_time_encoding/src/Base64UrlSafe.php
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Base64UrlSafe
|
||||
* [A-Z][a-z][0-9]\-_
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Base64UrlSafe extends Base64
|
||||
{
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 6-bit integers
|
||||
* into 8-bit integers.
|
||||
*
|
||||
* Base64 character set:
|
||||
* [A-Z] [a-z] [0-9] - _
|
||||
* 0x41-0x5a, 0x61-0x7a, 0x30-0x39, 0x2d, 0x5f
|
||||
*
|
||||
* @param int $src
|
||||
* @return int
|
||||
*/
|
||||
protected static function decode6Bits(int $src): int
|
||||
{
|
||||
$ret = -1;
|
||||
|
||||
// if ($src > 0x40 && $src < 0x5b) $ret += $src - 0x41 + 1; // -64
|
||||
$ret += (((0x40 - $src) & ($src - 0x5b)) >> 8) & ($src - 64);
|
||||
|
||||
// if ($src > 0x60 && $src < 0x7b) $ret += $src - 0x61 + 26 + 1; // -70
|
||||
$ret += (((0x60 - $src) & ($src - 0x7b)) >> 8) & ($src - 70);
|
||||
|
||||
// if ($src > 0x2f && $src < 0x3a) $ret += $src - 0x30 + 52 + 1; // 5
|
||||
$ret += (((0x2f - $src) & ($src - 0x3a)) >> 8) & ($src + 5);
|
||||
|
||||
// if ($src == 0x2c) $ret += 62 + 1;
|
||||
$ret += (((0x2c - $src) & ($src - 0x2e)) >> 8) & 63;
|
||||
|
||||
// if ($src == 0x5f) ret += 63 + 1;
|
||||
$ret += (((0x5e - $src) & ($src - 0x60)) >> 8) & 64;
|
||||
|
||||
return $ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses bitwise operators instead of table-lookups to turn 8-bit integers
|
||||
* into 6-bit integers.
|
||||
*
|
||||
* @param int $src
|
||||
* @return string
|
||||
*/
|
||||
protected static function encode6Bits(int $src): string
|
||||
{
|
||||
$diff = 0x41;
|
||||
|
||||
// if ($src > 25) $diff += 0x61 - 0x41 - 26; // 6
|
||||
$diff += ((25 - $src) >> 8) & 6;
|
||||
|
||||
// if ($src > 51) $diff += 0x30 - 0x61 - 26; // -75
|
||||
$diff -= ((51 - $src) >> 8) & 75;
|
||||
|
||||
// if ($src > 61) $diff += 0x2d - 0x30 - 10; // -13
|
||||
$diff -= ((61 - $src) >> 8) & 13;
|
||||
|
||||
// if ($src > 62) $diff += 0x5f - 0x2b - 1; // 3
|
||||
$diff += ((62 - $src) >> 8) & 49;
|
||||
|
||||
return \pack('C', $src + $diff);
|
||||
}
|
||||
}
|
||||
90
vendor/paragonie/constant_time_encoding/src/Binary.php
vendored
Normal file
90
vendor/paragonie/constant_time_encoding/src/Binary.php
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Binary
|
||||
*
|
||||
* Binary string operators that don't choke on
|
||||
* mbstring.func_overload
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Binary
|
||||
{
|
||||
/**
|
||||
* Safe string length
|
||||
*
|
||||
* @ref mbstring.func_overload
|
||||
*
|
||||
* @param string $str
|
||||
* @return int
|
||||
*/
|
||||
public static function safeStrlen(string $str): int
|
||||
{
|
||||
if (\function_exists('mb_strlen')) {
|
||||
// mb_strlen in PHP 7.x can return false.
|
||||
/** @psalm-suppress RedundantCast */
|
||||
return (int) \mb_strlen($str, '8bit');
|
||||
} else {
|
||||
return \strlen($str);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Safe substring
|
||||
*
|
||||
* @ref mbstring.func_overload
|
||||
*
|
||||
* @staticvar boolean $exists
|
||||
* @param string $str
|
||||
* @param int $start
|
||||
* @param ?int $length
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function safeSubstr(
|
||||
string $str,
|
||||
int $start = 0,
|
||||
$length = null
|
||||
): string {
|
||||
if ($length === 0) {
|
||||
return '';
|
||||
}
|
||||
if (\function_exists('mb_substr')) {
|
||||
return \mb_substr($str, $start, $length, '8bit');
|
||||
}
|
||||
// Unlike mb_substr(), substr() doesn't accept NULL for length
|
||||
if ($length !== null) {
|
||||
return \substr($str, $start, $length);
|
||||
} else {
|
||||
return \substr($str, $start);
|
||||
}
|
||||
}
|
||||
}
|
||||
52
vendor/paragonie/constant_time_encoding/src/EncoderInterface.php
vendored
Normal file
52
vendor/paragonie/constant_time_encoding/src/EncoderInterface.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Interface EncoderInterface
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
interface EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $binString (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function encode(string $binString): string;
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $encodedString
|
||||
* @param bool $strictPadding Error on invalid padding
|
||||
* @return string (raw binary)
|
||||
*/
|
||||
public static function decode(string $encodedString, bool $strictPadding = false): string;
|
||||
}
|
||||
262
vendor/paragonie/constant_time_encoding/src/Encoding.php
vendored
Normal file
262
vendor/paragonie/constant_time_encoding/src/Encoding.php
vendored
Normal file
@@ -0,0 +1,262 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Encoding
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Encoding
|
||||
{
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32Encode(string $str): string
|
||||
{
|
||||
return Base32::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32EncodeUpper(string $str): string
|
||||
{
|
||||
return Base32::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 decoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32Decode(string $str): string
|
||||
{
|
||||
return Base32::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 decoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32DecodeUpper(string $str): string
|
||||
{
|
||||
return Base32::decodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32HexEncode(string $str): string
|
||||
{
|
||||
return Base32Hex::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32Hex encoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32HexEncodeUpper(string $str): string
|
||||
{
|
||||
return Base32Hex::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32Hex decoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32HexDecode(string $str): string
|
||||
{
|
||||
return Base32Hex::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32Hex decoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32HexDecodeUpper(string $str): string
|
||||
{
|
||||
return Base32Hex::decodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 encoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64Encode(string $str): string
|
||||
{
|
||||
return Base64::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 decoding
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64Decode(string $str): string
|
||||
{
|
||||
return Base64::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64EncodeDotSlash(string $str): string
|
||||
{
|
||||
return Base64DotSlash::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode from base64 to raw binary
|
||||
*
|
||||
* Base64 character set "./[A-Z][a-z][0-9]"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws \RangeException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64DecodeDotSlash(string $str): string
|
||||
{
|
||||
return Base64DotSlash::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode into Base64
|
||||
*
|
||||
* Base64 character set "[.-9][A-Z][a-z]" or "./[0-9][A-Z][a-z]"
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64EncodeDotSlashOrdered(string $str): string
|
||||
{
|
||||
return Base64DotSlashOrdered::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode from base64 to raw binary
|
||||
*
|
||||
* Base64 character set "[.-9][A-Z][a-z]" or "./[0-9][A-Z][a-z]"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
* @throws \RangeException
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64DecodeDotSlashOrdered(string $str): string
|
||||
{
|
||||
return Base64DotSlashOrdered::decode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function hexEncode(string $bin_string): string
|
||||
{
|
||||
return Hex::encode($bin_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a hexadecimal string into a binary string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $hex_string
|
||||
* @return string (raw binary)
|
||||
* @throws \RangeException
|
||||
*/
|
||||
public static function hexDecode(string $hex_string): string
|
||||
{
|
||||
return Hex::decode($hex_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function hexEncodeUpper(string $bin_string): string
|
||||
{
|
||||
return Hex::encodeUpper($bin_string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $bin_string (raw binary)
|
||||
* @return string
|
||||
*/
|
||||
public static function hexDecodeUpper(string $bin_string): string
|
||||
{
|
||||
return Hex::decode($bin_string);
|
||||
}
|
||||
}
|
||||
146
vendor/paragonie/constant_time_encoding/src/Hex.php
vendored
Normal file
146
vendor/paragonie/constant_time_encoding/src/Hex.php
vendored
Normal file
@@ -0,0 +1,146 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
use RangeException;
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class Hex
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class Hex implements EncoderInterface
|
||||
{
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $binString (raw binary)
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encode(string $binString): string
|
||||
{
|
||||
$hex = '';
|
||||
$len = Binary::safeStrlen($binString);
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C', $binString[$i]);
|
||||
$c = $chunk[1] & 0xf;
|
||||
$b = $chunk[1] >> 4;
|
||||
|
||||
$hex .= \pack(
|
||||
'CC',
|
||||
(87 + $b + ((($b - 10) >> 8) & ~38)),
|
||||
(87 + $c + ((($c - 10) >> 8) & ~38))
|
||||
);
|
||||
}
|
||||
return $hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a binary string into a hexadecimal string without cache-timing
|
||||
* leaks, returning uppercase letters (as per RFC 4648)
|
||||
*
|
||||
* @param string $binString (raw binary)
|
||||
* @return string
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function encodeUpper(string $binString): string
|
||||
{
|
||||
$hex = '';
|
||||
$len = Binary::safeStrlen($binString);
|
||||
|
||||
for ($i = 0; $i < $len; ++$i) {
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C', $binString[$i]);
|
||||
$c = $chunk[1] & 0xf;
|
||||
$b = $chunk[1] >> 4;
|
||||
|
||||
$hex .= \pack(
|
||||
'CC',
|
||||
(55 + $b + ((($b - 10) >> 8) & ~6)),
|
||||
(55 + $c + ((($c - 10) >> 8) & ~6))
|
||||
);
|
||||
}
|
||||
return $hex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a hexadecimal string into a binary string without cache-timing
|
||||
* leaks
|
||||
*
|
||||
* @param string $encodedString
|
||||
* @param bool $strictPadding
|
||||
* @return string (raw binary)
|
||||
* @throws RangeException
|
||||
*/
|
||||
public static function decode(
|
||||
string $encodedString,
|
||||
bool $strictPadding = false
|
||||
): string {
|
||||
$hex_pos = 0;
|
||||
$bin = '';
|
||||
$c_acc = 0;
|
||||
$hex_len = Binary::safeStrlen($encodedString);
|
||||
$state = 0;
|
||||
if (($hex_len & 1) !== 0) {
|
||||
if ($strictPadding) {
|
||||
throw new RangeException(
|
||||
'Expected an even number of hexadecimal characters'
|
||||
);
|
||||
} else {
|
||||
$encodedString = '0' . $encodedString;
|
||||
++$hex_len;
|
||||
}
|
||||
}
|
||||
|
||||
/** @var array<int, int> $chunk */
|
||||
$chunk = \unpack('C*', $encodedString);
|
||||
while ($hex_pos < $hex_len) {
|
||||
++$hex_pos;
|
||||
$c = $chunk[$hex_pos];
|
||||
$c_num = $c ^ 48;
|
||||
$c_num0 = ($c_num - 10) >> 8;
|
||||
$c_alpha = ($c & ~32) - 55;
|
||||
$c_alpha0 = (($c_alpha - 10) ^ ($c_alpha - 16)) >> 8;
|
||||
|
||||
if (($c_num0 | $c_alpha0) === 0) {
|
||||
throw new RangeException(
|
||||
'Expected hexadecimal character'
|
||||
);
|
||||
}
|
||||
$c_val = ($c_num0 & $c_num) | ($c_alpha & $c_alpha0);
|
||||
if ($state === 0) {
|
||||
$c_acc = $c_val * 16;
|
||||
} else {
|
||||
$bin .= \pack('C', $c_acc | $c_val);
|
||||
}
|
||||
$state ^= 1;
|
||||
}
|
||||
return $bin;
|
||||
}
|
||||
}
|
||||
186
vendor/paragonie/constant_time_encoding/src/RFC4648.php
vendored
Normal file
186
vendor/paragonie/constant_time_encoding/src/RFC4648.php
vendored
Normal file
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace ParagonIE\ConstantTime;
|
||||
|
||||
use TypeError;
|
||||
|
||||
/**
|
||||
* Copyright (c) 2016 - 2022 Paragon Initiative Enterprises.
|
||||
* Copyright (c) 2014 Steve "Sc00bz" Thomas (steve at tobtu dot com)
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class RFC4648
|
||||
*
|
||||
* This class conforms strictly to the RFC
|
||||
*
|
||||
* @package ParagonIE\ConstantTime
|
||||
*/
|
||||
abstract class RFC4648
|
||||
{
|
||||
/**
|
||||
* RFC 4648 Base64 encoding
|
||||
*
|
||||
* "foo" -> "Zm9v"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64Encode(string $str): string
|
||||
{
|
||||
return Base64::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 decoding
|
||||
*
|
||||
* "Zm9v" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64Decode(string $str): string
|
||||
{
|
||||
return Base64::decode($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 (URL Safe) encoding
|
||||
*
|
||||
* "foo" -> "Zm9v"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64UrlSafeEncode(string $str): string
|
||||
{
|
||||
return Base64UrlSafe::encode($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base64 (URL Safe) decoding
|
||||
*
|
||||
* "Zm9v" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base64UrlSafeDecode(string $str): string
|
||||
{
|
||||
return Base64UrlSafe::decode($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* "foo" -> "MZXW6==="
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32Encode(string $str): string
|
||||
{
|
||||
return Base32::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32 encoding
|
||||
*
|
||||
* "MZXW6===" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32Decode(string $str): string
|
||||
{
|
||||
return Base32::decodeUpper($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32-Hex encoding
|
||||
*
|
||||
* "foo" -> "CPNMU==="
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32HexEncode(string $str): string
|
||||
{
|
||||
return Base32::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base32-Hex decoding
|
||||
*
|
||||
* "CPNMU===" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base32HexDecode(string $str): string
|
||||
{
|
||||
return Base32::decodeUpper($str, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base16 decoding
|
||||
*
|
||||
* "foo" -> "666F6F"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*
|
||||
* @throws TypeError
|
||||
*/
|
||||
public static function base16Encode(string $str): string
|
||||
{
|
||||
return Hex::encodeUpper($str);
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 4648 Base16 decoding
|
||||
*
|
||||
* "666F6F" -> "foo"
|
||||
*
|
||||
* @param string $str
|
||||
* @return string
|
||||
*/
|
||||
public static function base16Decode(string $str): string
|
||||
{
|
||||
return Hex::decode($str, true);
|
||||
}
|
||||
}
|
||||
20
vendor/spomky-labs/otphp/LICENSE
vendored
Normal file
20
vendor/spomky-labs/otphp/LICENSE
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2016 Florent Morselli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
42
vendor/spomky-labs/otphp/README.md
vendored
Normal file
42
vendor/spomky-labs/otphp/README.md
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
TOTP / HOTP library in PHP
|
||||
==========================
|
||||
|
||||

|
||||
|
||||
[](https://packagist.org/packages/spomky-labs/otphp)
|
||||
[](https://packagist.org/packages/spomky-labs/otphp)
|
||||
[](https://packagist.org/packages/spomky-labs/otphp)
|
||||
[](https://packagist.org/packages/spomky-labs/otphp)
|
||||
|
||||
A php library for generating one-time passwords according to [RFC 4226](https://datatracker.ietf.org/doc/html/rfc4226) (HOTP Algorithm) and [RFC 6238](https://datatracker.ietf.org/doc/html/rfc6238) (TOTP Algorithm)
|
||||
|
||||
This library is compatible with Google Authenticator apps available for Android and iPhone.
|
||||
It is also compatible with other applications such as [FreeOTP](https://play.google.com/store/apps/details?id=org.fedorahosted.freeotp) for example.
|
||||
|
||||
# Documentation
|
||||
|
||||
The documentation of this project is available in the [*doc* folder](doc/index.md).
|
||||
|
||||
# Support
|
||||
|
||||
I bring solutions to your problems and answer your questions.
|
||||
|
||||
If you really love that project, and the work I have done or if you want I prioritize your issues, then you can help me out for a couple of :beers: or more!
|
||||
|
||||
[Become a sponsor](https://github.com/sponsors/Spomky)
|
||||
|
||||
Or
|
||||
|
||||
[](https://www.patreon.com/FlorentMorselli)
|
||||
|
||||
## Contributing
|
||||
|
||||
Requests for new features, bug fixed and all other ideas to make this project useful are welcome.
|
||||
|
||||
Please report all issues in [the repository bug tracker](hhttps://github.com/Spomky-Labs/otphp/issues).
|
||||
|
||||
Also make sure to [follow these best practices](.github/CONTRIBUTING.md).
|
||||
|
||||
## Licence
|
||||
|
||||
This software is release under the [MIT licence](LICENSE).
|
||||
87
vendor/spomky-labs/otphp/SECURITY.md
vendored
Normal file
87
vendor/spomky-labs/otphp/SECURITY.md
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Supported |
|
||||
| ------- |----------------------------------------|
|
||||
| 11.0.x | :white_check_mark: |
|
||||
| 10.0.x | :white_check_mark: (security fix only) |
|
||||
| < 10.0 | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please email `security@spomky-labs.com`.
|
||||
If deemed necessary, you can encrypt your message using one of the following GPG key
|
||||
|
||||
```
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
xjMEXTsJVxYJKwYBBAHaRw8BAQdAZCS93eHRx97V+LQbAWuAaeKIdUZ9YIkn
|
||||
QH5pQ7dDU0TNMWNvbnRhY3RAc3BvbWt5LWxhYnMuY29tIDxjb250YWN0QHNw
|
||||
b21reS1sYWJzLmNvbT7CdwQQFgoAHwUCXTsJVwYLCQcIAwIEFQgKAgMWAgEC
|
||||
GQECGwMCHgEACgkQG6hbCDSDj+1/tgEAoy11uHvDV7kkG/iN2/0ylV72hU8y
|
||||
c/xoqGd7qFaKD6ABANcthlg63OrQVTf0dUPOT9Y2BJpOOA88JJWgILtuUPIO
|
||||
zjgEXTsJVxIKKwYBBAGXVQEFAQEHQKiX7nldkmICePhzwReZnBPmjpsmNt7V
|
||||
Y8xHdICKsr8cAwEIB8JhBBgWCAAJBQJdOwlXAhsMAAoJEBuoWwg0g4/t0KgA
|
||||
/31ucb/bL/MGpWFrpSjTs6uQhZWlBmcFoeMhwCYepIpZAQDd65UBqFDKXJWv
|
||||
Xy3zoMQQzD9Z6fUATnFrWkzjHwhvDQ==
|
||||
=j4dw
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
xsFNBGILZFoBEADo9pzAMRVxL5typ22Ywifdyi3CMHgg7zptfb8otrQci8IX
|
||||
m7B8/NTA0I9EkenzSW/Mf4k2iPNCwXc+qVEHPvPNvr3WazcdiDQJjXqMtkxG
|
||||
l2dvdQHdBxN46v+mvWDVGf9anYQxIAmZrj7CDLOfD/cG/8STL4hSbFjRBOKs
|
||||
xAP8wgRA/amcrf9WcCDxURGIq8mDPcECR8fca+iukTmMe2NDEc56pJi0KVoF
|
||||
pFhOMMfjgP/XvtGjjSNZNGRgHSLTQs8UiK+5BjPh+iWFIPV5+ZPLpbSOcoma
|
||||
GyeX5i1DmAh7cWx/FphvFzOun6to3ERuy82+zW54iA9zS8+kIfV4Wjr2qE7l
|
||||
Ctc9l8RIv/6dMXoW2Y42CTuywlAMnlP7XaaUgE++CXTIuO7+6Gp0E5NlmqB5
|
||||
lb+CZLV/LS27gUcajs23ve5B3UId2bGUflvTtY/J0VPzrJMoEErVnkCsnD7W
|
||||
Oiwe8GiSNMJmTGu/A45xf5nuYNcuU7blA5XXwPoHZuALj1zv6eCWVxWz02l9
|
||||
Fc/T+gNkOEErlXOcldyXxQ5Qb99TU5NgdqzbibyR9QAqdfwtgg19oFbiSP7t
|
||||
8b5P2qAIW2GaOCkX007cBCzTXNrcQNruTwUD59LZQLhdGz5WJo/gefC/3ZvR
|
||||
vKoJKCRlk7s43aUjeZzE+Engpr5e1wl63WjAzQARAQABzTNzZWN1cml0eUBz
|
||||
cG9ta3ktbGFicy5jb20gPHNlY3VyaXR5QHNwb21reS1sYWJzLmNvbT7CwY0E
|
||||
EAEIACAFAmILZFoGCwkHCAMCBBUICgIEFgIBAAIZAQIbAwIeAQAhCRBy14gx
|
||||
FHv4aBYhBKgF8zJv89FYVv0RFHLXiDEUe/hoA+YP/ijaePtilKURzNVrPWfc
|
||||
gDw/ZNCR+dVAgwGo9VcbOvkyZmyqD6yBjuDWvG96KQs0LRrqWKonAvnewNtp
|
||||
wQruuvrlcCuNE6TTfvx0wh2+lwKD7MH5dKutHUCowVNAsZ5uZxHVF9RGLBh+
|
||||
JRofklupcGqUx+Jtx4uq2gAGOqV4/QdvneMjkLwqVu8FGIM59LfdNfp/iA3p
|
||||
wX2DvfxBO58Gu6hilmf7R+b9nX0U7xYJM6QJb7H89cV3/AoTh2kf1wtFY+Py
|
||||
Di6VZTMUBYOoz2iSnvCE8KlBWDu98/A2EJ7kDGQdmnuIgsURsyap3yKioaUr
|
||||
LGTaG0OiC/gkXkKisH6eff6Gw06qelBarf5N/GgoeAN/amE8twy3a+Hx1pyw
|
||||
ZzkjPsL7uWg3Koy5mPuCtWfPtIBcJaTLS5d8ESlJ8/CfaVaDludzYQZo70Xn
|
||||
m4KzjPnptm3djpZNwoFEUxrHVREOEe69/MnEL2PNcEMQkapg16PnH4phajnC
|
||||
7bYOPDteMJlHjNmQzz9d25ZwzVBHDDT50mHDijR2D/OgKx3NQr88fiFAWhKG
|
||||
lEu1ZuOkKIKV5VIFbocTWSoV7bkzIfrll49xWou+4VOxgRuqjquFC4RV8fea
|
||||
lLbHOcJlOR00aFDmoOWQ3/QNvajaWJFzDdocGbgbnEBMDFRoUkuhqOBcnzA+
|
||||
apW/zsFNBGILZFoBEADSwiM49wObRpxOyas91M6WvJ4Gt3iXqj+L8dmcw0FW
|
||||
UdDpwOxy8tuZx+OfXEBBH3eJHOobC66vN+E9WYobVkJ5zfbGxfQruTuvUZNl
|
||||
X9Lo0UwoP+AP21AKUUvsf48iZGWzmlkxgPnhAQS4ECkkWCKPf7nFTk+V+jIN
|
||||
nf6ZDZLXaRUnG0nLvzs0raG1eTVrGvPSCC8u3R2zIh9SvoeEgTnT/Re0mhCu
|
||||
ah3fwG+4vXc6VIjR1ZtpM9+Y8sl+PFZ/Oiisc+46oU5qXVVLtHfLdxYZ4vl2
|
||||
IflHDKKmrfbfGY1hJl/foBLglT3Cd8GTu3FjiAJX9PpkiWbsflc0OUBQf9aC
|
||||
73W5FLS4P4clm4nNzVGkNucWHvk+urM6nEUf02bhsfF0TPeos3QcJorfKNUS
|
||||
TvuGYccENuK5cVOzEcU+VhN08GT0pr0CpqJnsw+zV8vD4k3aPmMFmSVog+bY
|
||||
NhfB7AgwbOjd6MhQJcP7YjYTHaa6YsnKMSg4RhkDjvMa3421hfaWsVvlIb0f
|
||||
AZJ8BnXgfE0uI8CKA9dc6I2Posl33zC8HI2sS1MEJ90Am68P+uJt61LdJeD5
|
||||
VXSrCkzBhUBds0hbGR6+DF20UD496m7Lw3VBoWOl2bMeLdERDarFMDYsPH47
|
||||
rie9wlrnPNR57HUqK4bpkFwqTStRkRFUhFv7LLWZ1QARAQABwsF2BBgBCAAJ
|
||||
BQJiC2RaAhsMACEJEHLXiDEUe/hoFiEEqAXzMm/z0VhW/REUcteIMRR7+GhI
|
||||
lQ/9GbSwIdGue6Gw0msYAEoER9HhpYB//9/GG7/c4ZW60nLSSYuhNWIo0Akl
|
||||
10CzeApezf/O9/1EExqZ9ygj4wtUphcQOdRJVhXPt+gskw7/NHoXUJ+Z1rbb
|
||||
EWbKle9YufZ4PAKYhlxdqTlWyQvPVxrRvbuhYeQG4S412VzKjH0/x1Fh2CfV
|
||||
hFuyOaRjg89T6rihXL1rCSJ/PDQeQtvtXeJ30yFj+aapCj+VqUl+2D+N0bzS
|
||||
LL18kEPQnJw4BOHOXrw349dAKmHN/QkRH8DINlXLyaOlABglnSViDQL3Q1t3
|
||||
sBuIeClsl3brQNJRp/RKOdTBMNAX+BhAjqodbwwT+UkJl9xJKw0Cla4wtbs2
|
||||
T0yoK/Z1iFfvPdufkK4q6ocAHJUp3+XckFIZxsHQvhQPbm9XoOt1RTO29MOw
|
||||
EYo8UjFQCnXJVsj1/6XMgIUe5tPYvS/ZZZNJFF4j+OE8xRKLKqg/DFcpEipC
|
||||
LCmzzr/hhWx0XP4CIK2tYsAMk3ieCZuk1Wa+NGLL4WfALWsNHq3wg5Wzv+yJ
|
||||
dp14fv711BVYlriI+VKggGFgBdz0dWkgrBk4+thLatJFcjFYr8BLkbtPraa3
|
||||
sFI/cGxvOXSIy4GEALdfnozyU3RJtMNtVi3IzGeIFAOb457y/IrMqpWLp1FX
|
||||
BUqlX5YJHneD9Q8Sfz/HKDQDCqg=
|
||||
=o+4z
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
```
|
||||
57
vendor/spomky-labs/otphp/composer.json
vendored
Normal file
57
vendor/spomky-labs/otphp/composer.json
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"name": "spomky-labs/otphp",
|
||||
"type": "library",
|
||||
"description": "A PHP library for generating one time passwords according to RFC 4226 (HOTP Algorithm) and the RFC 6238 (TOTP Algorithm) and compatible with Google Authenticator",
|
||||
"license": "MIT",
|
||||
"keywords": ["otp", "hotp", "totp", "RFC 4226", "RFC 6238", "Google Authenticator", "FreeOTP"],
|
||||
"homepage": "https://github.com/Spomky-Labs/otphp",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Florent Morselli",
|
||||
"homepage": "https://github.com/Spomky"
|
||||
},
|
||||
{
|
||||
"name": "All contributors",
|
||||
"homepage": "https://github.com/Spomky-Labs/otphp/contributors"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^8.1",
|
||||
"ext-mbstring": "*",
|
||||
"paragonie/constant_time_encoding": "^2.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"ekino/phpstan-banned-code": "^1.0",
|
||||
"infection/infection": "^0.26",
|
||||
"php-parallel-lint/php-parallel-lint": "^1.3",
|
||||
"phpstan/phpstan": "^1.0",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpstan/phpstan-strict-rules": "^1.0",
|
||||
"phpunit/phpunit": "^9.5.26",
|
||||
"qossmic/deptrac-shim": "^1.0",
|
||||
"rector/rector": "^0.14",
|
||||
"symfony/phpunit-bridge": "^6.1",
|
||||
"symplify/easy-coding-standard": "^11.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": { "OTPHP\\": "src/" }
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": { "OTPHP\\Test\\": "tests/" }
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"phpstan/extension-installer": true,
|
||||
"infection/extension-installer": true,
|
||||
"composer/package-versions-deprecated": true,
|
||||
"symfony/flex": true,
|
||||
"symfony/runtime": true
|
||||
},
|
||||
"optimize-autoloader": true,
|
||||
"preferred-install": {
|
||||
"*": "dist"
|
||||
},
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
85
vendor/spomky-labs/otphp/src/Factory.php
vendored
Normal file
85
vendor/spomky-labs/otphp/src/Factory.php
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OTPHP;
|
||||
|
||||
use function count;
|
||||
use InvalidArgumentException;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* This class is used to load OTP object from a provisioning Uri.
|
||||
*
|
||||
* @see \OTPHP\Test\FactoryTest
|
||||
*/
|
||||
final class Factory implements FactoryInterface
|
||||
{
|
||||
public static function loadFromProvisioningUri(string $uri): OTPInterface
|
||||
{
|
||||
try {
|
||||
$parsed_url = Url::fromString($uri);
|
||||
$parsed_url->getScheme() === 'otpauth' || throw new InvalidArgumentException('Invalid scheme.');
|
||||
} catch (Throwable $throwable) {
|
||||
throw new InvalidArgumentException('Not a valid OTP provisioning URI', $throwable->getCode(), $throwable);
|
||||
}
|
||||
|
||||
$otp = self::createOTP($parsed_url);
|
||||
|
||||
self::populateOTP($otp, $parsed_url);
|
||||
|
||||
return $otp;
|
||||
}
|
||||
|
||||
private static function populateParameters(OTPInterface $otp, Url $data): void
|
||||
{
|
||||
foreach ($data->getQuery() as $key => $value) {
|
||||
$otp->setParameter($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
private static function populateOTP(OTPInterface $otp, Url $data): void
|
||||
{
|
||||
self::populateParameters($otp, $data);
|
||||
$result = explode(':', rawurldecode(mb_substr($data->getPath(), 1)));
|
||||
|
||||
if (count($result) < 2) {
|
||||
$otp->setIssuerIncludedAsParameter(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($otp->getIssuer() !== null) {
|
||||
$result[0] === $otp->getIssuer() || throw new InvalidArgumentException(
|
||||
'Invalid OTP: invalid issuer in parameter'
|
||||
);
|
||||
$otp->setIssuerIncludedAsParameter(true);
|
||||
}
|
||||
$otp->setIssuer($result[0]);
|
||||
}
|
||||
|
||||
private static function createOTP(Url $parsed_url): OTPInterface
|
||||
{
|
||||
switch ($parsed_url->getHost()) {
|
||||
case 'totp':
|
||||
$totp = TOTP::createFromSecret($parsed_url->getSecret());
|
||||
$totp->setLabel(self::getLabel($parsed_url->getPath()));
|
||||
|
||||
return $totp;
|
||||
case 'hotp':
|
||||
$hotp = HOTP::createFromSecret($parsed_url->getSecret());
|
||||
$hotp->setLabel(self::getLabel($parsed_url->getPath()));
|
||||
|
||||
return $hotp;
|
||||
default:
|
||||
throw new InvalidArgumentException(sprintf('Unsupported "%s" OTP type', $parsed_url->getHost()));
|
||||
}
|
||||
}
|
||||
|
||||
private static function getLabel(string $data): string
|
||||
{
|
||||
$result = explode(':', rawurldecode(mb_substr($data, 1)));
|
||||
|
||||
return count($result) === 2 ? $result[1] : $result[0];
|
||||
}
|
||||
}
|
||||
14
vendor/spomky-labs/otphp/src/FactoryInterface.php
vendored
Normal file
14
vendor/spomky-labs/otphp/src/FactoryInterface.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OTPHP;
|
||||
|
||||
interface FactoryInterface
|
||||
{
|
||||
/**
|
||||
* This method is the unique public method of the class. It can load a provisioning Uri and convert it into an OTP
|
||||
* object.
|
||||
*/
|
||||
public static function loadFromProvisioningUri(string $uri): OTPInterface;
|
||||
}
|
||||
124
vendor/spomky-labs/otphp/src/HOTP.php
vendored
Normal file
124
vendor/spomky-labs/otphp/src/HOTP.php
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace OTPHP;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use function is_int;
|
||||
|
||||
/**
|
||||
* @see \OTPHP\Test\HOTPTest
|
||||
*/
|
||||
final class HOTP extends OTP implements HOTPInterface
|
||||
{
|
||||
private const DEFAULT_WINDOW = 0;
|
||||
|
||||
public static function create(
|
||||
null|string $secret = null,
|
||||
int $counter = self::DEFAULT_COUNTER,
|
||||
string $digest = self::DEFAULT_DIGEST,
|
||||
int $digits = self::DEFAULT_DIGITS
|
||||
): self {
|
||||
$htop = $secret !== null
|
||||
? self::createFromSecret($secret)
|
||||
: self::generate()
|
||||
;
|
||||
$htop->setCounter($counter);
|
||||
$htop->setDigest($digest);
|
||||
$htop->setDigits($digits);
|
||||
|
||||
return $htop;
|
||||
}
|
||||
|
||||
public static function createFromSecret(string $secret): self
|
||||
{
|
||||
$htop = new self($secret);
|
||||
$htop->setCounter(self::DEFAULT_COUNTER);
|
||||
$htop->setDigest(self::DEFAULT_DIGEST);
|
||||
$htop->setDigits(self::DEFAULT_DIGITS);
|
||||
|
||||
return $htop;
|
||||
}
|
||||
|
||||
public static function generate(): self
|
||||
{
|
||||
return self::createFromSecret(self::generateSecret());
|
||||
}
|
||||
|
||||
public function getCounter(): int
|
||||
{
|
||||
$value = $this->getParameter('counter');
|
||||
is_int($value) || throw new InvalidArgumentException('Invalid "counter" parameter.');
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getProvisioningUri(): string
|
||||
{
|
||||
return $this->generateURI('hotp', [
|
||||
'counter' => $this->getCounter(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the counter is not provided, the OTP is verified at the actual counter.
|
||||
*/
|
||||
public function verify(string $otp, null|int $counter = null, null|int $window = null): bool
|
||||
{
|
||||
$counter >= 0 || throw new InvalidArgumentException('The counter must be at least 0.');
|
||||
|
||||
if ($counter === null) {
|
||||
$counter = $this->getCounter();
|
||||
} elseif ($counter < $this->getCounter()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->verifyOtpWithWindow($otp, $counter, $window);
|
||||
}
|
||||
|
||||
public function setCounter(int $counter): void
|
||||
{
|
||||
$this->setParameter('counter', $counter);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, callable>
|
||||
*/
|
||||
protected function getParameterMap(): array
|
||||
{
|
||||
return [...parent::getParameterMap(), ...[
|
||||
'counter' => static function (mixed $value): int {
|
||||
$value = (int) $value;
|
||||
$value >= 0 || throw new InvalidArgumentException('Counter must be at least 0.');
|
||||
|
||||
return $value;
|
||||
},
|
||||
]];
|
||||
}
|
||||
|
||||
private function updateCounter(int $counter): void
|
||||
{
|
||||
$this->setCounter($counter);
|
||||
}
|
||||
|
||||
private function getWindow(null|int $window): int
|
||||
{
|
||||
return abs($window ?? self::DEFAULT_WINDOW);
|
||||
}
|
||||
|
||||
private function verifyOtpWithWindow(string $otp, int $counter, null|int $window): bool
|
||||
{
|
||||
$window = $this->getWindow($window);
|
||||
|
||||
for ($i = $counter; $i <= $counter + $window; ++$i) {
|
||||
if ($this->compareOTP($this->at($i), $otp)) {
|
||||
$this->updateCounter($i + 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user