many fixes and expands and module expansions

This commit is contained in:
Dennis Eichhorn 2021-04-04 17:10:53 +02:00
parent 02313d3a33
commit 67f969a6b8
23 changed files with 510 additions and 340 deletions

View File

@ -62,10 +62,10 @@ class PermissionAbstract implements \JsonSerializable
/**
* Providing module id.
*
* @var int
* @var string
* @since 1.0.0
*/
protected int $from = 0;
protected ?string $from = null;
/**
* Type.
@ -105,7 +105,7 @@ class PermissionAbstract implements \JsonSerializable
* @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|string $module Module Module to check (null if all are acceptable)
* @param int $from Provided by which module
* @param null|string $from Provided by which module
* @param null|int $type Type (e.g. customer) (null if all are acceptable)
* @param null|int $element (e.g. customer id) (null if all are acceptable)
* @param null|int $component (e.g. address) (null if all are acceptable)
@ -117,7 +117,7 @@ class PermissionAbstract implements \JsonSerializable
int $unit = null,
string $app = null,
string $module = null,
int $from = 0,
string $from = null,
int $type = null,
int $element = null,
int $component = null,
@ -226,11 +226,11 @@ class PermissionAbstract implements \JsonSerializable
/**
* Get providing module id.
*
* @return int Returns the module responsible for setting this permission
* @return null|string Returns the module responsible for setting this permission
*
* @since 1.0.0
*/
public function getFrom() : int
public function getFrom() : ?string
{
return $this->from;
}
@ -238,13 +238,13 @@ class PermissionAbstract implements \JsonSerializable
/**
* Set providing module id.
*
* @param int $from Providing module
* @param null|string $from Providing module
*
* @return void
*
* @since 1.0.0
*/
public function setFrom(int $from = 0) : void
public function setFrom(string $from = null) : void
{
$this->from = $from;
}

View File

@ -12,8 +12,8 @@
*
* Extended based on:
* MIT License
* © 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* © PathFinding.js
* (c) 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* (c) PathFinding.js
*/
declare(strict_types=1);

View File

@ -12,8 +12,8 @@
*
* Extended based on:
* MIT License
* © 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* © PathFinding.js
* (c) 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* (c) PathFinding.js
*/
declare(strict_types=1);

View File

@ -12,8 +12,8 @@
*
* Extended based on:
* MIT License
* © 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* © PathFinding.js
* (c) 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* (c) PathFinding.js
*/
declare(strict_types=1);

View File

@ -12,8 +12,8 @@
*
* Extended based on:
* MIT License
* © 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* © PathFinding.js
* (c) 2011-2012 Xueqiao Xu <xueqiaoxu@gmail.com>
* (c) PathFinding.js
*/
declare(strict_types=1);

View File

