-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
550 additions
and
496 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
.php_cs | ||
.php_cs.cache | ||
.phpunit.result.cache | ||
composer.lock | ||
phpunit.xml | ||
vendor/ | ||
composer.lock | ||
|
||
|
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
<?php | ||
|
||
namespace Pnz\TwigExtensionNumber; | ||
|
||
use Twig\Extension\AbstractExtension; | ||
use Twig\TwigFilter; | ||
|
||
final class Number extends AbstractExtension | ||
{ | ||
private const DEFAULT_DECIMALS = 2; | ||
private const UNITY_GRAM = 'g'; | ||
private const UNITY_METER = 'm'; | ||
private static $unities = [ | ||
self::UNITY_GRAM => [ | ||
'3' => 'K', // kilogram | ||
// '2' => 'H', | ||
// '1' => 'Da', | ||
'0' => '', | ||
// '-1' => 'd', // decigram | ||
// '-2' => 'c', // centigram | ||
'-3' => 'm', // milligram | ||
'-6' => 'µ', // microgram (mcg) | ||
'-9' => 'n', // nanogram | ||
'-12' => 'p', // picogram | ||
], | ||
self::UNITY_METER => [ | ||
'3' => 'K', // kilometer | ||
// '2' => 'H', | ||
// '1' => 'Da', | ||
'0' => '', | ||
// '-1' => 'd', // decimeter | ||
'-2' => 'c', // centimeter | ||
'-3' => 'm', // millimiter | ||
'-6' => 'µ', // micrometer | ||
'-9' => 'n', // nanometer | ||
'-12' => 'p', // picometer | ||
], | ||
]; | ||
|
||
public function getFilters(): array | ||
{ | ||
return [ | ||
new TwigFilter('format_bytes', [$this, 'formatBytes']), | ||
new TwigFilter('format_grams', [$this, 'formatGrams']), | ||
new TwigFilter('format_meters', [$this, 'formatMeters']), | ||
]; | ||
} | ||
|
||
/** | ||
* @param float|int|string $number | ||
* @param float|int $unityBias | ||
*/ | ||
public function formatMeters($number, int $decimals = 2, $unityBias = 1): string | ||
{ | ||
return $this->formatUnity($number, $decimals, self::UNITY_METER, $unityBias); | ||
} | ||
|
||
/** | ||
* @param float|int|string $number | ||
* @param float|int $unityBias | ||
*/ | ||
public function formatGrams($number, int $decimals = 2, $unityBias = 1): string | ||
{ | ||
return $this->formatUnity($number, $decimals, self::UNITY_GRAM, $unityBias); | ||
} | ||
|
||
/** | ||
* Filter for converting bytes to a human-readable format, as Unix command "ls -h" does. | ||
* | ||
* @param int|string $number a string or integer number value to format | ||
* @param bool $base2conversion defines if the conversion has to be strictly performed as binary values or | ||
* by using a decimal conversion such as 1 KByte = 1000 Bytes | ||
* | ||
* @return string the number converted to human readable representation | ||
* @todo: Use Intl-based translations to deal with "11.4" conversion to "11,4" value | ||
*/ | ||
public function formatBytes($number, bool $base2conversion = true): string | ||
{ | ||
if (!$this->isValidValue($number)) { | ||
return ''; | ||
} | ||
|
||
$unit = $base2conversion ? 1024 : 1000; | ||
if ($number < $unit) { | ||
return $number.' B'; | ||
} | ||
$exp = (int) (log($number) / log($unit)); | ||
$pre = ($base2conversion ? 'kMGTPE' : 'KMGTPE'); | ||
$pre = $pre[$exp - 1].($base2conversion ? '' : 'i'); | ||
|
||
return sprintf('%.1f %sB', $number / ($unit ** $exp), $pre); | ||
} | ||
|
||
/** | ||
* @param float|int|string $number | ||
* @param float|int $unityBias | ||
*/ | ||
protected function formatUnity($number, int $decimals, string $unity, $unityBias = 1): string | ||
{ | ||
if ($decimals < 0 || !$this->isValidValue($number)) { | ||
return ''; | ||
} | ||
if (null === $decimals) { | ||
$decimals = self::DEFAULT_DECIMALS; | ||
} | ||
|
||
if (1 !== $unityBias && 0 !== $unityBias && null !== $unityBias) { | ||
$number *= $unityBias; | ||
} | ||
|
||
$exp = (0 === $number) ? 0 : (int) log10(abs($number)); | ||
$exp = $this->getNearestExp($exp, $unity); | ||
$pre = $this->getUnityPrefix($exp, $unity); | ||
$value = $number / (10 ** $exp); | ||
|
||
return sprintf('%.'.$decimals.'f %s'.$unity, $value, $pre); | ||
} | ||
|
||
/** | ||
* @param mixed $number | ||
*/ | ||
private function isValidValue($number): bool | ||
{ | ||
return is_numeric($number); | ||
} | ||
|
||
/** | ||
* @return int The new exponential to use | ||
*/ | ||
private function getNearestExp(int $search, string $unity): int | ||
{ | ||
$exps = array_keys(self::$unities[$unity]); | ||
$closest = array_pop($exps); | ||
|
||
foreach ($exps as $value) { | ||
if ((int) $value === $search || $search > $value) { | ||
return $value; | ||
} | ||
|
||
if (abs($search - $closest) > abs($value - $search)) { | ||
$closest = $value; | ||
} | ||
} | ||
|
||
return $closest; | ||
} | ||
|
||
private function getUnityPrefix(int $exp, string $unity): string | ||
{ | ||
return self::$unities[$unity][(string) $exp]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,38 +1,39 @@ | ||
# Twig-Extension-Number | ||
|
||
[](https://travis-ci.org/thePanz/Twig-Extension-Number) [](https://packagist.org/packages/pnz/twig-extension-number) [](https://packagist.org/packages/pnz/twig-extension-number) [](https://packagist.org/packages/pnz/twig-extension-number) [](https://packagist.org/packages/pnz/twig-extension-number) [](https://scrutinizer-ci.com/g/thePanz/Twig-Extension-Number/?branch=1.x) | ||
|
||
|
||
A Twig extension to handle number formatting. | ||
|
||
Included filters: | ||
|
||
- `format_bytes` : Format the given amount as bytes and display it in an as a human readable format. | ||
- `format_bytes` Formats the given amount as bytes and display it in an as a human-readable format. | ||
The filter supports 1000/1024 base counting and formatting | ||
|
||
- `format_grams` : Format the given amount as "grams" in an human readable format | ||
|
||
- `format_meters` : Format the given amount as "meters" in an human readable format | ||
|
||
- `format_grams` Formats the given amount as "grams" in a human-readable format | ||
- `format_meters` Formats the given amount as "meters" in a human-readable format | ||
|
||
## Examples | ||
|
||
Display the value 4000 grams in a human readable format (4.00 Kg): | ||
Display the value of 4000 grams in a human-readable format (4.00 Kg): | ||
``` | ||
{{ 4000 | format_grams }} | ||
``` | ||
|
||
[Decimals] Display the value 4000 grams in a human readable format with 3 decimals (4.000 Kg): | ||
``` | ||
{{ 4000 | format_grams(3) }} | ||
``` | ||
|
||
[UnityBias] Display the value 4000 milligrams as grams in a human readable format with 3 decimals (4.00 g): | ||
``` | ||
{{ 4000 | format_grams(3, 1E-3) }} | ||
The filter allows some customization of the output, given its signature `filter_grams(decimals, unityBias)`: | ||
* *Decimals*: Display the value of 4000 grams in a human-readable format with 3 decimals (4.000 Kg): | ||
``` | ||
{{ 4000 | format_grams(3) }} | ||
``` | ||
* *UnityBias*: Set the filter to handle the number as being expressed with a different bias then the standard unit (grams). | ||
To display the value of 4000 (expressed in milligrams, `1E-3`) as grams in a human-readable format with 3 decimals (4.00 g) | ||
use: | ||
``` | ||
{{ 4000 | format_grams(3, 1E-3) }} | ||
``` | ||
|
||
## Install | ||
|
||
In Symfony, tag `Pnz\TwigExtensionNumber\Number` with `twig.extension`, and the filter will be | ||
automatically registered. | ||
|
||
```yaml | ||
# file: config/services.yaml | ||
Pnz\TwigExtensionNumber\Number: | ||
tags: ['twig.extension'] | ||
``` | ||
|
||
|
||
## Todo | ||
- [] Implement I18n of number values | ||
- [] Implement `format_liters` filter |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
--TEST-- | ||
"format_bytes" filter | ||
--TEMPLATE-- | ||
{{ 0|format_bytes }} | ||
{{ 0|format_bytes(false) }} | ||
{{ 1|format_bytes }} | ||
{{ 1|format_bytes(false) }} | ||
{{ 1000|format_bytes }} | ||
{{ 1000|format_bytes(false) }} | ||
{{ 1024|format_bytes }} | ||
{{ 1024|format_bytes(false) }} | ||
{{ 2048|format_bytes }} | ||
{{ 2048|format_bytes(false) }} | ||
{{ 2048|format_bytes }} | ||
{{ 2048|format_bytes(false) }} | ||
{{ 2500|format_bytes }} | ||
{{ 2500|format_bytes(false) }} | ||
{{ 1000000|format_bytes }} | ||
{{ 1000000|format_bytes(false) }} | ||
{{ 1048576|format_bytes }} | ||
{{ 1048576|format_bytes(false) }} | ||
{{ 1000000000|format_bytes }} | ||
{{ 1000000000|format_bytes(false) }} | ||
{{ 1073741824|format_bytes }} | ||
{{ 1073741824|format_bytes(false) }} | ||
{{ 1099511627776|format_bytes }} | ||
{{ 1099511627776|format_bytes(false) }} | ||
{{ (1.12589990684263e+15)|format_bytes }} | ||
{{ (1.12589990684263e+15)|format_bytes(false) }} | ||
--DATA-- | ||
return [] | ||
--EXPECT-- | ||
0 B | ||
0 B | ||
1 B | ||
1 B | ||
1000 B | ||
1.0 KiB | ||
1.0 kB | ||
1.0 KiB | ||
2.0 kB | ||
2.0 KiB | ||
2.0 kB | ||
2.0 KiB | ||
2.4 kB | ||
2.5 KiB | ||
976.6 kB | ||
1.0 MiB | ||
1.0 MB | ||
1.0 MiB | ||
953.7 MB | ||
1.0 GiB | ||
1.0 GB | ||
1.1 GiB | ||
1.0 TB | ||
1.1 TiB | ||
1.0 PB | ||
1.1 PiB |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
--TEST-- | ||
"format_grams" filter | ||
--TEMPLATE-- | ||
{{ 1000000|format_grams }} | ||
{{ 100000|format_grams }} | ||
{{ 10000|format_grams }} | ||
{{ 1000|format_grams }} | ||
{{ 100|format_grams }} | ||
{{ 10|format_grams }} | ||
{{ 1|format_grams }} | ||
{{ 0|format_grams }} | ||
{{ '0.0'|format_grams() }} | ||
{{ (0.0)|format_grams(0) }} | ||
--DATA-- | ||
return []; | ||
--EXPECT-- | ||
1000.00 Kg | ||
100.00 Kg | ||
10.00 Kg | ||
1.00 Kg | ||
100.00 g | ||
10.00 g | ||
1.00 g | ||
0.00 g | ||
0.00 g | ||
0 g |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
namespace Pnz\TwigExtensionNumber\Tests; | ||
|
||
use Pnz\TwigExtensionNumber\Number; | ||
use Twig\Test\IntegrationTestCase; | ||
|
||
/** | ||
* @covers \Pnz\TwigExtensionNumber\Number | ||
* | ||
* @internal | ||
*/ | ||
final class IntegrationTest extends IntegrationTestCase | ||
{ | ||
public function getExtensions(): array | ||
{ | ||
return [ | ||
new Number(), | ||
]; | ||
} | ||
|
||
public function getFixturesDir(): string | ||
{ | ||
return __DIR__.'/Fixtures/'; | ||
} | ||
} |
Oops, something went wrong.