Migliorato supporto nativo delle conversione numeriche

Aggiunto sistema basilare per le conversioni numeriche nel caso non sia presente l'estensione intl di PHP.
This commit is contained in:
Thomas Zilio 2017-09-20 12:14:33 +02:00
parent dbbe2d0f5f
commit e654dba5e3
4 changed files with 129 additions and 17 deletions

View File

@ -27,4 +27,12 @@ $HTMLManagers = [];
// Lingua del progetto (per la traduzione e la conversione numerica)
$lang = 'it';
// Personalizzazione della formattazione di timestamp, date e orari
$formatter = [];
$formatter = [
'timestamp' => 'd/m/Y H:i',
'date' => 'd/m/Y',
'time' => 'H:i',
'number' => [
'decimals' => ',',
'thousands' => '.',
],
];

View File

@ -294,7 +294,8 @@ if (empty($creation) && (!file_exists('config.inc.php') || !$valid_config)) {
$extensions = [
'zip' => tr("Necessario per l'utilizzo delle funzioni di aggiornamento automatico e backup, oltre che per eventuali moduli aggiuntivi"),
'pdo_mysql' => tr('Necessario per la connessione al database'),
'openssl' => tr('Utile per la generazione di chiavi complesse (non obbligatorio)'),
'openssl' => tr('Utile per la generazione di chiavi complesse (facoltativo)'),
'intl' => tr('Utile per la gestione automatizzata della conversione numerica (facoltativo)'),
];
foreach ($extensions as $key => $value) {
$check = extension_loaded($key);

View File

@ -16,10 +16,15 @@ class Formatter
'timestamp' => 'Y-m-d H:i:s',
'date' => 'Y-m-d',
'time' => 'H:i:s',
'number' => [
'decimals' => '.',
'thousands' => '',
],
];
/** @var NumberFormatter Oggetto dedicato alla formattazione dei numeri */
/** @var NumberFormatter|array Oggetto dedicato alla formattazione dei numeri */
protected $numberFormatter;
protected $precision;
/** @var string Pattern per i timestamp */
protected $timestampPattern;
@ -28,9 +33,13 @@ class Formatter
/** @var string Pattern per gli orari */
protected $timePattern;
public function __construct($locale, $timestamp = null, $date = null, $time = null)
public function __construct($locale, $timestamp = null, $date = null, $time = null, $number = [])
{
$this->numberFormatter = new NumberFormatter($locale, NumberFormatter::DECIMAL);
if (class_exists('NumberFormatter')) {
$this->numberFormatter = new NumberFormatter($locale, NumberFormatter::DECIMAL);
} else {
$this->numberFormatter = $number;
}
$this->setTimestampPattern($timestamp);
@ -62,15 +71,23 @@ class Formatter
{
$value = trim($value);
if (!empty($decimals)) {
$original = $this->numberFormatter->getAttribute(NumberFormatter::FRACTION_DIGITS);
$this->numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $decimals);
}
if (is_object($this->numberFormatter)) {
if (!empty($decimals)) {
$original = $this->numberFormatter->getAttribute(NumberFormatter::FRACTION_DIGITS);
$this->numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $decimals);
}
$result = $this->numberFormatter->format($value);
$result = $this->numberFormatter->format($value);
if (!empty($decimals)) {
$this->numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $original);
if (!empty($decimals)) {
$this->numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $original);
}
} else {
$decimals = !empty($decimals) ? $decimals : $this->precision;
$number = number_format($value, $decimals, $this->getStandardFormats()['number']['decimals'], $this->getStandardFormats()['number']['thousands']);
$result = $this->customNumber($number, $this->getStandardFormats()['number'], $this->getNumberSeparators());
}
return is_numeric($value) ? $result : false;
@ -85,7 +102,17 @@ class Formatter
*/
public function parseNumber($value)
{
return ctype_digit(str_replace(array_values($this->getNumberSeparators()), '', $value)) ? $this->numberFormatter->parse($value) : false;
if (!ctype_digit(str_replace(array_values($this->getNumberSeparators()), '', $value))) {
return false;
}
if (is_object($this->numberFormatter)) {
$result = $this->numberFormatter->parse($value);
} else {
$result = $this->customNumber($value, $this->getNumberSeparators(), $this->getStandardFormats()['number']);
}
return $result;
}
/**
@ -123,7 +150,11 @@ class Formatter
*/
public function setPrecision($decimals)
{
$this->numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $decimals);
if (is_object($this->numberFormatter)) {
$this->numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, $decimals);
} else {
$this->precision = $decimals;
}
}
/**
@ -134,11 +165,79 @@ class Formatter
public function getNumberSeparators()
{
return [
'decimals' => $this->numberFormatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL),
'thousands' => $this->numberFormatter->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL),
'decimals' => is_object($this->numberFormatter) ? $this->numberFormatter->getSymbol(NumberFormatter::DECIMAL_SEPARATOR_SYMBOL) : $this->numberFormatter['decimals'],
'thousands' => is_object($this->numberFormatter) ? $this->numberFormatter->getSymbol(NumberFormatter::GROUPING_SEPARATOR_SYMBOL) : $this->numberFormatter['thousands'],
];
}
/**
* Converte l'elemento in una rappresentazione numerica.
*
* @param string $value
*
* @return array
*/
public function customNumber($value, $current, $format)
{
$value = trim($value);
if (strlen($value) == 0) {
return false;
}
$sign = null;
if ($value[0] == '+' || $value[0] == '-') {
$sign = $value[0];
$value = trim(substr($value, 1));
} elseif (!is_numeric($value[0])) {
return false;
}
if (strlen($value) == 0) {
return false;
}
$pieces = explode($current['decimals'], $value);
if (count($pieces) > 2) {
return false;
}
$integer = $pieces[0];
$decimal = (isset($pieces[1])) ? $pieces[1] : null;
if (!empty($current['thousands'])) {
$error = true;
if (floor(strlen($integer) / 4) == substr_count($integer, $current['thousands'])) {
$values = str_split(strrev($integer), 4);
foreach ($values as $key => $value) {
if (strlen($value) == 4 && ends_with($value, $current['thousands'])) {
$values[$key] = substr($value, 0, -1);
}
}
$integer = strrev(implode($values));
$error = substr_count($integer, $current['thousands']);
}
if (!empty($error)) {
return false;
}
}
if (!ctype_digit($integer) || (strlen($integer) != strlen((int) $integer)) || (isset($decimal) && !ctype_digit($decimal))) {
return false;
}
$result = $sign.number_format($integer, 0, '', $format['thousands']);
if (isset($decimal)) {
$result .= $format['decimals'].$decimal;
}
return $result;
}
// Gestione della conversione dei timestamp
/**

View File

@ -120,7 +120,11 @@ class Translator extends Util\Singleton
$this->locale,
empty($formatter['timestamp']) ? 'd/m/Y H:i' : $formatter['timestamp'],
empty($formatter['date']) ? 'd/m/Y' : $formatter['date'],
empty($formatter['time']) ? 'H:i' : $formatter['time']
empty($formatter['time']) ? 'H:i' : $formatter['time'],
empty($formatter['number']) ? [
'decimals' => ',',
'thousands' => '.',
] : $formatter['number']
);
self::$formatter->setPrecision(Settings::get('Cifre decimali per importi'));