fix billing process

This commit is contained in:
Dennis Eichhorn 2023-04-08 04:36:26 +02:00
parent 4d0a6e5c2d
commit b9cc466bed
43 changed files with 993 additions and 127 deletions

View File

@ -46,10 +46,10 @@ class PermissionAbstract implements \JsonSerializable
/**
* App name.
*
* @var null|string
* @var null|int
* @since 1.0.0
*/
protected ?string $app = null;
protected ?int $app = null;
/**
* Module id.
@ -135,7 +135,7 @@ class PermissionAbstract implements \JsonSerializable
* Constructor.
*
* @param null|int $unit Unit to check (null if all are acceptable)
* @param null|string $app App to check (null if all are acceptable)
* @param null|int $app App to check (null if all are acceptable)
* @param null|string $module Module Module to check (null if all are acceptable)
* @param null|string $from Provided by which module
* @param null|int $category Category (e.g. customer) (null if all are acceptable)
@ -147,7 +147,7 @@ class PermissionAbstract implements \JsonSerializable
*/
public function __construct(
int $unit = null,
string $app = null,
int $app = null,
string $module = null,
string $from = null,
int $category = null,
@ -211,11 +211,11 @@ class PermissionAbstract implements \JsonSerializable
/**
* Get app name.
*
* @return null|string
* @return null|int
*
* @since 1.0.0
*/
public function getApp() : ?string
public function getApp() : ?int
{
return $this->app;
}
@ -223,13 +223,13 @@ class PermissionAbstract implements \JsonSerializable
/**
* Set app name.
*
* @param string $app App name
* @param int $app App name
*
* @return void
*
* @since 1.0.0
*/
public function setApp(string $app = null) : void
public function setApp(int $app = null) : void
{
$this->app = $app;
}
@ -467,7 +467,7 @@ class PermissionAbstract implements \JsonSerializable
*
* @param int $permission Permission to check
* @param null|int $unit Unit Unit to check (null if all are acceptable)
* @param null|string $app App App to check (null if all are acceptable)
* @param null|int $app App App to check (null if all are acceptable)
* @param null|string $module Module Module to check (null if all are acceptable)
* @param null|int $category Category (e.g. customer) (null if all are acceptable)
* @param null|int $element (e.g. customer id) (null if all are acceptable)
@ -480,7 +480,7 @@ class PermissionAbstract implements \JsonSerializable
public function hasPermission(
int $permission,
int $unit = null,
string $app = null,
int $app = null,
string $module = null,
int $category = null,
int $element = null,

View File

@ -123,7 +123,7 @@ trait PermissionHandlingTrait
*
* @param int $permission Permission to check
* @param null|int $unit Unit Unit to check (null if all are acceptable)
* @param null|string $app App App to check (null if all are acceptable)
* @param null|int $app App App to check (null if all are acceptable)
* @param null|string $module Module Module to check (null if all are acceptable)
* @param null|int $category Type (e.g. customer) (null if all are acceptable)
* @param null|int $element (e.g. customer id) (null if all are acceptable)
@ -136,15 +136,13 @@ trait PermissionHandlingTrait
public function hasPermission(
int $permission,
int $unit = null,
string $app = null,
int $app = null,
string $module = null,
int $category = null,
int $element = null,
int $component = null
) : bool
{
$app = $app !== null ? \strtolower($app) : $app;
foreach ($this->permissions as $p) {
if ($p->hasPermission($permission, $unit, $app, $module, $category, $element, $component)) {
return true;

View File

@ -70,7 +70,7 @@ final class BasicOcr
}
/**
* Reat image from path
* Read image from path
*
* @param string $path Image to read
* @param int $limit Limit
@ -93,7 +93,8 @@ final class BasicOcr
if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) {
return []; // @codeCoverageIgnore
}
$magicNumber = $unpack[1];
// $magicNumber = $unpack[1];
if (($read = \fread($fp, 4)) === false || ($unpack = \unpack('N', $read)) === false) {
return []; // @codeCoverageIgnore
@ -125,6 +126,7 @@ final class BasicOcr
) {
return []; // @codeCoverageIgnore
}
$images[] = \array_values($unpack);
}
@ -237,6 +239,53 @@ final class BasicOcr
return $dist;
}
public static function imagesToMNIST(array $images, string $out, int $resolution) : void
{
$out = \fopen($out, 'wb');
\fwrite($out, \pack('N', 2051));
\fwrite($out, \pack('N', 1));
\fwrite($out, \pack('N', $resolution));
\fwrite($out, \pack('N', $resolution));
foreach ($images as $in) {
$im = \imagecreatefromstring(\file_get_contents($in));
$new = \imagescale($im, $resolution, $resolution);
// Convert the image to grayscale and normalize the pixel values
$mnist = [];
for ($i = 0; $i < $resolution; ++$i) {
for ($j = 0; $j < $resolution; ++$j) {
$pixel = \imagecolorat($new, $j, $i);
$gray = \round((0.299 * (($pixel >> 16) & 0xFF) + 0.587 * (($pixel >> 8) & 0xFF) + 0.114 * ($pixel & 0xFF)) / 255, 3);
\array_push($mnist, $gray);
}
}
for ($i = 0; $i < \count($mnist); $i++) {
\fwrite($out, \pack('C', \round($mnist[$i] * 255)));
}
}
\fclose($out);
}
public static function labelsToMNIST(array $data, string $out) : void
{
// Only allows single char labels
$out = \fopen($out, 'wb');
\fwrite($out, \pack('N', 2049));
\fwrite($out, \pack('N', 1));
foreach ($data as $e) {
\fwrite($out, \pack('C', $e));
}
\fclose($out);
}
/**
* Categorize an unknown image
*
@ -250,7 +299,6 @@ final class BasicOcr
*/
public function matchImage(string $path, int $comparison = 3, int $limit = 0) : array
{
// @todo: implement image reading if it isn't an mnist file
$Xtest = $this->readImages($path, $limit);
return $this->kNearest($this->Xtrain, $this->ytrain, $Xtest, $comparison);

View File

@ -115,8 +115,6 @@ final class TesseractOcr
return '';
}
// @todo: auto flip image if x% of text are garbage words?
\unlink($filepath);
return \trim($parsed);

View File

@ -37,7 +37,7 @@ final class DependencyResolver
{
$resolved = [];
$unresolved = [];
foreach ($graph as $table => $dependency) {
foreach ($graph as $table => $_) {
self::dependencyResolve($table, $graph, $resolved, $unresolved);
}

View File

@ -48,18 +48,18 @@ final class EUVATBffOnline implements EUVATInterface
$request->setMethod(RequestMethod::GET);
$result = [
'status' => -1,
'vat' => 'C',
'name' => '',
'city' => '',
'postal' => '',
'status' => -1,
'vat' => 'C',
'name' => '',
'city' => '',
'postal' => '',
'address' => '',
'body' => '',
'body' => '',
];
$matches = [];
try {
$body = Rest::request($request)->getBody();
$body = Rest::request($request)->getBody();
$result['body'] = $body;
\preg_match('/ErrorCode.*?(\d+)/s', $body, $matches);
@ -93,13 +93,13 @@ final class EUVATBffOnline implements EUVATInterface
) : array
{
$result = [
'status' => -1,
'vat' => 'C',
'name' => 'C',
'city' => 'C',
'postal' => 'C',
'status' => -1,
'vat' => 'C',
'name' => 'C',
'city' => 'C',
'postal' => 'C',
'address' => 'C',
'body' => '',
'body' => '',
];
if (empty($ownVAT)) {
@ -112,7 +112,7 @@ final class EUVATBffOnline implements EUVATInterface
$request->setMethod(RequestMethod::GET);
try {
$body = Rest::request($request)->getBody();
$body = Rest::request($request)->getBody();
$result['body'] = $body;
$matches = [];

View File

@ -68,6 +68,11 @@ final class EUVATVies implements EUVATInterface
$result['body'] = $body;
$json = \json_decode($body, true);
if ($json === false) {
return $result;
}
$result = \array_merge($result, self::parseResponse($json));
$result['status'] = $json['userError'] === 'VALID' ? 0 : -1;
@ -91,13 +96,13 @@ final class EUVATVies implements EUVATInterface
) : array
{
$result = [
'status' => -1,
'vat' => 'C',
'name' => 'C',
'city' => 'C',
'postal' => 'C',
'status' => -1,
'vat' => 'C',
'name' => 'C',
'city' => 'C',
'postal' => 'C',
'address' => 'C',
'body' => '',
'body' => '',
];
$request = new HttpRequest(
@ -110,10 +115,15 @@ final class EUVATVies implements EUVATInterface
$request->setMethod(RequestMethod::GET);
try {
$body = Rest::request($request)->getBody();
$body = Rest::request($request)->getBody();
$result['body'] = $body;
$json = \json_decode($body, true);
if ($json === false) {
return $result;
}
$result = \array_merge($result, self::parseResponse($json));
if ($otherName === '') {
@ -167,14 +177,14 @@ final class EUVATVies implements EUVATInterface
private static function parseResponse(array $json) : array
{
$result = [
'vat' => '',
'name' => '',
'city' => '',
'postal' => '',
'vat' => '',
'name' => '',
'city' => '',
'postal' => '',
'address' => '',
];
$result['vat'] = $json['isValid'] ? 'A' : 'B';
$result['vat'] = $json['isValid'] ? 'A' : 'B';
$result['name'] = $json['isValid'];
$result['city'] = \stripos($json['address'], "\n") !== false
@ -194,9 +204,9 @@ final class EUVATVies implements EUVATInterface
: $json['address'];
$result['name'] = $result['name'] === '---' ? '' : $result['name'];
$result['city'] = $result['city'] === '---' ? '' : $result['city'];
$result['postal'] = $result['postal'] === '---' ? '' : $result['postal'];
$result['name'] = $result['name'] === '---' ? '' : $result['name'];
$result['city'] = $result['city'] === '---' ? '' : $result['city'];
$result['postal'] = $result['postal'] === '---' ? '' : $result['postal'];
$result['address'] = $result['address'] === '---' ? '' : $result['address'];
return $result;

View File

@ -34,7 +34,16 @@ final class Forensics
{
}
public static function benfordAnalysis(array $data)
/**
* Perform the Benford analysis
*
* @param array $data Data to analyze
*
* @return array
*
* @since 1.0.0
*/
public static function benfordAnalysis(array $data) : array
{
$digits = \array_fill(1, 9, 0);
$size = \count($data);
@ -52,6 +61,13 @@ final class Forensics
return $results;
}
/**
* Calculate the general Benford distribution
*
* @return array
*
* @since 1.0.0
*/
public static function expectedBenfordDistribution() : array
{
$expected = [];

View File

@ -96,6 +96,8 @@ final class HttpSession implements SessionInterface
]);
\session_start();
// @codeCoverageIgnoreEnd
} else {
throw new \Exception('Bad application workflow');
}
if ($this->inactivityInterval > 0

View File

@ -93,28 +93,42 @@ final class Kernel
if (\count($kernel) === 3) {
\imageconvolution($im, $kernel, 1, 0);
} else {
// @todo: implement @see https://rosettacode.org/wiki/Image_convolution
// @todo: not working yet
$dim = [\imagesx($im), \imagesy($im)];
$kDim = [\count($kernel[1]), \count($kernel)]; // @todo: is the order correct? mhh...
$kDim = [\count($kernel[1]), \count($kernel)];
$kWidthRadius = NumericUtils::uRightShift($kDim[0], 1);
$kHeightRadius = NumericUtils::uRightShift($kDim[1], 1);
for ($i = $dim[0] - 1; $i >= 0; --$i) {
for ($j = $dim[1] - 1; $j >= 0; --$j) {
$newPixel = 0;
for ($y = 0; $y < $dim[1]; ++$y) {
for ($x = 0; $x < $dim[0]; ++$x) {
$newR = 0;
$newG = 0;
$newB = 0;
for ($ki = $kDim[0] - 1; $ki >= 0; --$ki) {
for ($kj = $kDim[1] - 1; $kj >= 0; --$kj) {
$newPixel += $kernel[$ki][$kj] * \imagecolorat($im,
\min(\max($i + $ki - $kWidthRadius, 0), $dim[0] - 1),
\min(\max($j + $kj - $kHeightRadius, 0), $dim[1] - 1)
for ($ky = 0; $ky < $kDim[0]; ++$ky) {
for ($kx = 0; $kx < $kDim[1]; ++$kx) {
$pixel = \imagecolorat($im,
\min(\max($x + $kx - $kWidthRadius, 0), $dim[0] - 1),
\min(\max($y + $ky - $kHeightRadius, 0), $dim[1] - 1)
);
// old
$r = ($pixel >> 16) & 0xFF;
$g = ($pixel >> 8) & 0xFF;
$b = $pixel & 0xFF;
// new
$newR += $r * $kernel[$ky][$kx];
$newG += $g * $kernel[$ky][$kx];
$newB += $b * $kernel[$ky][$kx];
}
}
\imagesetpixel($im, $i, $j, (int) $newPixel);
$newR = \max(0, \min(255, $newR));
$newG = \max(0, \min(255, $newG));
$newB = \max(0, \min(255, $newB));
\imagesetpixel($im, $x, $y, (int) (($newR << 16) + ($newG << 8) | $newB));
}
}
}

View File

@ -0,0 +1,542 @@
<?php
/**
* Karaka
*
* PHP Version 8.1
*
* @package phpOMS\Localization
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\Localization;
/**
* ISO 639 country -> language trait.
*
* @package phpOMS\Localization
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
trait ISO639CountryTrait
{
/**
* Get language from country.
*
* @param string $country Country
*
* @return array
*
* @since 1.0.0
*/
public static function languageFromCountry(string $country) : array
{
switch (\strtoupper($country)) {
case ISO3166TwoEnum::_AFG:
return [self::_PS, self::_UZ, self::_TK];
case ISO3166TwoEnum::_ALA:
return [self::_SV];
case ISO3166TwoEnum::_ALB:
return [self::_SQ];
case ISO3166TwoEnum::_DZA:
return [self::_AR];
case ISO3166TwoEnum::_ASM:
return [self::_EN, self::_SM];
case ISO3166TwoEnum::_AND:
return [self::_CA];
case ISO3166TwoEnum::_AGO:
return [self::_PT];
case ISO3166TwoEnum::_AIA:
return [self::_EN];
case ISO3166TwoEnum::_ATG:
return [self::_EN];
case ISO3166TwoEnum::_ARG:
return [self::_ES, self::_GN];
case ISO3166TwoEnum::_ARM:
return [self::_HY, self::_RU];
case ISO3166TwoEnum::_ABW:
return [self::_NL];
case ISO3166TwoEnum::_AUS:
return [self::_EN];
case ISO3166TwoEnum::_AUT:
return [self::_DE];
case ISO3166TwoEnum::_AZE:
return [self::_AZ, self::_RU, self::_HY];
case ISO3166TwoEnum::_BHS:
return [self::_EN];
case ISO3166TwoEnum::_BHR:
return [self::_AR];
case ISO3166TwoEnum::_BGD:
return [self::_BN];
case ISO3166TwoEnum::_BRB:
return [self::_EN];
case ISO3166TwoEnum::_BLR:
return [self::_BE, self::_RU];
case ISO3166TwoEnum::_BEL:
return [self::_NL, self::_FR, self::_DE];
case ISO3166TwoEnum::_BLZ:
return [self::_EN];
case ISO3166TwoEnum::_BEN:
return [self::_FR];
case ISO3166TwoEnum::_BMU:
return [self::_EN];
case ISO3166TwoEnum::_BTN:
return [self::_DZ];
case ISO3166TwoEnum::_BOL:
return [self::_ES, self::_QU, self::_AY];
case ISO3166TwoEnum::_BES:
return [self::_NL, self::_EN];
case ISO3166TwoEnum::_BIH:
return [self::_BS, self::_HR, self::_SR];
case ISO3166TwoEnum::_BWA:
return [self::_EN, self::_TN];
case ISO3166TwoEnum::_BVT:
return [];
case ISO3166TwoEnum::_BRA:
return [self::_PT];
case ISO3166TwoEnum::_IOT:
return [self::_EN];
case ISO3166TwoEnum::_BRN:
return [self::_MS];
case ISO3166TwoEnum::_BGR:
return [self::_BG];
case ISO3166TwoEnum::_BFA:
return [self::_FR];
case ISO3166TwoEnum::_BDI:
return [self::_RN, self::_FR];
case ISO3166TwoEnum::_CPV:
return [self::_PT];
case ISO3166TwoEnum::_KHM:
return [self::_KM];
case ISO3166TwoEnum::_CMR:
return [self::_FR, self::_EN];
case ISO3166TwoEnum::_CAN:
return [self::_EN, self::_FR];
case ISO3166TwoEnum::_CYM:
return [self::_EN];
case ISO3166TwoEnum::_CAF:
return [self::_FR, self::_SG];
case ISO3166TwoEnum::_TCD:
return [self::_FR, self::_AR];
case ISO3166TwoEnum::_CHL:
return [self::_ES];
break;
case ISO3166TwoEnum::_CHN:
return [self::_ZH];
break;
case ISO3166TwoEnum::_CXR:
return [self::_EN];
break;
case ISO3166TwoEnum::_CCK:
return [self::_EN];
case ISO3166TwoEnum::_COL:
return [self::_ES];
case ISO3166TwoEnum::_COM:
return [self::_AR, self::_FR];
case ISO3166TwoEnum::_COG:
return [self::_FR, self::_LN, self::_KG, self::_SW];
case ISO3166TwoEnum::_COD:
return [self::_FR, self::_LN, self::_KG, self::_SW];
case ISO3166TwoEnum::_COK:
return [self::_EN];
case ISO3166TwoEnum::_CRI:
return [self::_ES];
case ISO3166TwoEnum::_CIV:
return [self::_FR];
case ISO3166TwoEnum::_HRV:
return [self::_HR];
case ISO3166TwoEnum::_CUB:
return [self::_ES];
case ISO3166TwoEnum::_CUW:
return [self::_NL, self::_PA, self::_EN];
case ISO3166TwoEnum::_CYP:
return [self::_EL, self::_TR];
case ISO3166TwoEnum::_CZE:
return [self::_CS, self::_SK];
case ISO3166TwoEnum::_DNK:
return [self::_DA];
case ISO3166TwoEnum::_DJI:
return [self::_FR, self::_AR, self::_SO];
case ISO3166TwoEnum::_DMA:
return [self::_EN];
case ISO3166TwoEnum::_DOM:
return [self::_ES];
case ISO3166TwoEnum::_ECU:
return [self::_ES];
case ISO3166TwoEnum::_EGY:
return [self::_AR];
case ISO3166TwoEnum::_SLV:
return [self::_ES];
case ISO3166TwoEnum::_GNQ:
return [self::_ES, self::_FR, self::_PT];
case ISO3166TwoEnum::_ERI:
return [self::_TI, self::_AR, self::_EN];
case ISO3166TwoEnum::_EST:
return [self::_ET];
case ISO3166TwoEnum::_ETH:
return [self::_AM, self::_OM, self::_TI, self::_SO, self::_AR];
case ISO3166TwoEnum::_FLK:
return [self::_EN];
case ISO3166TwoEnum::_FRO:
return [self::_FO];
case ISO3166TwoEnum::_FJI:
return [self::_EN, self::_FJ, self::_HI, self::_UR];
case ISO3166TwoEnum::_FIN:
return [self::_FI, self::_SV];
case ISO3166TwoEnum::_FRA:
return [self::_FR];
case ISO3166TwoEnum::_GUF:
return [self::_FR];
case ISO3166TwoEnum::_PYF:
return [self::_FR, self::_TY];
case ISO3166TwoEnum::_ATF:
return [self::_FR];
case ISO3166TwoEnum::_GAB:
return [self::_FR];
case ISO3166TwoEnum::_GMB:
return [self::_EN];
case ISO3166TwoEnum::_GEO:
return [self::_KA];
case ISO3166TwoEnum::_DEU:
return [self::_DE];
case ISO3166TwoEnum::_GHA:
return [self::_EN];
case ISO3166TwoEnum::_GIB:
return [self::_EN];
case ISO3166TwoEnum::_GRC:
return [self::_EL];
case ISO3166TwoEnum::_GRL:
return [self::_KL];
case ISO3166TwoEnum::_GRD:
return [self::_EN];
case ISO3166TwoEnum::_GLP:
return [self::_FR];
case ISO3166TwoEnum::_GUM:
return [self::_EN, self::_CH, self::_ES];
case ISO3166TwoEnum::_GTM:
return [self::_ES];
case ISO3166TwoEnum::_GGY:
return [self::_EN, self::_FR];
case ISO3166TwoEnum::_GIN:
return [self::_FR];
case ISO3166TwoEnum::_GNB:
return [self::_PT];
case ISO3166TwoEnum::_GUY:
return [self::_EN];
case ISO3166TwoEnum::_HTI:
return [self::_FR, self::_HT];
case ISO3166TwoEnum::_HMD:
return [self::_EN];
case ISO3166TwoEnum::_VAT:
return [self::_IT, self::_LA];
case ISO3166TwoEnum::_HND:
return [self::_ES];
case ISO3166TwoEnum::_HKG:
return [self::_ZH, self::_EN];
case ISO3166TwoEnum::_HUN:
return [self::_HU];
case ISO3166TwoEnum::_ISL:
return [self::_IS];
case ISO3166TwoEnum::_IND:
return [self::_HI, self::_EN];
case ISO3166TwoEnum::_IDN:
return [self::_ID];
case ISO3166TwoEnum::_IRN:
return [self::_FA];
case ISO3166TwoEnum::_IRQ:
return [self::_AR, self::_KU];
case ISO3166TwoEnum::_IRL:
return [self::_GA, self::_EN];
case ISO3166TwoEnum::_IMN:
return [self::_EN, self::_GV];
case ISO3166TwoEnum::_ISR:
return [self::_HE, self::_AR];
case ISO3166TwoEnum::_ITA:
return [self::_IT];
case ISO3166TwoEnum::_JAM:
return [self::_EN];
case ISO3166TwoEnum::_JPN:
return [self::_JA];
case ISO3166TwoEnum::_JEY:
return [self::_EN, self::_FR];
case ISO3166TwoEnum::_JOR:
return [self::_AR];
case ISO3166TwoEnum::_KAZ:
return [self::_KK, self::_RU];
case ISO3166TwoEnum::_KEN:
return [self::_SW, self::_EN];
case ISO3166TwoEnum::_KIR:
return [self::_EN];
case ISO3166TwoEnum::_PRK:
return [self::_KO];
case ISO3166TwoEnum::_KOR:
return [self::_KO];
case ISO3166TwoEnum::_KWT:
return [self::_AR];
case ISO3166TwoEnum::_KGZ:
return [self::_KY, self::_RU];
case ISO3166TwoEnum::_LAO:
return [self::_LO];
case ISO3166TwoEnum::_LVA:
return [self::_LV];
case ISO3166TwoEnum::_LBN:
return [self::_AR, self::_FR];
case ISO3166TwoEnum::_LSO:
return [self::_EN, self::_ST];
case ISO3166TwoEnum::_LBR:
return [self::_EN];
case ISO3166TwoEnum::_LBY:
return [self::_AR];
case ISO3166TwoEnum::_LIE:
return [self::_DE];
case ISO3166TwoEnum::_LTU:
return [self::_LT];
case ISO3166TwoEnum::_LUX:
return [self::_LB, self::_FR, self::_DE];
case ISO3166TwoEnum::_MAC:
return [self::_ZH, self::_PT];
case ISO3166TwoEnum::_MDG:
return [self::_MG, self::_FR];
case ISO3166TwoEnum::_MWI:
return [self::_NY, self::_EN];
case ISO3166TwoEnum::_MYS:
return [self::_MS];
case ISO3166TwoEnum::_MDV:
return [self::_DV];
case ISO3166TwoEnum::_MLI:
return [self::_FR];
case ISO3166TwoEnum::_MLT:
return [self::_MT, self::_EN];
case ISO3166TwoEnum::_MHL:
return [self::_MH, self::_EN];
case ISO3166TwoEnum::_MTQ:
return [self::_FR];
case ISO3166TwoEnum::_MRT:
return [self::_AR, self::_FR];
case ISO3166TwoEnum::_MUS:
return [self::_EN, self::_FR];
case ISO3166TwoEnum::_MYT:
return [self::_FR];
case ISO3166TwoEnum::_MEX:
return [self::_ES];
case ISO3166TwoEnum::_FSM:
return [self::_EN];
case ISO3166TwoEnum::_MDA:
return [self::_RO];
case ISO3166TwoEnum::_MCO:
return [self::_FR];
case ISO3166TwoEnum::_MNG:
return [self::_MN];
case ISO3166TwoEnum::_MNE:
return [self::_SR, self::_BS, self::_SQ, self::_HR];
case ISO3166TwoEnum::_MSR:
return [self::_EN];
case ISO3166TwoEnum::_MAR:
return [self::_AR];
case ISO3166TwoEnum::_MOZ:
return [self::_PT];
case ISO3166TwoEnum::_MMR:
return [self::_MY];
case ISO3166TwoEnum::_NAM:
return [self::_EN, self::_AF];
case ISO3166TwoEnum::_NRU:
return [self::_NA, self::_EN];
case ISO3166TwoEnum::_NPL:
return [self::_NE];
case ISO3166TwoEnum::_NLD:
return [self::_NL];
case ISO3166TwoEnum::_NCL:
return [self::_FR];
case ISO3166TwoEnum::_NZL:
return [self::_EN, self::_MI];
case ISO3166TwoEnum::_NIC:
return [self::_ES];
case ISO3166TwoEnum::_NER:
return [self::_FR];
case ISO3166TwoEnum::_NGA:
return [self::_EN];
case ISO3166TwoEnum::_NIU:
return [self::_EN];
case ISO3166TwoEnum::_NFK:
return [self::_EN];
case ISO3166TwoEnum::_MNP:
return [self::_EN, self::_CH];
case ISO3166TwoEnum::_NOR:
return [self::_NO, self::_NB, self::_NN];
case ISO3166TwoEnum::_OMN:
return [self::_AR];
case ISO3166TwoEnum::_PAK:
return [self::_UR, self::_EN];
case ISO3166TwoEnum::_PLW:
return [self::_EN, self::_JA, self::_ZH];
case ISO3166TwoEnum::_PSE:
return [self::_AR];
case ISO3166TwoEnum::_PAN:
return [self::_ES];
case ISO3166TwoEnum::_PNG:
return [self::_EN, self::_HO];
case ISO3166TwoEnum::_PRY:
return [self::_ES, self::_GN];
case ISO3166TwoEnum::_PER:
return [self::_ES, self::_QU, self::_AY];
case ISO3166TwoEnum::_PHL:
return [self::_EN];
case ISO3166TwoEnum::_PCN:
return [self::_EN];
case ISO3166TwoEnum::_POL:
return [self::_PL];
case ISO3166TwoEnum::_PRT:
return [self::_PT];
case ISO3166TwoEnum::_PRI:
return [self::_ES, self::_EN];
case ISO3166TwoEnum::_QAT:
return [self::_AR];
case ISO3166TwoEnum::_REU:
return [self::_FR];
case ISO3166TwoEnum::_ROU:
return [self::_RO];
case ISO3166TwoEnum::_RUS:
return [self::_RU];
case ISO3166TwoEnum::_RWA:
return [self::_RW, self::_EN, self::_FR];
case ISO3166TwoEnum::_BLM:
return [self::_FR];
case ISO3166TwoEnum::_SHN:
return [self::_EN];
case ISO3166TwoEnum::_KNA:
return [self::_EN];
case ISO3166TwoEnum::_LCA:
return [self::_EN];
case ISO3166TwoEnum::_MAF:
return [self::_FR, self::_EN, self::_NL];
case ISO3166TwoEnum::_SPM:
return [self::_FR];
case ISO3166TwoEnum::_VCT:
return [self::_EN];
case ISO3166TwoEnum::_WSM:
return [self::_SM, self::_EN];
case ISO3166TwoEnum::_SMR:
return [self::_IT];
case ISO3166TwoEnum::_STP:
return [self::_PT];
case ISO3166TwoEnum::_SAU:
return [self::_AR];
case ISO3166TwoEnum::_SEN:
return [self::_FR, self::_WO];
case ISO3166TwoEnum::_SRB:
return [self::_SR];
case ISO3166TwoEnum::_SYC:
return [self::_FR, self::_EN];
case ISO3166TwoEnum::_SLE:
return [self::_EN];
case ISO3166TwoEnum::_SGP:
return [self::_EN, self::_MS, self::_TA, self::_ZH];
case ISO3166TwoEnum::_SXM:
return [self::_NL, self::_EN];
case ISO3166TwoEnum::_SVK:
return [self::_SK];
case ISO3166TwoEnum::_SVN:
return [self::_SL];
case ISO3166TwoEnum::_SLB:
return [self::_EN];
case ISO3166TwoEnum::_SOM:
return [self::_SO, self::_AR, self::_IT, self::_EN];
case ISO3166TwoEnum::_ZAF:
return [self::_ZU, self::_XH, self::_AF, self::_EN, self::_TN, self::_ST, self::_TS, self::_SS, self::_VE];
case ISO3166TwoEnum::_SGS:
return [self::_EN];
case ISO3166TwoEnum::_KOR:
return [self::_KO];
case ISO3166TwoEnum::_SSD:
return [self::_EN];
case ISO3166TwoEnum::_ESP:
return [self::_ES];
case ISO3166TwoEnum::_LKA:
return [self::_SI, self::_TA, self::_EN];
case ISO3166TwoEnum::_SDN:
return [self::_AR, self::_EN];
case ISO3166TwoEnum::_SUR:
return [self::_NL];
case ISO3166TwoEnum::_SJM:
return [self::_NO];
case ISO3166TwoEnum::_SWZ:
return [self::_EN, self::_SS];
case ISO3166TwoEnum::_SWE:
return [self::_SV];
case ISO3166TwoEnum::_CHE:
return [self::_DE, self::_FR, self::_IT];
case ISO3166TwoEnum::_SYR:
return [self::_AR];
case ISO3166TwoEnum::_TWN:
return [self::_ZH];
case ISO3166TwoEnum::_TJK:
return [self::_TG, self::_RU];
case ISO3166TwoEnum::_TZA:
return [self::_SW, self::_EN];
case ISO3166TwoEnum::_THA:
return [self::_TH];
case ISO3166TwoEnum::_TLS:
return [self::_PT];
case ISO3166TwoEnum::_TGO:
return [self::_FR];
case ISO3166TwoEnum::_TKL:
return [self::_EN];
case ISO3166TwoEnum::_TON:
return [self::_EN, self::_TO];
case ISO3166TwoEnum::_TTO:
return [self::_EN];
case ISO3166TwoEnum::_TUN:
return [self::_AR];
case ISO3166TwoEnum::_TUR:
return [self::_TR];
case ISO3166TwoEnum::_TKM:
return [self::_TK, self::_RU];
case ISO3166TwoEnum::_TCA:
return [self::_EN];
case ISO3166TwoEnum::_TUV:
return [self::_EN];
case ISO3166TwoEnum::_UGA:
return [self::_EN, self::_SW];
case ISO3166TwoEnum::_UKR:
return [self::_UK];
case ISO3166TwoEnum::_ARE:
return [self::_AR];
case ISO3166TwoEnum::_GBR:
return [self::_EN, self::_CY, self::_GD, self::_GA];
case ISO3166TwoEnum::_USA:
return [self::_EN, self::_ES];
case ISO3166TwoEnum::_UMI:
return [self::_EN];
case ISO3166TwoEnum::_URY:
return [self::_ES];
case ISO3166TwoEnum::_UZB:
return [self::_UZ, self::_RU];
case ISO3166TwoEnum::_VUT:
return [self::_BI, self::_EN, self::_FR];
case ISO3166TwoEnum::_VEN:
return [self::_ES];
case ISO3166TwoEnum::_VNM:
return [self::_VI];
case ISO3166TwoEnum::_VGB:
return [self::_EN];
case ISO3166TwoEnum::_VIR:
return [self::_EN];
case ISO3166TwoEnum::_WLF:
return [self::_FR];
case ISO3166TwoEnum::_ESH:
return [self::_AR, self::_ES];
case ISO3166TwoEnum::_YEM:
return [self::_AR];
case ISO3166TwoEnum::_ZMB:
return [self::_EN];
case ISO3166TwoEnum::_ZWE:
return [self::_EN, self::_SN, self::_ND];
default:
return [];
}
}
}

View File

@ -118,6 +118,8 @@ class ISO639Enum extends Enum
public const _FJ = 'Fijian';
public const _FIL = 'Filipino';
public const _FO = 'Faroese';
public const _FR = 'French';
@ -393,4 +395,6 @@ class ISO639Enum extends Enum
public const _ZH = 'Chinese';
public const _ZU = 'Zulu';
use ISO639CountryTrait;
}

View File

@ -74,6 +74,8 @@ class ISO639x1Enum extends Enum
public const _BG = 'bg';
public const _MS = 'ms';
public const _MY = 'my';
public const _CA = 'ca';
@ -86,6 +88,8 @@ class ISO639x1Enum extends Enum
public const _CV = 'cv';
public const _KU = 'ku';
public const _KW = 'kw';
public const _KO = 'ko';
@ -120,6 +124,8 @@ class ISO639x1Enum extends Enum
public const _FI = 'fi';
public const _FIL = 'fil';
public const _FR = 'fr';
public const _FF = 'ff';
@ -262,6 +268,8 @@ class ISO639x1Enum extends Enum
public const _OS = 'os';
public const _PA = 'pa';
public const _PI = 'pi';
public const _FA = 'fa';
@ -322,6 +330,8 @@ class ISO639x1Enum extends Enum
public const _TE = 'te';
public const _TG = 'tg';
public const _TH = 'th';
public const _TI = 'ti';
@ -348,6 +358,8 @@ class ISO639x1Enum extends Enum
public const _UR = 'ur';
public const _UZ = 'uz';
public const _VE = 've';
public const _VI = 'vi';
@ -373,4 +385,6 @@ class ISO639x1Enum extends Enum
public const _ZU = 'zu';
public const _ZH = 'zh';
use ISO639CountryTrait;
}

View File

@ -120,6 +120,8 @@ class ISO639x2Enum extends Enum
public const _FI = 'fin';
public const _FIL = 'fil';
public const _FR = 'fra';
public const _FF = 'ful';
@ -393,4 +395,6 @@ class ISO639x2Enum extends Enum
public const _ZA = 'zha';
public const _ZU = 'zul';
use ISO639CountryTrait;
}

View File

@ -17,6 +17,7 @@ namespace phpOMS\Localization;
use phpOMS\Autoloader;
use phpOMS\Log\FileLogger;
use phpOMS\Module\ModuleAbstract;
use phpOMS\Stdlib\Base\FloatInt;
/**
* Localization class.
@ -206,22 +207,31 @@ final class L11nManager
/**
* Print a numeric value
*
* @param Localization $l11n Localization
* @param int|float $numeric Numeric value to print
* @param null|string $format Format type to use
* @param Localization $l11n Localization
* @param int|float|FloatInt $numeric Numeric value to print
* @param null|string $format Format type to use
*
* @return string
*
* @since 1.0.0
*/
public function getNumeric(Localization $l11n, int | float $numeric, string $format = null) : string
public function getNumeric(Localization $l11n, int | float | FloatInt $numeric, string $format = null) : string
{
return \number_format(
$numeric,
$l11n->getPrecision()[$format ?? 'medium'],
$l11n->getDecimal(),
$l11n->getThousands()
if (!($numeric instanceof FloatInt)) {
return \number_format(
$numeric,
$l11n->getPrecision()[$format ?? 'medium'],
$l11n->getDecimal(),
$l11n->getThousands()
);
}
$numeric->setLocalization(
$l11n->getThousands(),
$l11n->getDecimal()
);
return $numeric->getAmount($l11n->getPrecision()[$format ?? 'medium']);
}
/**
@ -247,17 +257,23 @@ final class L11nManager
/**
* Print a currency
*
* @param Localization $l11n Localization
* @param int|float $currency Currency value to print
* @param null|string $format Format type to use
* @param null|string $symbol Currency name/symbol
* @param int $divide Divide currency by divisor
* @param Localization $l11n Localization
* @param int|float|Money $currency Currency value to print
* @param null|string $symbol Currency name/symbol
* @param null|string $format Format type to use
* @param int $divide Divide currency by divisor
*
* @return string
*
* @since 1.0.0
*/
public function getCurrency(Localization $l11n, int | float $currency, string $format = null, string $symbol = null, int $divide = 1) : string
public function getCurrency(
Localization $l11n,
int | float | Money $currency,
string $symbol = null,
string $format = null,
int $divide = 1
) : string
{
$language = $l11n->getLanguage();
$symbol ??= $l11n->getCurrency();
@ -266,7 +282,7 @@ final class L11nManager
$currency = (int) ($currency * \pow(10, Money::MAX_DECIMALS));
}
if (!empty($symbol)) {
if ($divide > 1 && !empty($symbol)) {
if ($divide === 1000) {
$symbol = $this->getHtml($language, '0', '0', 'CurrencyK') . $symbol;
} elseif ($divide === 1000000) {
@ -276,7 +292,10 @@ final class L11nManager
}
}
$money = new Money((int) ($currency / $divide));
$money = !($currency instanceof Money)
? new Money((int) ($currency / $divide))
: $currency;
$money->setLocalization(
$l11n->getThousands(),
$l11n->getDecimal(),

View File

@ -108,14 +108,14 @@ abstract class NgramParser
}
}
if (!\count($tokens)) {
if (empty($tokens)) {
return [];
}
$tokens = \array_merge(...$tokens);
unset($tokens['_']);
\arsort($tokens, SORT_NUMERIC);
\arsort($tokens, \SORT_NUMERIC);
return \array_slice(
\array_keys($tokens),

View File

@ -39,7 +39,7 @@ class WhitespaceTokenizer
function ($word) {
return "_{$word}_";
},
\preg_split('/[^\pL]+(?<![\x27\x60\x{2019}])/u', $str, -1, PREG_SPLIT_NO_EMPTY)
\preg_split('/[^\pL]+(?<![\x27\x60\x{2019}])/u', $str, -1, \PREG_SPLIT_NO_EMPTY)
);
}
}

View File

@ -42,7 +42,7 @@ class Localization implements \JsonSerializable
* @var string
* @since 1.0.0
*/
protected string $country = ISO3166TwoEnum::_USA;
protected string $country = ISO3166TwoEnum::_XXX;
/**
* Timezone.
@ -338,14 +338,12 @@ class Localization implements \JsonSerializable
*
* @return void
*
* @throws InvalidEnumValue This exception is thrown if the country is invalid
*
* @since 1.0.0
*/
public function setCountry(string $country) : void
{
if (!ISO3166TwoEnum::isValidValue($country)) {
throw new InvalidEnumValue($country);
$this->country = '';
}
$this->country = $country;

View File

@ -201,7 +201,7 @@ final class NaiveBayesClassifier
$this->probabilities['attr'][$attr] = ['data' => []];
}
foreach ($valueArray['data'] as $word => $count) {
foreach ($valueArray['data'] as $word => $_) {
if (!isset($this->dict[$criteria][$attr]['data'][$word])) {
continue;
}

View File

@ -17,6 +17,7 @@ namespace phpOMS\Message\Http;
use phpOMS\Localization\Localization;
use phpOMS\Message\RequestAbstract;
use phpOMS\Router\RouteVerb;
use phpOMS\Security\Guard;
use phpOMS\Uri\HttpUri;
use phpOMS\Uri\UriInterface;
@ -94,6 +95,7 @@ final class HttpRequest extends RequestAbstract
self::cleanupGlobals();
$this->data = \array_change_key_case($this->data, \CASE_LOWER);
$this->data = Guard::unslash($this->data);
}
/**
@ -106,9 +108,10 @@ final class HttpRequest extends RequestAbstract
private function initCurrentRequest() : void
{
$this->uri = HttpUri::fromCurrent();
$this->data = $_GET + $_POST;
$this->data = $_POST + $_GET;
$this->files = $_FILES;
$this->header->l11n->setLanguage($this->getRequestLanguage());
$this->header->l11n->setCountry($this->getRequestCountry());
$this->initNonGetData();
}
@ -381,6 +384,31 @@ final class HttpRequest extends RequestAbstract
return \strtolower($firstLocalComponents[0]); // @codeCoverageIgnore
}
/**
* Get request language
*
* @return string
*
* @since 1.0.0
*/
public function getRequestCountry() : string
{
if (!isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
return '';
}
// @codeCoverageIgnoreStart
$components = \explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$locals = \stripos($components[0], ',') !== false
? $locals = \explode(',', $components[0])
: $components;
$firstLocalComponents = \explode('-', $locals[0]);
// @codeCoverageIgnoreEnd
return \strtoupper($firstLocalComponents[1] ?? ''); // @codeCoverageIgnore
}
/**
* Get request locale
*
@ -396,7 +424,9 @@ final class HttpRequest extends RequestAbstract
// @codeCoverageIgnoreStart
$components = \explode(';', $_SERVER['HTTP_ACCEPT_LANGUAGE']);
$locals = \stripos($components[0], ',') !== false ? $locals = \explode(',', $components[0]) : $components;
$locals = \stripos($components[0], ',') !== false
? $locals = \explode(',', $components[0])
: $components;
// @codeCoverageIgnoreEnd
return \str_replace('-', '_', $locals[0]); // @codeCoverageIgnore

View File

@ -92,7 +92,7 @@ final class Rest
/* @phpstan-ignore-next-line */
$data = self::createMultipartData($boundary, $request->getData());
// @todo: replace boundary/ with the correct boundary= in the future.
// @todo: Replace boundary/ with the correct boundary= in the future.
// Currently this cannot be done due to a bug. If we do it now the server cannot correclty populate php://input
$headers['content-type'] = 'Content-Type: multipart/form-data; boundary/' . $boundary;
$headers['content-length'] = 'Content-Length: ' . \strlen($data);

View File

@ -336,6 +336,18 @@ abstract class RequestAbstract implements MessageInterface
return $this->header->l11n->getLanguage();
}
/**
* Get request language.
*
* @return string
*
* @since 1.0.0
*/
public function getCountry() : string
{
return $this->header->l11n->getCountry();
}
/**
* Get request hash.
*

View File

@ -101,8 +101,9 @@ final class Head implements RenderableInterface
/**
* Add asset.
*
* @param int $type Asset type
* @param string $uri Asset uri
* @param int $type Asset type
* @param string $uri Asset uri
* @param array $attributes Asset attributes
*
* @return void
*
@ -116,8 +117,9 @@ final class Head implements RenderableInterface
/**
* Add tag.
*
* @param int $type Asset type
* @param string $uri Asset uri
* @param int $type Asset type
* @param string $content Asset content
* @param array $attributes Asset attributes
*
* @return void
*

View File

@ -74,7 +74,7 @@ interface RouterInterface
* @param string $uri Route
* @param string $csrf CSRF token
* @param int $verb Route verb
* @param string $app Application name
* @param int $app Application name
* @param int $unitId Organization id
* @param Account $account Account
* @param array $data Data
@ -87,7 +87,7 @@ interface RouterInterface
string $uri,
string $csrf = null,
int $verb = RouteVerb::GET,
string $app = null,
int $app = null,
int $unitId = null,
Account $account = null,
array $data = null

View File

@ -113,7 +113,7 @@ final class SocketRouter implements RouterInterface
string $uri,
string $csrf = null,
int $verb = RouteVerb::GET,
string $app = null,
int $app = null,
int $unitId = null,
Account $account = null,
array $data = null

View File

@ -115,7 +115,7 @@ final class WebRouter implements RouterInterface
string $uri,
string $csrf = null,
int $verb = RouteVerb::GET,
string $app = null,
int $app = null,
int $unitId = null,
Account $account = null,
array $data = null

View File

@ -52,4 +52,29 @@ final class Guard
{
return \stripos(FileUtils::absolute($path), FileUtils::absolute(empty($base) ? self::$BASE_PATH : $base)) === 0;
}
/**
* Remove slashes from a string or array
*
* @param string|array $data Data to unslash
*
* @return string|array
*
* @since 1.0.0
*/
public static function unslash(string | array $data) : string|array
{
if (\is_array($data)) {
$result = [];
foreach ($data as $key => $value) {
$result[$key] = self::unslash($value);
}
return $result;
} elseif (\is_string($data)) {
return \stripslashes($data);
}
return $data;
}
}

View File

@ -633,6 +633,18 @@ class Graph
return $longestPath;
}
/**
* Perform depth first traversal
*
* @param Node $node Graph node
* @param array $visited Is the node already visited
* @param array $path Array of nodes (a path through the graph = connected nodes)
* @param array $longestPath Array of nodes (longest path through the graph = connected nodes)
*
* @return void
*
* @since 1.0.0
*/
private function longestPathDfs(Node $node, &$visited, &$path, &$longestPath)
{
$visited[$node->getId()] = true;

View File

@ -172,6 +172,15 @@ class Node
return $this->edges[$key] ?? null;
}
/**
* Check if the node has a certain neighbor
*
* @param Node $node Neighbor node
*
* @return bool
*
* @since 1.0.0
*/
public function hasNeighbor(self $node) : bool
{
foreach ($this->edges as $edge) {

View File

@ -166,7 +166,7 @@ final class MultiMap implements \Countable
*/
private function garbageCollectValues() : void
{
foreach ($this->values as $valueKey => $value) {
foreach ($this->values as $valueKey => $_) {
if (!\in_array($valueKey, $this->keys)) {
unset($this->values[$valueKey]);
}

View File

@ -391,6 +391,8 @@ class Directory extends FileAbstract implements DirectoryInterface
continue;
}
$e = [];
list(
$e['permission'],
$e['number'],

View File

@ -86,7 +86,7 @@ final class UriFactory
if ($identifier === '*') {
self::$uri = [];
} else {
foreach (self::$uri as $key => $value) {
foreach (self::$uri as $key => $_) {
if (\stripos($key, $identifier) === 0) {
unset(self::$uri[$key]);
}

View File

@ -794,7 +794,7 @@ class QR extends TwoDAbstract
{
$b = 0;
$bitMask = [];
$bitMask = $this->generateMaskNo($maskNo, $width, $s, $d);
$bitMask = $this->generateMaskNo($maskNo, $width, $s);
if ($maskGenOnly) {
return 0;

View File

@ -114,7 +114,7 @@ final class Currency
$node = $xml->Cube->Cube->Cube;
self::$ecbCurrencies = [];
foreach ($node as $key => $value) {
foreach ($node as $value) {
/** @var null|array<string, string|int|float> $attributes */
if (($attributes = $value->attributes()) === null) {
continue;

View File

@ -12,9 +12,27 @@
*/
declare(strict_types=1);
/**
* iCal parser.
*
* @package phpOMS\Utils\Parser\Calendar
* @license OMS License 2.0
* @link https://jingga.app
* @since 1.0.0
*/
class ICalParser
{
public static function parse(string $data) {
/**
* Parse iCal data
*
* @param string $data iCal data
*
* @return array
*
* @since 1.0.0
*/
public static function parse(string $data) : array
{
\preg_match_all('/BEGIN:VEVENT(.*?)END:VEVENT/s', $data, $matches, PREG_SET_ORDER);
$eventList = [];
@ -54,8 +72,19 @@ class ICalParser
$eventList[] = $event;
}
return $eventList;
}
/**
* Parse rrule
*
* @param string $rruleString rrule string
*
* @return array
*
* @since 1.0.0
*/
private static function parseRRule($rruleString) : array
{
$rrule = [];

View File

@ -28,16 +28,6 @@ use PhpOffice\PhpSpreadsheet\Writer\Pdf;
*/
class SpreadsheetWriter extends Pdf
{
/**
* Render Pdf
*
* @todo: can be removed?
*
* @var bool
* @since 1.0.0
*/
protected bool $isMPdf = true;
/**
* Save Spreadsheet to file.
*
@ -47,6 +37,8 @@ class SpreadsheetWriter extends Pdf
*/
public function toPdfString(): string
{
$this->isMPdf = true;
$pdf = new \Mpdf\Mpdf();
// Check for paper size and page orientation

View File

@ -290,7 +290,7 @@ final class StringUtils
break;
}
// @todo: this should not be necessary
// @todo: This should not be necessary but the algorithm above allows for weird combinations.
return \str_replace(
['</del></del>', '</ins></ins>', '<ins></ins>', '<del></del>', '</ins><ins>', '</del><del>', '</ins> <del>', '</del> <ins>'],
['</del>', '</ins>', '', '', '', '', '</ins><del>', '</del><ins>'],

View File

@ -16,10 +16,12 @@ namespace phpOMS\Views;
use phpOMS\Localization\L11nManager;
use phpOMS\Localization\Localization;
use phpOMS\Localization\Money;
use phpOMS\Message\RequestAbstract;
use phpOMS\Message\ResponseAbstract;
use phpOMS\Module\Exception\InvalidModuleException;
use phpOMS\Module\Exception\InvalidThemeException;
use phpOMS\Stdlib\Base\FloatInt;
/**
* Basic view which can be used as basis for specific implementations.
@ -308,14 +310,14 @@ class View extends ViewAbstract
/**
* Print a numeric value
*
* @param int|float $numeric Numeric value to print
* @param null|string $format Format type to use
* @param int|float|FloatInt $numeric Numeric value to print
* @param null|string $format Format type to use
*
* @return string
*
* @since 1.0.0
*/
public function getNumeric(int | float $numeric, string $format = null) : string
public function getNumeric(int | float | FloatInt $numeric, string $format = null) : string
{
return $this->l11nManager->getNumeric($this->l11n, $numeric, $format);
}
@ -338,18 +340,24 @@ class View extends ViewAbstract
/**
* Print a currency
*
* @param int|float $currency Currency value to print
* @param null|string $format Format type to use
* @param null|string $symbol Currency name/symbol
* @param int $divide Divide currency by divisor
* @param int|float|Money $currency Currency value to print
* @param int $precision Precision
* @param null|string $symbol Currency name/symbol
* @param null|string $format Format type to use
* @param int $divide Divide currency by divisor
*
* @return string
*
* @since 1.0.0
*/
public function getCurrency(int | float $currency, string $format = null, string $symbol = null, int $divide = 1) : string
public function getCurrency(
int | float | Money $currency,
string $symbol = null,
string $format = null,
int $divide = 1
) : string
{
return $this->l11nManager->getCurrency($this->l11n, $currency, $format, $symbol, $divide);
return $this->l11nManager->getCurrency($this->l11n, $currency, $symbol, $format, $divide);
}
/**

View File

@ -0,0 +1,39 @@
<?php
/**
* Karaka
*
* PHP Version 8.1
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\tests\Api\EUVAT;
use phpOMS\Api\EUVAT\EUVATBffOnline;
/**
* @testdox phpOMS\tests\Api\EUVAT\EUVATBffOnlineTest: EU VAT German BFF Online validation
*
* @internal
*/
final class EUVATBffOnlineTest extends \PHPUnit\Framework\TestCase
{
/**
* @testdox The BFF Online service can validate a valid VAT ID
* @covers phpOMS\Api\EUVAT\EUVATBffOnline
* @group framework
*/
public function testValidateInvalidId() : void
{
$bff = new EUVATBffOnline();
$status = $bff->validate('DE123456789', 'DE123456789');
self::assertEquals(0, $status['status']);
self::assertEquals('C', $status['vat']);
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* Karaka
*
* PHP Version 8.1
*
* @package tests
* @copyright Dennis Eichhorn
* @license OMS License 2.0
* @version 1.0.0
* @link https://jingga.app
*/
declare(strict_types=1);
namespace phpOMS\tests\Api\EUVAT;
use phpOMS\Api\EUVAT\EUVATVies;
/**
* @testdox phpOMS\tests\Api\EUVAT\EUVATViesTest: EU VAT Vies validation
*
* @internal
*/
final class EUVATViesTest extends \PHPUnit\Framework\TestCase
{
/**
* @testdox The VIES service can validate a valid VAT ID
* @covers phpOMS\Api\EUVAT\EUVATVies
* @group framework
*/
public function testValidateInvalidId() : void
{
$vies = new EUVATVies();
$status = $vies->validate('DE123456789');
self::assertEquals(0, $status['status']);
self::assertEquals('C', $status['vat']);
}
}

View File

@ -7,4 +7,4 @@ use phpOMS\Message\Http\HttpRequest;
$request = HttpRequest::createFromSuperglobals();
echo $request->getRequestLanguage();
echo $request->getCountry();

View File

@ -59,7 +59,7 @@ final class HttpRequestTest extends \PHPUnit\Framework\TestCase
self::assertEquals('', $request->__toString());
self::assertFalse($request->hasData('key'));
self::assertNull($request->getData('key'));
self::assertEquals('en', $request->getRequestLanguage());
self::assertEquals('en', $request->getCountry());
self::assertEquals('en_US', $request->getLocale());
}

View File

@ -135,7 +135,7 @@ final class NodeTest extends \PHPUnit\Framework\TestCase
self::assertInstanceOf(Edge::class, $edge = $node1->setNodeRelative($node2, null, false));
self::assertCount(1, $node2->getEdges());
self::assertFalse($edge->isDirected());
self::assertFalse($edge->isDirected);
}
/**
@ -173,7 +173,7 @@ final class NodeTest extends \PHPUnit\Framework\TestCase
$node1->setNodeRelative($node2);
$node1->setNodeRelative($node3);
self::assertEquals('C', $node1->getEdgeByNeighbor($node3)->getNode2()->getId());
self::assertEquals('C', $node1->getEdgeByNeighbor($node3)->node2->getId());
self::assertNull($node1->getEdgeByNeighbor($node4));
}
}