Feature: #102217 - Configurable scale for TCA type "number"
See forge#102217
Description
Fields using TCA type number with format set to decimal
have always been limited to two decimal digits.
The only alternative was the usage of TCA type number with
format set to integer without any decimal digits.
The new TCA column configuration option scale makes this number
configurable:
'conversion_factor' => [
'label' => 'Conversion factor',
'config' => [
'type' => 'number',
'scale' => 6,
],
],
The option defaults to
0
, which is the previous behavior.
Values are limited to a scale between
0
and
30
,
the maximum supported by all database platforms.
If the database column is auto-created by TYPO3, the scale is part of the
column definition. For a scale equal to
0
, an integer column will be
generated.
For a scale greater than
0
, the following configuration applies:
The number of digits in front of the decimal point stays
at eight, the configured scale is added on top: The example above results in
decimal.
Impact
Decimal numbers can be stored and edited with more (or less) than two decimal digits. The scale is respected by the automatically created database column, by the DataHandler when persisting a value, and by the FormEngine when rendering and validating the field in the backend.
Decimal values are rounded on their digits and no longer through a float, so
values with a scale a float can not represent are kept exactly. The new API
method
Math does this rounding and is
available for extensions as well. It accepts digits with an optional sign,
decimal point and exponent, and throws an
\Invalid for
anything else: A value like
'1,5'
is rejected instead of being silently
read as
15
.
Lowering the scale of an existing field leaves stored values with more decimal
digits than the field now allows. Such a value is rounded to the scale when the
record is opened in the backend, and it is stored rounded with the next save of
that record. This matters because a value that is no multiple of the
step
attribute makes the browser refuse to submit the whole form, and it
does so without any visible message if the field sits on an inactive tab. MySQL
and PostgreSQL round the stored values themselves as soon as the column is
altered, while SQLite keeps decimal values as strings and therefore does not.
The rendered input field carries the scale as its
step
attribute, so a
scale of
6
results in
step="0.. Browsers evaluate that
attribute in double precision and can no longer do so below
1e-, so a
scale above
18
is rendered as
step="any"
instead. Such a field is
still rounded to its scale by the DataHandler and by the FormEngine, but the
browser no longer restricts the value, and the arrows of the input field step
by one.
As part of this, the internal web component
typo3- now reads the attribute
scale
instead of
precision
.
Migration
The TCA migration from format to scale is done like the following:
// Before
'<mycolumn_integer>' => [
'label' => 'Format integer',
'config' => [
'type' => 'number',
'format' => 'integer',
],
],
'<mycolumn_decimal>' => [
'label' => 'Format decimal',
'config' => [
'type' => 'number',
'format' => 'decimal',
],
],
// After
'<mycolumn_integer>' => [
'label' => 'Format integer',
'config' => [
'type' => 'number',
'scale' => 0,
],
],
'<mycolumn_decimal>' => [
'label' => 'Format decimal',
'config' => [
'type' => 'number',
'scale' => 2,
],
],
An automatic TCA migration is performed on the fly, migrating all occurrences
of format to scale.