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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@
"packages/support/src/Math/constants.php",
"packages/support/src/Math/functions.php",
"packages/support/src/Namespace/functions.php",
"packages/support/src/Number/functions.php",
"packages/support/src/Path/functions.php",
"packages/support/src/Random/functions.php",
"packages/support/src/Regex/functions.php",
Expand Down
3 changes: 1 addition & 2 deletions packages/core/src/AppConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

namespace Tempest\Core;

use Tempest\Core\Exceptions\LogExceptionProcessor;

use function Tempest\env;

final class AppConfig
Expand All @@ -16,6 +14,7 @@ final class AppConfig

public function __construct(
?Environment $environment = null,

?string $baseUri = null,

/** @var class-string<\Tempest\Core\ExceptionProcessor>[] */
Expand Down
3 changes: 2 additions & 1 deletion packages/support/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
"src/Math/constants.php",
"src/Math/functions.php",
"src/Json/functions.php",
"src/Filesystem/functions.php"
"src/Filesystem/functions.php",
"src/Number/functions.php"
]
},
"autoload-dev": {
Expand Down
167 changes: 167 additions & 0 deletions packages/support/src/Currency.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
<?php

namespace Tempest\Support;

/**
* Represents an ISO-4217 currency.
*/
enum Currency
{
case AED;
case AFN;
case ALL;
case AMD;
case AOA;
case ARS;
case AUD;
case AWG;
case AZN;
case BAM;
case BBD;
case BDT;
case BGN;
case BHD;
case BIF;
case BMD;
case BND;
case BOB;
case BRL;
case BSD;
case BTN;
case BWP;
case BYN;
case BZD;
case CAD;
case CDF;
case CHF;
case CLP;
case CNY;
case COP;
case CRC;
case CUP;
case CVE;
case CZK;
case DJF;
case DKK;
case DOP;
case DZD;
case EGP;
case ERN;
case ETB;
case EUR;
case FJD;
case FKP;
case GBP;
case GEL;
case GHS;
case GIP;
case GMD;
case GNF;
case GTQ;
case GYD;
case HKD;
case HNL;
case HTG;
case HUF;
case IDR;
case ILS;
case INR;
case IQD;
case IRR;
case ISK;
case JMD;
case JOD;
case JPY;
case KES;
case KGS;
case KHR;
case KMF;
case KPW;
case KRW;
case KWD;
case KYD;
case KZT;
case LAK;
case LBP;
case LKR;
case LRD;
case LSL;
case LYD;
case MAD;
case MDL;
case MGA;
case MKD;
case MMK;
case MNT;
case MOP;
case MRU;
case MUR;
case MVR;
case MWK;
case MXN;
case MYR;
case MZN;
case NAD;
case NGN;
case NIO;
case NOK;
case NPR;
case NZD;
case OMR;
case PAB;
case PEN;
case PGK;
case PHP;
case PKR;
case PLN;
case PYG;
case QAR;
case RON;
case RSD;
case RUB;
case RWF;
case SAR;
case SBD;
case SCR;
case SDG;
case SEK;
case SGD;
case SHP;
case SLE;
case SOS;
case SRD;
case SSP;
case STN;
case SVC;
case SYP;
case SZL;
case THB;
case TJS;
case TMT;
case TND;
case TOP;
case TRY;
case TTD;
case TWD;
case TZS;
case UAH;
case UGX;
case USD;
case UYU;
case UYW;
case UZS;
case VED;
case VES;
case VND;
case VUV;
case WST;
case XAF;
case XCD;
case XCG;
case XOF;
case XPF;
case YER;
case ZAR;
case ZMW;
case ZWG;
}
3 changes: 1 addition & 2 deletions packages/support/src/Math/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use function cos as php_cos;
use function count;
use function exp as php_exp;
use function floor as php_floor;
use function intdiv;
use function log as php_log;
use function round as php_round;
Expand Down Expand Up @@ -216,8 +217,6 @@ function exp(float $number): float
return php_exp($number);
}

use function floor as php_floor;

/**
* Return the largest integer value less then or equal to the given number.
*/
Expand Down
156 changes: 156 additions & 0 deletions packages/support/src/Number/functions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
<?php

namespace Tempest\Support\Number;

use NumberFormatter;
use Tempest\Support\Currency;
use Tempest\Support\Language\Locale;
use Tempest\Support\Math;

