Skip to content

Commit

Permalink
Prepare for branch 2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
thePanz committed Jan 20, 2021
1 parent 5f446c5 commit 3037eb6
Show file tree
Hide file tree
Showing 12 changed files with 550 additions and 496 deletions.
7 changes: 4 additions & 3 deletions .gitignore
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


13 changes: 0 additions & 13 deletions .travis.yml

This file was deleted.

152 changes: 152 additions & 0 deletions Number.php
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];
}
}
49 changes: 25 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
# Twig-Extension-Number

[![Travis Build Status](https://travis-ci.org/thePanz/Twig-Extension-Number.svg?branch=1.x)](https://travis-ci.org/thePanz/Twig-Extension-Number) [![Latest Stable Version](https://poser.pugx.org/pnz/twig-extension-number/v/stable.svg)](https://packagist.org/packages/pnz/twig-extension-number) [![Total Downloads](https://poser.pugx.org/pnz/twig-extension-number/downloads.svg)](https://packagist.org/packages/pnz/twig-extension-number) [![Latest Unstable Version](https://poser.pugx.org/pnz/twig-extension-number/v/unstable.svg)](https://packagist.org/packages/pnz/twig-extension-number) [![License](https://poser.pugx.org/pnz/twig-extension-number/license.svg)](https://packagist.org/packages/pnz/twig-extension-number) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/thePanz/Twig-Extension-Number/badges/quality-score.png?b=1.x)](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
58 changes: 58 additions & 0 deletions Tests/Fixtures/bytes.test
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
26 changes: 26 additions & 0 deletions Tests/Fixtures/grams.test
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
26 changes: 26 additions & 0 deletions Tests/IntegrationTest.php
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/';
}
}
Loading

0 comments on commit 3037eb6

Please sign in to comment.