@ -29,7 +29,7 @@ final class CustomerValue
*
* Hazard Model, same as $margin * (1 + $discountRate) / (1 + $discountRate - $retentionRate)
*
* @param float $margin Margin per period
* @param float $margin Margin per period (or revenue/sales)
* @param float $retentionRate Rate of remaining customers per period (= average lifetime / (1 + average lifetime))
* @param float $discountRate Cost of capital to discount future revenue
*
@ -42,6 +42,32 @@ final class CustomerValue
return $margin * $retentionRate / (1 + $discountRate - $retentionRate);
}
/**
* Basic customer lifetime value
*
* Hazard Model, same as $margin * (1 + $discountRate) / (1 + $discountRate - $retentionRate)
*
* @param array $margins Margin per period (or revenue/sales)
* @param float $retentionRate Rate of remaining customers per period (= average lifetime / (1 + average lifetime))
* @param float $discountRate Cost of capital to discount future revenue
*
* @return float
*
* @since 1.0.0
*/
public static function getBasicCLV(array $margins, float $retentionRate, float $discountRate) : float
{
$clv = 0.0;
$c = 1;
foreach ($margins as $margin) {
$clv += ($retentionRate ** $c) * $margin * \pow(1 / (1 + $discountRate), $c);
++$c;
}
return $clv;
}
/**
* Normalized measure of recurring revenue
*

View File

@ -58,6 +58,68 @@ final class Metrics
return ($ce - $cn) / $cs;
}
/**
* Calcualte the coefficient of retention
*
* @param float $retentionRate Observed retention rate (optionally use the average)
* @param float $rc Retention rate ceiling
* @param int $t Period
*
* @return float
*
* @since 1.0.0
*/
public static function getCoefficientOfRetention(float $retentionRate, float $rc, int $t) : float
{
return 1 / $t * \log($rc - $retentionRate);
}
/**
* Predict the retention rate for period t
*
* @param float $rc Retention rate ceiling
* @param float $r Coefficient of retention
* @param int $t Period t
*
* @return float
*
* @since 1.0.0
*/
public static function predictCustomerRetention(float $rc, float $r, int $t) : float
{
return $rc * (1 - \exp(-$r * $t));
}
/**
* Calculate the average lifetime duration
*
* @param array $retainedCustomers Retained customers per period
*
* @return float
*
* @since 1.0.0
*/
public static function averageLifetimeDuration(array $retainedCustomers) : float
{
return \array_sum($retainedCustomers) / \count($retainedCustomers);
}
/**
* Calculate the probability of a customer being active
*
* @param int $purchases Number of purchases during the periods
* @param int $periods Number of periods (e.g. number of months)
* @param int $lastPurchase In which period was the last purchase
*
* @return float
*
* @since 1.0.0
*/
public static function customerActiveProbability(int $purchases, int $periods, int $lastPurchase) : float
{
return \pow($lastPurchase / $periods, $purchases);
}
/**
* Calculate the customer profits
*

View File

@ -420,7 +420,7 @@ class DataMapperAbstract implements DataMapperInterface
}
if ($condValue['orderBy'] !== null) {
$where1->orderBy(static::$table . '_' . $searchDepth . '.' . static::$columns[$condValue['orderBy']], $condValue['sortOrder']);
$where1->orderBy(static::$table . '_' . $searchDepth . '.' . static::getColumnByMember($condValue['orderBy']), $condValue['sortOrder']);
}
if ($condValue['limit'] !== null) {
@ -899,14 +899,6 @@ class DataMapperAbstract implements DataMapperInterface
/** @var self $mapper */
$mapper = static::$hasMany[$propertyName]['mapper'];
if (\is_object($values)) {
// conditionals
TestUtils::setMember($values, $mapper::$columns[static::$hasMany[$propertyName]['self']]['internal'], $objId);
$mapper::createArray($values);
continue;
}
if (!\is_array($values)) {
continue;
}
@ -1160,14 +1152,13 @@ class DataMapperAbstract implements DataMapperInterface
$values = $obj->{$propertyName};
}
if (!\is_array($values)) {
// conditionals
if (!\is_array($values) || empty($values)) {
continue;
}
/** @var self $mapper */
$mapper = static::$hasMany[$propertyName]['mapper'];
$relReflectionClass = !empty($values) ? new \ReflectionClass(\reset($values)) : null;
$relReflectionClass = new \ReflectionClass(\reset($values));
$objsIds[$propertyName] = [];
foreach ($values as $key => &$value) {
@ -1178,7 +1169,6 @@ class DataMapperAbstract implements DataMapperInterface
continue;
}
/** @var \ReflectionClass @relReflectionClass */
$primaryKey = $mapper::getObjectId($value, $relReflectionClass);
// already in db
@ -2081,7 +2071,7 @@ class DataMapperAbstract implements DataMapperInterface
*/
public static function populateOwnsOne(string $member, array $result, int $depth = 3, mixed $default = null) : mixed
{
/** @var self $mapper */
/** @var self|string $mapper */
$mapper = static::$ownsOne[$member]['mapper'];
if ($depth < 1) {
@ -2121,7 +2111,7 @@ class DataMapperAbstract implements DataMapperInterface
*/
public static function populateOwnsOneArray(string $member, array $result, int $depth = 3, mixed $default = null) : array
{
/** @var self $mapper */
/** @var self|string $mapper */
$mapper = static::$ownsOne[$member]['mapper'];
if ($depth < 1) {
@ -2162,7 +2152,7 @@ class DataMapperAbstract implements DataMapperInterface
*/
public static function populateBelongsTo(string $member, array $result, int $depth = 3, mixed $default = null) : mixed
{
/** @var self $mapper */
/** @var self|string $mapper */
$mapper = static::$belongsTo[$member]['mapper'];
if ($depth < 1) {
@ -2202,7 +2192,7 @@ class DataMapperAbstract implements DataMapperInterface
*/
public static function populateBelongsToArray(string $member, array $result, int $depth = 3, mixed $default = null) : array
{
/** @var self $mapper */
/** @var self|string $mapper */
$mapper = static::$belongsTo[$member]['mapper'];
if ($depth < 1) {
@ -3111,6 +3101,8 @@ class DataMapperAbstract implements DataMapperInterface
try {
$results = false;
$t = $query->toSql();
$sth = self::$db->con->prepare($query->toSql());
if ($sth !== false) {
$sth->execute();
@ -3323,7 +3315,7 @@ class DataMapperAbstract implements DataMapperInterface
// get BelognsToQuery
if ($depth > 1 && self::$relations === RelationType::ALL) {
foreach (static::$belongsTo as $rel) {
foreach (static::$belongsTo as $key => $rel) {
if (isset(self::$withFields[$key]) && self::$withFields[$key]['ignore']) {
continue;
}
@ -3348,7 +3340,7 @@ class DataMapperAbstract implements DataMapperInterface
// get HasManyQuery (but only for elements which have a 'column' defined)
if ($depth > 1 && self::$relations === RelationType::ALL) {
foreach (static::$hasMany as $rel) {
foreach (static::$hasMany as $key => $rel) {
// @todo: impl. conditiona/with handling, sort, limit, filter or is this not required here?
if (isset($rel['external']) || !isset($rel['column']) // @todo: conflict with getHasMany()???!?!?!?!
|| (isset(self::$withFields[$key]) && self::$withFields[$key]['ignore'])

View File

@ -28,6 +28,14 @@ use phpOMS\DataStorage\Database\Connection\ConnectionAbstract;
*/
class Builder extends BuilderAbstract
{
/**
* Log queries.
*
* @var bool
* @since 1.0.0
*/
public static bool $log = false;
/**
* Is read only.
*
@ -369,7 +377,13 @@ class Builder extends BuilderAbstract
$this->resolveJoinDependencies();
}
return $this->grammar->compileQuery($this);
$query = $this->grammar->compileQuery($this);
if (self::$log) {
\phpOMS\Log\FileLogger::getInstance()->debug($query);
}
return $query;
}
/**

View File

@ -83,7 +83,7 @@ class Country
/**
* Country developed.
*
* @var string
* @var bool
* @since 1.0.0
*/
protected bool $isDeveloped = false;

View File

@ -14,6 +14,8 @@ declare(strict_types=1);
namespace phpOMS\Localization;
use phpOMS\Stdlib\Base\FloatInt;
/**
* Money class.
*
@ -22,32 +24,8 @@ namespace phpOMS\Localization;
* @link https://orange-management.org
* @since 1.0.0
*/
final class Money implements \Serializable
final class Money extends FloatInt
{
/**
* Max amount of decimals.
*
* @var int
* @since 1.0.0
*/
public const MAX_DECIMALS = 4;
/**
* Thousands separator.
*
* @var string
* @since 1.0.0
*/
private string $thousands = ',';
/**
* Decimal separator.
*
* @var string
* @since 1.0.0
*/
private string $decimal = '.';
/**
* Currency symbol position
*
@ -64,14 +42,6 @@ final class Money implements \Serializable
*/
private string $symbol = ISO4217SymbolEnum::_USD;
/**
* Value.
*
* @var int
* @since 1.0.0
*/
private int $value = 0;
/**
* Constructor.
*
@ -85,48 +55,10 @@ final class Money implements \Serializable
*/
public function __construct(int | float | string $value = 0, string $thousands = ',', string $decimal = '.', string $symbol = '', int $position = 0)
{
$this->value = \is_int($value) ? $value : self::toInt((string) $value);
$this->thousands = $thousands;
$this->decimal = $decimal;
$this->symbol = $symbol;
$this->position = $position;
}
/**
* Money to int.
*
* @param string $value Money value
* @param string $thousands Thousands character
* @param string $decimal Decimal character
*
* @return int
*
* @throws \Exception this exception is thrown if an internal explode or substr error occurs
*
* @since 1.0.0
*/
public static function toInt(string $value, string $thousands = ',', string $decimal = '.') : int
{
$split = \explode($decimal, $value);
if ($split === false) {
throw new \Exception('Internal explode error.'); // @codeCoverageIgnore
}
$left = $split[0];
$left = \str_replace($thousands, '', $left);
$right = '';
if (\count($split) > 1) {
$right = $split[1];
}
$right = \substr($right, 0, self::MAX_DECIMALS);
if ($right === false) {
throw new \Exception('Internal substr error.'); // @codeCoverageIgnore
}
return ((int) $left) * 10 ** self::MAX_DECIMALS + (int) \str_pad($right, self::MAX_DECIMALS, '0');
parent::__construct($value, $thousands, $decimal);
}
/**
@ -143,30 +75,15 @@ final class Money implements \Serializable
*/
public function setLocalization(string $thousands = ',', string $decimal = '.', string $symbol = '', int $position = 0) : self
{
$this->thousands = $thousands;
$this->decimal = $decimal;
$this->symbol = $symbol;
$this->position = $position;
return $this;
}
/**
* Set value by string.
*
* @param string $value Money value
*
* @return Money
*
* @since 1.0.0
*/
public function setString(string $value) : self
{
$this->value = self::toInt($value, $this->thousands, $this->decimal);
parent::setLocalization($thousands, $decimal);
return $this;
}
/**
* Get money.
*
@ -180,200 +97,4 @@ final class Money implements \Serializable
{
return ($this->position === 0 && !empty($this->symbol) ? $this->symbol . ' ' : '') . $this->getAmount($decimals) . ($this->position === 1 ? ' ' . $this->symbol : '');
}
/**
* Get money.
*
* @param null|int $decimals Precision (null = auto decimals)
*
* @return string
*
* @throws \Exception this exception is thrown if an internal substr error occurs
*
* @since 1.0.0
*/
public function getAmount(?int $decimals = 2) : string
{
$value = $this->value === 0
? \str_repeat('0', self::MAX_DECIMALS)
: (string) \round($this->value, -self::MAX_DECIMALS + $decimals);
$left = \substr($value, 0, -self::MAX_DECIMALS);
/** @var string $left */
$left = $left === false ? '0' : $left;
$right = \substr($value, -self::MAX_DECIMALS);
if ($right === false) {
throw new \Exception(); // @codeCoverageIgnore
}
if ($decimals === null) {
$decimals = \strlen(\rtrim($right, '0'));
}
return $decimals > 0
? \number_format((float) $left, 0, $this->decimal, $this->thousands) . $this->decimal . \substr($right, 0, $decimals)
: \str_pad($left, 1, '0');
}
/**
* Add money.
*
* @param int|float|string|Money $value Value to add
*
* @return Money
*
* @since 1.0.0
*/
public function add(int | float | string | self $value) : self
{
if (\is_string($value) || \is_float($value)) {
$this->value += self::toInt((string) $value, $this->thousands, $this->decimal);
} elseif (\is_int($value)) {
$this->value += $value;
} else {
$this->value += $value->getInt();
}
return $this;
}
/**
* Get money value.
*
* @return int
*
* @since 1.0.0
*/
public function getInt() : int
{
return $this->value;
}
/**
* Sub money.
*
* @param int|float|string|Money $value Value to subtract
*
* @return Money
*
* @since 1.0.0
*/
public function sub(int | float | string | self $value) : self
{
if (\is_string($value) || \is_float($value)) {
$this->value -= self::toInt((string) $value, $this->thousands, $this->decimal);
} elseif (\is_int($value)) {
$this->value -= $value;
} else {
$this->value -= $value->getInt();
}
return $this;
}
/**
* Mult.
*
* @param int|float $value Value to multiply with
*
* @return Money
*
* @since 1.0.0
*/
public function mult(int | float $value) : self
{
$this->value = (int) ($this->value * $value);
return $this;
}
/**
* Div.
*
* @param int|float $value Value to divide by
*
* @return Money
*
* @since 1.0.0
*/
public function div(int | float $value) : self
{
$this->value = (int) ($this->value / $value);
return $this;
}
/**
* Abs.
*
* @return Money
*
* @since 1.0.0
*/
public function abs() : self
{
$this->value = \abs($this->value);
return $this;
}
/**
* Power.
*
* @param int|float $value Value to power
*
* @return Money
*
* @since 1.0.0
*/
public function pow(int | float $value) : self
{
$this->value = (int) ($this->value ** $value);
return $this;
}
/**
* Searialze.
*
* @return string
*
* @since 1.0.0
*/
public function serialize() : string
{
return (string) $this->getInt();
}
/**
* Unserialize.
*
* @param mixed $value Value to unserialize
*
* @return void
*
* @since 1.0.0
*/
public function unserialize($value) : void
{
$this->setInt((int) $value);
}
/**
* Set money value.
*
* @param int $value Value
*
* @return Money
*
* @since 1.0.0
*/
public function setInt(int $value) : self
{
$this->value = $value;
return $this;
}
}

View File

@ -19,6 +19,8 @@ use phpOMS\Math\Functions\Gamma;
/**
* Chi squared distribution.
*
* Test if two variables are similarly distributed (goodness fit, test dependency of variables)
*
* @package phpOMS\Math\Stochastic\Distribution
* @license OMS License 1.0
* @link https://orange-management.org

View File

@ -15,7 +15,9 @@ declare(strict_types=1);
namespace phpOMS\Math\Stochastic\Distribution;
/**
* Bernulli distribution.
* T distribution.
*
* Test the similarity of two means
*
* @package phpOMS\Math\Stochastic\Distribution
* @license OMS License 1.0

View File

@ -20,6 +20,8 @@ use phpOMS\Math\Statistic\MeasureOfDispersion;
/**
* ZTest
*
* Test if the mean is the same as the population mean
*
* @package phpOMS\Math\Stochastic\Distribution
* @license OMS License 1.0
* @link https://orange-management.org

View File

@ -12,8 +12,8 @@
*
* Extended based on:
* GLGPL 2.1 License
* © 2012 - 2015 Marcus Bointon, 2010 - 2012 Jim Jagielski, 2004 - 2009 Andy Prevost
* © PHPMailer
* (c) 2012 - 2015 Marcus Bointon, 2010 - 2012 Jim Jagielski, 2004 - 2009 Andy Prevost
* (c) PHPMailer
*/
declare(strict_types=1);

View File

@ -11,8 +11,8 @@
*
* Extended based on:
* GLGPL 2.1 License
* © 2012 - 2015 Marcus Bointon, 2010 - 2012 Jim Jagielski, 2004 - 2009 Andy Prevost
* © PHPMailer
* (c) 2012 - 2015 Marcus Bointon, 2010 - 2012 Jim Jagielski, 2004 - 2009 Andy Prevost
* (c) PHPMailer
*/
declare(strict_types=1);

View File

@ -11,8 +11,8 @@
*
* Extended based on:
* GLGPL 2.1 License
* © 2012 - 2015 Marcus Bointon, 2010 - 2012 Jim Jagielski, 2004 - 2009 Andy Prevost
* © PHPMailer
* (c) 2012 - 2015 Marcus Bointon, 2010 - 2012 Jim Jagielski, 2004 - 2009 Andy Prevost
* (c) PHPMailer
*/
declare(strict_types=1);

View File

@ -148,7 +148,7 @@ final class PhpCode
* Validate file integrety
*
* @param string $source Source code path
* @param string $hash Source hash
* @param string $hash Source hash (md5)
*
* @return bool Returns true if filee matches expected signature otherwise false is returned
*

View File

@ -37,4 +37,6 @@ abstract class AddressType extends Enum
public const CONTRACT = 6;
public const OTHER = 7;
public const EDUCATION = 8;
}

343
Stdlib/Base/FloatInt.php Normal file
View File

@ -0,0 +1,343 @@
<?php
/**
* Orange Management
*
* PHP Version 8.0
*
* @package phpOMS\Stdlib
* @copyright Dennis Eichhorn
* @license OMS License 1.0
* @version 1.0.0
* @link https://orange-management.org
*/
declare(strict_types=1);
namespace phpOMS\Stdlib\Base;
/**
* FloatInt class.
*
* @package phpOMS\Stdlib
* @license OMS License 1.0
* @link https://orange-management.org
* @since 1.0.0
*/
class FloatInt implements \Serializable
{
/**
* Max amount of decimals.
*
* @var int
* @since 1.0.0
*/
public const MAX_DECIMALS = 4;
/**
* Thousands separator.
*
* @var string
* @since 1.0.0
*/
protected string $thousands = ',';
/**
* Decimal separator.
*
* @var string
* @since 1.0.0
*/
protected string $decimal = '.';
/**
* Value.
*
* @var int
* @since 1.0.0
*/
protected int $value = 0;
/**
* Constructor.
*
* @param int|float|string $value Value
* @param string $thousands Thousands separator
* @param string $decimal Decimal separator
*
* @since 1.0.0
*/
public function __construct(int | float | string $value = 0, string $thousands = ',', string $decimal = '.')
{
$this->value = \is_int($value) ? $value : self::toInt((string) $value);
$this->thousands = $thousands;
$this->decimal = $decimal;
}
/**
* FloatInt to int.
*
* @param string $value FloatInt value
* @param string $thousands Thousands character
* @param string $decimal Decimal character
*
* @return int
*
* @throws \Exception this exception is thrown if an internal explode or substr error occurs
*
* @since 1.0.0
*/
public static function toInt(string $value, string $thousands = ',', string $decimal = '.') : int
{
$split = \explode($decimal, $value);
if ($split === false) {
throw new \Exception('Internal explode error.'); // @codeCoverageIgnore
}
$left = $split[0];
$left = \str_replace($thousands, '', $left);
$right = '';
if (\count($split) > 1) {
$right = $split[1];
}
$right = \substr($right, 0, self::MAX_DECIMALS);
if ($right === false) {
throw new \Exception('Internal substr error.'); // @codeCoverageIgnore
}
return ((int) $left) * 10 ** self::MAX_DECIMALS + (int) \str_pad($right, self::MAX_DECIMALS, '0');
}
/**
* Set localization.
*
* @param string $thousands Thousands separator
* @param string $decimal Decimal separator
*
* @return FloatInt
*
* @since 1.0.0
*/
public function setLocalization(string $thousands = ',', string $decimal = '.') : self
{
$this->thousands = $thousands;
$this->decimal = $decimal;
return $this;
}
/**
* Set value by string.
*
* @param string $value FloatInt value
*
* @return FloatInt
*
* @since 1.0.0
*/
public function setString(string $value) : self
{
$this->value = self::toInt($value, $this->thousands, $this->decimal);
return $this;
}
/**
* Get money.
*
* @param null|int $decimals Precision (null = auto decimals)
*
* @return string
*
* @throws \Exception this exception is thrown if an internal substr error occurs
*
* @since 1.0.0
*/
public function getAmount(?int $decimals = 2) : string
{
$isNegative = $this->value < 0 ? 1 : 0;
$value = $this->value === 0
? \str_repeat('0', self::MAX_DECIMALS)
: (string) \round($this->value, -self::MAX_DECIMALS + $decimals);
$left = \substr($value, 0, -self::MAX_DECIMALS + $isNegative);
/** @var string $left */
$left = $left === false ? '0' : $left;
$right = \substr($value, -self::MAX_DECIMALS + $isNegative);
if ($right === false) {
throw new \Exception(); // @codeCoverageIgnore
}
if ($decimals === null) {
$decimals = \strlen(\rtrim($right, '0'));
}
return $decimals > 0
? \number_format((float) $left, 0, $this->decimal, $this->thousands) . $this->decimal . \substr($right, 0, $decimals)
: \str_pad($left, 1, '0');
}
/**
* Add money.
*
* @param int|float|string|FloatInt $value Value to add
*
* @return FloatInt
*
* @since 1.0.0
*/
public function add(int | float | string | self $value) : self
{
if (\is_string($value) || \is_float($value)) {
$this->value += self::toInt((string) $value, $this->thousands, $this->decimal);
} elseif (\is_int($value)) {
$this->value += $value;
} else {
$this->value += $value->getInt();
}
return $this;
}
/**
* Get money value.
*
* @return int
*
* @since 1.0.0
*/
public function getInt() : int
{
return $this->value;
}
/**
* Sub money.
*
* @param int|float|string|FloatInt $value Value to subtract
*
* @return FloatInt
*
* @since 1.0.0
*/
public function sub(int | float | string | self $value) : self
{
if (\is_string($value) || \is_float($value)) {
$this->value -= self::toInt((string) $value, $this->thousands, $this->decimal);
} elseif (\is_int($value)) {
$this->value -= $value;
} else {
$this->value -= $value->getInt();
}
return $this;
}
/**
* Mult.
*
* @param int|float $value Value to multiply with
*
* @return FloatInt
*
* @since 1.0.0
*/
public function mult(int | float $value) : self
{
$this->value = (int) ($this->value * $value);
return $this;
}
/**
* Div.
*
* @param int|float $value Value to divide by
*
* @return FloatInt
*
* @since 1.0.0
*/
public function div(int | float $value) : self
{
$this->value = (int) ($this->value / $value);
return $this;
}
/**
* Abs.
*
* @return FloatInt
*
* @since 1.0.0
*/
public function abs() : self
{
$this->value = \abs($this->value);
return $this;
}
/**
* Power.
*
* @param int|float $value Value to power
*
* @return FloatInt
*
* @since 1.0.0
*/
public function pow(int | float $value) : self
{
$this->value = (int) ($this->value ** $value);
return $this;
}
/**
* Searialze.
*
* @return string
*
* @since 1.0.0
*/
public function serialize() : string
{
return (string) $this->getInt();
}
/**
* Unserialize.
*
* @param mixed $value Value to unserialize
*
* @return void
*
* @since 1.0.0
*/
public function unserialize($value) : void
{
$this->setInt((int) $value);
}
/**
* Set money value.
*
* @param int $value Value
*
* @return FloatInt
*
* @since 1.0.0
*/
public function setInt(int $value) : self
{
$this->value = $value;
return $this;
}
}

View File

@ -212,15 +212,17 @@ class Location implements \JsonSerializable, \Serializable
}
/**
* Constructs the object
* @link http://php.net/manual/en/serializable.unserialize.php
* @param string $serialized <p>
* The string representation of the object.
* </p>
* @return void
* @since 5.1.0
* {@inheritdoc}
*/
public function unserialize($serialized) : void
{
$data = \json_decode($serialized, true);
$this->postal = $data['postal'];
$this->city = $data['city'];
$this->country = $data['country'];
$this->address = $data['address'];
$this->state = $data['state'];
$this->geo = $data['geo'];
}
}

View File

@ -110,7 +110,9 @@ final class FileUtils
public static function absolute(string $origPath) : string
{
if (\file_exists($origPath) !== false) {
return \realpath($origPath);
$path = \realpath($origPath);
return $path === false ? '' : $path;
}
$startsWithSlash = \strpos($origPath, '/') === 0 || \strpos($origPath, '\\') === 0 ? '/' : '';

View File

@ -32,7 +32,7 @@ class MbStringUtilsTest extends \PHPUnit\Framework\TestCase
*/
public function testEntropy() : void
{
self::assertEqualsWithDelta(2.75, MbStringUtils::mb_entropy('akj@!©¥j'), 0.1);
self::assertEqualsWithDelta(2.75, MbStringUtils::mb_entropy('akj@!(c)¥j'), 0.1);
}
/**