/**
* Formats the given number.
*
* @see https://www.php.net/manual/en/class.numberformatter.php
*/
function format(int|float $number, ?int $precision = null, ?int $maxPrecision = null, ?Locale $locale = null): string|false
{
$locale ??= Locale::ENGLISH;
$formatter = new NumberFormatter($locale->value, NumberFormatter::DECIMAL);

if (! is_null($maxPrecision)) {
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $maxPrecision);
} elseif (! is_null($precision)) {
$formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);
}

return $formatter->format($number);
}

/**
* Spells out the given number in the given locale.
*
* @see https://www.php.net/manual/en/class.numberformatter.php
*/
function spell_out(int|float $number, ?Locale $locale = null, ?int $after = null, ?int $until = null): string|false
{
$locale ??= Locale::ENGLISH;

if (! is_null($after) && $number <= $after) {
return namespace\format($number, locale: $locale);
}

if (! is_null($until) && $number >= $until) {
return namespace\format($number, locale: $locale);
}

$formatter = new NumberFormatter($locale->value, NumberFormatter::SPELLOUT);

return $formatter->format($number);
}

/**
* Converts the given number to ordinal form.
*
* @see https://www.php.net/manual/en/class.numberformatter.php
*/
function to_ordinal(int|float $number, ?Locale $locale = null): string|false
{
$locale ??= Locale::ENGLISH;
$formatter = new NumberFormatter($locale->value, NumberFormatter::ORDINAL);

return $formatter->format($number);
}

/**
* Spells out the given number in the given locale in ordinal form.
*
* @see https://www.php.net/manual/en/class.numberformatter.php
*/
function to_spelled_ordinal(int|float $number, ?Locale $locale = null): string|false
{
$locale ??= Locale::ENGLISH;
$formatter = new NumberFormatter($locale->value, NumberFormatter::SPELLOUT);
$formatter->setTextAttribute(NumberFormatter::DEFAULT_RULESET, '%spellout-ordinal');

return $formatter->format($number);
}

/**
* Converts the given number to its percentage equivalent.
*/
function to_percentage(int|float $number, int $precision = 0, ?int $maxPrecision = null, ?Locale $locale = null): string|false
{
$locale ??= Locale::ENGLISH;
$formatter = new NumberFormatter($locale->value, NumberFormatter::PERCENT);

if (! is_null($maxPrecision)) {
$formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $maxPrecision);
} else {
$formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);
}

return $formatter->format($number / 100);
}

/**
* Converts the given number to its currency equivalent.
*/
function currency(int|float $number, Currency $currency, ?Locale $locale = null, ?int $precision = null): string|false
{
$locale ??= Locale::ENGLISH;
$formatter = new NumberFormatter($locale->value, NumberFormatter::CURRENCY);

if (! is_null($precision)) {
$formatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $precision);
}

return $formatter->formatCurrency($number, $currency->name);
}

/**
* Converts the given number of bytes to its human-readable file size equivalent.
*/
function to_file_size(int|float $bytes, int $precision = 0, ?int $maxPrecision = null, bool $useBinaryPrefix = false): string
{
$base = $useBinaryPrefix ? 1024 : 1000;
$units = $useBinaryPrefix
? ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', 'RiB', 'QiB']
: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'RB', 'QB'];

for ($i = 0; ($bytes / $base) > 0.9 && $i < (count($units) - 1); $i++) {
$bytes /= $base;
}

return sprintf('%s %s', namespace\format($bytes, $precision, $maxPrecision), $units[$i]);
}

/**
* Converts the number to its human-readable equivalent.
*/
function to_human_readable(int|float $number, int $precision = 0, ?int $maxPrecision = null, array $units = []): string|false
{
if ($units === []) {
$units = [
3 => 'K',
6 => 'M',
9 => 'B',
12 => 'T',
15 => 'Q',
];
}

switch (true) {
case floatval($number) === 0.0:
return $precision > 0 ? namespace\format(0, $precision, $maxPrecision) : '0';
case $number < 0:
return sprintf('-%s', namespace\to_human_readable(Math\abs($number), $precision, $maxPrecision, $units));
case $number >= 1e15:
return sprintf('%s' . end($units), namespace\to_human_readable($number / 1e15, $precision, $maxPrecision, $units));
}

$numberExponent = Math\floor(Math\log($number, base: 10));
$displayExponent = $numberExponent - ($numberExponent % 3);
$number /= 10 ** $displayExponent;

return trim(sprintf('%s%s', namespace\format($number, $precision, $maxPrecision), $units[$displayExponent] ?? ''));
}
Loading