CoolCMS API

ImportRules
in package

FinalYes

Rules shared by the validator (dry-run) and the executor (real write): the single place for column limits, nullable/not-null field lists and scalar interpretation. If each side kept its own copy, the report would promise something different from what the executor does.

Pure static helpers without I/O; DB matching is done by ImportMatcher, per-item verdicts by ImportValidator.

Table of Contents

Constants

CODE_MAX_LENGTH  : int = 20
DEFAULT_UNIT_CODE  : string = 'ks'
Default unit of a new set when the file has no `<unit>`.
EAN_MAX_LENGTH  : int = 45
FROM_AMOUNT_DEFAULT  : string = '0'
Default tier when the file omits `fromAmount` (the base tier of the DB).
FROM_AMOUNT_MIN  : int = 0
Lowest quantity tier of the price series. Data contract: the base tier ("from 1 piece") is `from_amount = 0` (legacy, admin price list, {@see \App\UI\Api\Eshop\Models\Services\PriceResolver}), and the export writes it that way, so the import accepts zero (export to import round trip).
INT_UNSIGNED_MAX  : string = '4294967295'
Upper limit of int unsigned columns (`product_set_prices.from_amount`, `product_set_prices.points`).
MAX_IMAGES_PER_VARIANT  : int = 20
Maximum number of images per variant.
NAME_MAX_LENGTH  : int = 255
OPTION_PARAMETER_TYPES  : array<string|int, mixed> = [\App\Core\Base\Shared\Shared\Models\Entities\P...
Parameter types whose value is matched to an option: the `option` attribute or the element content as a name. Shared by validator and writer so that the rules are not duplicated.
PARAMETER_KIND_OPTION  : string = 'option'
PARAMETER_KIND_RANGE  : string = 'range'
PARAMETER_KIND_TEXT  : string = 'text'
PRICE_MAX_EXCLUSIVE  : string = '100000000000'
Upper limit of a money value. `product_set_prices.price` is decimal(15,4), so 11 digits before the decimal point; above that the DB would fail the write or silently clip the value (same reason as {@see WEIGHT_MAX_EXCLUSIVE}). Compared with bcmath on a string, not a float: `(float) '1e1000'` is `INF` and any comparison with it lies.
PRICE_SCALE  : int = 4
Precision of the money columns of the price series (`product_set_prices.price`/`original_price` decimal(15,4)) and of the Store stock columns (decimal(10,3)). `PRICE_WORK_SCALE` is the working precision of the VAT calculation so that nothing is rounded twice.
PRICE_WORK_SCALE  : int = 8
PRODUCER_MAX_LENGTH  : int = 45
PRODUCT_NOT_NULL_FIELDS  : array<string|int, mixed> = ['activated']
RANGE_PARAMETER_TYPES  : array<string|int, mixed> = [\App\Core\Base\Shared\Shared\Models\Entities\P...
STOCK_MAX_EXCLUSIVE  : string = '10000000'
Same limit for the stock axis. Store columns are decimal(10,3), so 7 digits before the decimal point; it applies to the absolute value because `mode="add"` may subtract.
STOCK_SCALE  : int = 3
VARIANT_NOT_NULL_FIELDS  : array<string|int, mixed> = ['code', 'unit', 'weight', 'warranty', 'freeDel...
Not-null variant columns; an empty tag is a hard error. `description` and `shortDescription` are deliberately absent: they are not null, but an empty string is a legitimate value for them (clearing a description makes sense).
VARIANT_NULLABLE_FIELDS  : array<string|int, mixed> = ['ean', 'isbn', 'publishTime', 'unpublishTime',...
Variant fields that can be cleared by an empty tag (nullable columns and nullable FKs).
WARRANTY_MAX  : int = 255
WEIGHT_MAX_EXCLUSIVE  : string = '10000000'
Number ranges. A value out of range would fail the write with a generic database error (strict `sql_mode`) or be silently clipped to the column limit (non-strict); the range is therefore a hard item error: - `weight` decimal(10,3): 0 <= x < 10^7, - `warranty` tinyint(3) unsigned: 0-255 months.
WEIGHT_SCALE  : int = 3
EXPAND_MAX_LENGTH  : int = 512
Length cap of an expanded exponential notation. `1e1000000000` would expand to a gigabyte string; above the cap the value is not expanded and stays in exponential form, which {@see isPlainDecimal()} rejects as invalid input.

Methods

classifyParameterKind()  : string
The single place that decides which data shape a parameter of a given type expects: the validator uses it for the type check (hard error on mismatch), the writer to build the `ProductSetParameterRel` value. `$hasOptions` decides when `$type` alone is not enough (the entity can have options without being listed in {@see OPTION_PARAMETER_TYPES}, e.g.
isBoolean()  : bool
isDateTime()  : bool
isDecimal()  : bool
Returns whether the value has a shape the writer can calculate with. A non-numeric value is a hard error; without this test `(float)` of "abc" would become a silent zero.
isFromAmountValid()  : bool
Quantity tier `fromAmount`: an integer >= 0 (int unsigned column; the base tier "from 1 piece" is `0` in the DB). Anything else is a hard item error, otherwise the price would be written to a different axis than the file meant. The export writes `fromAmount="0"`, so zero must be accepted for the export to import round trip.
isNegativeAmount()  : bool
Exact sign of a numeric value, shared by the price and stock axes. `(float)` and `bccomp()` with a scale are not enough: both lose non-zero digits below the scale, so `-0.00009` would come out as zero and the writer would round it half-up to a negative value.
isPlainDecimal()  : bool
Plain decimal notation: the form that bcmath and a decimal column both accept. Stricter than `is_numeric()`: no exponents, no hex, no spaces.
isPointsValid()  : bool
`points` is an integer >= 0 (int unsigned column).
isPriceAmountValid()  : bool
Returns whether `<amount>`/`<originalAmount>`/... is a number >= 0; a negative price is nonsense.
isStockAmountInRange()  : bool
Returns whether a quantity fits decimal(10,3) after rounding. It is measured on the value the writer actually stores ({@see toStockDecimal()}), not on the raw input, otherwise the same gap as with prices remains between the gate and the rounding. The range applies to the absolute value; the sign is handled by {@see isNegativeAmount()} according to the mode.
isStockDecimalInRange()  : bool
Same limit on a value that is already in the column shape. The writer needs it separately: with `mode="add"` the DB gets `bcadd(current stock, delta)`, not the input, so the input gate guarantees nothing (`9000000 + 5000000` passed validation and was silently clipped).
isWarrantyInRange()  : bool
`warranty` is an integer 0-{@see WARRANTY_MAX} (tinyint unsigned).
isWeightInRange()  : bool
`weight` is a number in the decimal(10,3) range: 0 <= x < 10^7.
normalizeDecimal()  : string
Decimal point canonical, comma tolerated. Also expands exponential notation (`1e2`, `1.5E+3`) to a plain decimal. Spreadsheets emit it into exports and `is_numeric()` accepts it, but bcmath does not: `bcdiv('1e2', ...)` ends with `ValueError: ... is not well-formed` inside {@see priceWithoutVat()}/{@see toStockDecimal()}.
normalizeFromAmount()  : int
Tier axis for writing and comparing. Both `0` and `1` mean "from 1 piece" (the resolver takes the highest `from_amount <= quantity`) and the DB keeps the base tier as `0`, so `fromAmount="1"` must target the same axis; otherwise a parallel axis `1` would appear next to the base tier and silently override it on the front end. Call only with a value that passed {@see isFromAmountValid()}.
parseBoolean()  : bool|null
`1`/`0` canonical, `true`/`false` tolerated; anything else yields `null` (the caller has already validated).
parseDateTime()  : DateTime|null
Parses `Y-m-d H:i:s` or `Y-m-d`. Returns a `DateTime` in the application zone (Europe/Prague): `publish_time`/`unpublish_time` are stored through Doctrine `datetime` exactly as the admin form (`ProductSetEditComponent`) writes them, so after an import the admin sees exactly the value from the file.
priceWithoutVat()  : string
Price without VAT from a price with VAT and a rate in percent (`base = withVat / (1 + p/100)`), rounded half-up to {@see PRICE_SCALE} decimals, the column precision.
resolveAction()  : string
A per-item `action` overrides the product card `action`, which overrides the global job `mode`.
toPriceDecimal()  : numeric-string
Converts a money value to the shape of the `price`/`original_price` decimal(15,4) columns. It has the same shape as {@see \App\UI\Api\Eshop\Models\Managers\ProductSetManager::savePriceSnapshot()} writes (`number_format(..., 4)`), so the check "same price means no new snapshot" compares like with like.
toStockDecimal()  : numeric-string
Converts a stock quantity to the shape of the Store decimal(10,3) columns (`stock_levels.quantity`, `stock_movements.quantity`, `stock_items.min_quantity`).
toWeightDecimal()  : numeric-string
Converts a weight to the shape of `product_sets.weight` decimal(10,3).
expandScientific()  : string
Expands exponential notation to a plain decimal, exactly and without floats, by shifting the decimal point in the digit string: `1e2` to `100`, `1.5e-3` to `0.0015`.
isNegativeDecimal()  : bool
Exact test of a negative decimal string, without bcmath scale (which would drop non-zero digits below the scale) and without floats. Negative means a minus sign plus at least one non-zero digit; `-0`/`-0.0000` is zero.
isUnsignedIntInRange()  : bool
Integer in the range of an int unsigned column. Compared as a string (bcmath), not with `(int)`: on 64 bits `99999999999999999999999` does not fit an int and the cast yields a value that passes the gate.
roundHalfUp()  : numeric-string
bcmath half-up rounding (`bcadd`/`bcdiv` truncate on their own), same approach as `OrderCalculator::round3()`.

Constants

DEFAULT_UNIT_CODE

Default unit of a new set when the file has no `<unit>`.

public string DEFAULT_UNIT_CODE = 'ks'

FROM_AMOUNT_DEFAULT

Default tier when the file omits `fromAmount` (the base tier of the DB).

public string FROM_AMOUNT_DEFAULT = '0'

FROM_AMOUNT_MIN

Lowest quantity tier of the price series. Data contract: the base tier ("from 1 piece") is `from_amount = 0` (legacy, admin price list, {@see \App\UI\Api\Eshop\Models\Services\PriceResolver}), and the export writes it that way, so the import accepts zero (export to import round trip).

public int FROM_AMOUNT_MIN = 0

INT_UNSIGNED_MAX

Upper limit of int unsigned columns (`product_set_prices.from_amount`, `product_set_prices.points`).

public string INT_UNSIGNED_MAX = '4294967295'

IMPORTANT: without it 4294967296 passed; a strict sql_mode fails the write, a non-strict one silently clips it to 4294967295. For from_amount that is worse than losing a number: it is the axis of the price series, so two quantity tiers collapse into one after clipping and idempotence breaks (ImportProductWriter::loadCurrentPrices() reads the clipped value while the key uses the unclipped one, so a match never happens and every run creates a new point).

MAX_IMAGES_PER_VARIANT

Maximum number of images per variant.

public int MAX_IMAGES_PER_VARIANT = 20

OPTION_PARAMETER_TYPES

Parameter types whose value is matched to an option: the `option` attribute or the element content as a name. Shared by validator and writer so that the rules are not duplicated.

public array<string|int, mixed> OPTION_PARAMETER_TYPES = [\App\Core\Base\Shared\Shared\Models\Entities\ParameterType::SELECT, \App\Core\Base\Shared\Shared\Models\Entities\ParameterType::MULTISELECT, \App\Core\Base\Shared\Shared\Models\Entities\ParameterType::RADIO, \App\Core\Base\Shared\Shared\Models\Entities\ParameterType::CHECKBOXLIST, \App\Core\Base\Shared\Shared\Models\Entities\ParameterType::SELECT_CURRENCY, \App\Core\Base\Shared\Shared\Models\Entities\ParameterType::SELECT_REGION]

PARAMETER_KIND_OPTION

public string PARAMETER_KIND_OPTION = 'option'

PARAMETER_KIND_RANGE

public string PARAMETER_KIND_RANGE = 'range'

PARAMETER_KIND_TEXT

public string PARAMETER_KIND_TEXT = 'text'

PRICE_MAX_EXCLUSIVE

Upper limit of a money value. `product_set_prices.price` is decimal(15,4), so 11 digits before the decimal point; above that the DB would fail the write or silently clip the value (same reason as {@see WEIGHT_MAX_EXCLUSIVE}). Compared with bcmath on a string, not a float: `(float) '1e1000'` is `INF` and any comparison with it lies.

public string PRICE_MAX_EXCLUSIVE = '100000000000'

PRICE_SCALE

Precision of the money columns of the price series (`product_set_prices.price`/`original_price` decimal(15,4)) and of the Store stock columns (decimal(10,3)). `PRICE_WORK_SCALE` is the working precision of the VAT calculation so that nothing is rounded twice.

public int PRICE_SCALE = 4

PRODUCER_MAX_LENGTH

public int PRODUCER_MAX_LENGTH = 45

PRODUCT_NOT_NULL_FIELDS

public array<string|int, mixed> PRODUCT_NOT_NULL_FIELDS = ['activated']

not-null product card fields

RANGE_PARAMETER_TYPES

public array<string|int, mixed> RANGE_PARAMETER_TYPES = [\App\Core\Base\Shared\Shared\Models\Entities\ParameterType::RANGE, \App\Core\Base\Shared\Shared\Models\Entities\ParameterType::RANGE_SLIDER, \App\Core\Base\Shared\Shared\Models\Entities\ParameterType::LIMITRANGE_SLIDER]

parameter types with a value + value2 range

STOCK_MAX_EXCLUSIVE

Same limit for the stock axis. Store columns are decimal(10,3), so 7 digits before the decimal point; it applies to the absolute value because `mode="add"` may subtract.

public string STOCK_MAX_EXCLUSIVE = '10000000'

IMPORTANT: without this gate 1e1000 passed as a number (is_numeric() accepts an unexpanded exponent) and the writer turned it into 0.000, so mode="set" silently zeroed the stock instead of rejecting the item.

VARIANT_NOT_NULL_FIELDS

Not-null variant columns; an empty tag is a hard error. `description` and `shortDescription` are deliberately absent: they are not null, but an empty string is a legitimate value for them (clearing a description makes sense).

public array<string|int, mixed> VARIANT_NOT_NULL_FIELDS = ['code', 'unit', 'weight', 'warranty', 'freeDelivery', 'freePayment', 'activated']

VARIANT_NULLABLE_FIELDS

Variant fields that can be cleared by an empty tag (nullable columns and nullable FKs).

public array<string|int, mixed> VARIANT_NULLABLE_FIELDS = ['ean', 'isbn', 'publishTime', 'unpublishTime', 'vat', 'state']

WEIGHT_MAX_EXCLUSIVE

Number ranges. A value out of range would fail the write with a generic database error (strict `sql_mode`) or be silently clipped to the column limit (non-strict); the range is therefore a hard item error: - `weight` decimal(10,3): 0 <= x < 10^7, - `warranty` tinyint(3) unsigned: 0-255 months.

public string WEIGHT_MAX_EXCLUSIVE = '10000000'

IMPORTANT: the limit is a string compared with bcmath, never a float. (float) '1e1000' is INF and number_format() turned it into the text inf; 9999999.9995 passed a float gate and was rounded to 10000000.000, one digit more than the column holds (same reason for PRICE_MAX_EXCLUSIVE and STOCK_MAX_EXCLUSIVE).

EXPAND_MAX_LENGTH

Length cap of an expanded exponential notation. `1e1000000000` would expand to a gigabyte string; above the cap the value is not expanded and stays in exponential form, which {@see isPlainDecimal()} rejects as invalid input.

private int EXPAND_MAX_LENGTH = 512

Methods

classifyParameterKind()

The single place that decides which data shape a parameter of a given type expects: the validator uses it for the type check (hard error on mismatch), the writer to build the `ProductSetParameterRel` value. `$hasOptions` decides when `$type` alone is not enough (the entity can have options without being listed in {@see OPTION_PARAMETER_TYPES}, e.g.

public static classifyParameterKind(int|null $type, bool $hasOptions) : string

type === null on old data).

Parameters
$type : int|null
$hasOptions : bool
Return values
string

isBoolean()

public static isBoolean(string $value) : bool
Parameters
$value : string
Return values
bool

isDateTime()

public static isDateTime(string $value) : bool
Parameters
$value : string
Return values
bool

isDecimal()

Returns whether the value has a shape the writer can calculate with. A non-numeric value is a hard error; without this test `(float)` of "abc" would become a silent zero.

public static isDecimal(string $value) : bool

IMPORTANT: is_numeric() is the wrong test here, as for prices: the unexpanded exponent 1e1000 is a valid number for it, but toStockDecimal() turns it into a safe 0.000. The gate therefore measures the same shape the conversion handles: isPlainDecimal() on the expanded value.

Parameters
$value : string
Return values
bool

isFromAmountValid()

Quantity tier `fromAmount`: an integer >= 0 (int unsigned column; the base tier "from 1 piece" is `0` in the DB). Anything else is a hard item error, otherwise the price would be written to a different axis than the file meant. The export writes `fromAmount="0"`, so zero must be accepted for the export to import round trip.

public static isFromAmountValid(string $value) : bool
Parameters
$value : string
Return values
bool

isNegativeAmount()

Exact sign of a numeric value, shared by the price and stock axes. `(float)` and `bccomp()` with a scale are not enough: both lose non-zero digits below the scale, so `-0.00009` would come out as zero and the writer would round it half-up to a negative value.

public static isNegativeAmount(string $value) : bool
Parameters
$value : string
Return values
bool

isPlainDecimal()

Plain decimal notation: the form that bcmath and a decimal column both accept. Stricter than `is_numeric()`: no exponents, no hex, no spaces.

public static isPlainDecimal(string $normalized) : bool

The assert narrows the type for callers: whatever passes is also a numeric-string, so the bcmath calls below get the type they require.

Parameters
$normalized : string
Tags
phpstan-assert-if-true

numeric-string $normalized

Return values
bool

isPointsValid()

`points` is an integer >= 0 (int unsigned column).

public static isPointsValid(string $value) : bool

IMPORTANT: the upper limit INT_UNSIGNED_MAX is required: 99999999999999999999999 passed and the writer turned it into nonsense with an (int) cast, which the DB then silently clipped.

Parameters
$value : string
Return values
bool

isPriceAmountValid()

Returns whether `<amount>`/`<originalAmount>`/... is a number >= 0; a negative price is nonsense.

public static isPriceAmountValid(string $value) : bool

Both the shape and the range are checked. The validation accepts exactly what the writer can calculate and a decimal(15,4) column can hold: an expandable exponent passes as a plain number, an unexpandable or overflowing one is a hard item error (same policy as for weight, see WEIGHT_MAX_EXCLUSIVE). Without it 1e2 passed and the writer crashed on bcdiv(), and 1e1000 produced the string inf for a decimal column.

Parameters
$value : string
Return values
bool

isStockAmountInRange()

Returns whether a quantity fits decimal(10,3) after rounding. It is measured on the value the writer actually stores ({@see toStockDecimal()}), not on the raw input, otherwise the same gap as with prices remains between the gate and the rounding. The range applies to the absolute value; the sign is handled by {@see isNegativeAmount()} according to the mode.

public static isStockAmountInRange(string $value) : bool
Parameters
$value : string
Return values
bool

isStockDecimalInRange()

Same limit on a value that is already in the column shape. The writer needs it separately: with `mode="add"` the DB gets `bcadd(current stock, delta)`, not the input, so the input gate guarantees nothing (`9000000 + 5000000` passed validation and was silently clipped).

public static isStockDecimalInRange(numeric-string $stored) : bool
Parameters
$stored : numeric-string

value after toStockDecimal() or a bcmath sum

Return values
bool

isWarrantyInRange()

`warranty` is an integer 0-{@see WARRANTY_MAX} (tinyint unsigned).

public static isWarrantyInRange(string $value) : bool
Parameters
$value : string
Return values
bool

isWeightInRange()

`weight` is a number in the decimal(10,3) range: 0 <= x < 10^7.

public static isWeightInRange(string $value) : bool

The same three gates as for prices and stock, with bcmath instead of float: the shape (isDecimal(), not is_numeric(), which accepts the unexpanded exponent 1e1000), the sign exactly (isNegativeAmount(); (float) loses digits below the scale) and the range measured on the rounded value, i.e. on what actually goes into the column.

Parameters
$value : string
Return values
bool

normalizeDecimal()

Decimal point canonical, comma tolerated. Also expands exponential notation (`1e2`, `1.5E+3`) to a plain decimal. Spreadsheets emit it into exports and `is_numeric()` accepts it, but bcmath does not: `bcdiv('1e2', ...)` ends with `ValueError: ... is not well-formed` inside {@see priceWithoutVat()}/{@see toStockDecimal()}.

public static normalizeDecimal(string $value) : string

IMPORTANT: the expansion works on the string (shifting the decimal point), never via (float): for large exponents a float is INF and number_format() then prints inf.

A value that cannot be expanded (non-numeric, or exponent above EXPAND_MAX_LENGTH) is returned unchanged; is_numeric() and isPlainDecimal() filter it out themselves.

Parameters
$value : string
Return values
string

normalizeFromAmount()

Tier axis for writing and comparing. Both `0` and `1` mean "from 1 piece" (the resolver takes the highest `from_amount <= quantity`) and the DB keeps the base tier as `0`, so `fromAmount="1"` must target the same axis; otherwise a parallel axis `1` would appear next to the base tier and silently override it on the front end. Call only with a value that passed {@see isFromAmountValid()}.

public static normalizeFromAmount(string $value) : int
Parameters
$value : string
Return values
int

parseBoolean()

`1`/`0` canonical, `true`/`false` tolerated; anything else yields `null` (the caller has already validated).

public static parseBoolean(string $value) : bool|null
Parameters
$value : string
Return values
bool|null

parseDateTime()

Parses `Y-m-d H:i:s` or `Y-m-d`. Returns a `DateTime` in the application zone (Europe/Prague): `publish_time`/`unpublish_time` are stored through Doctrine `datetime` exactly as the admin form (`ProductSetEditComponent`) writes them, so after an import the admin sees exactly the value from the file.

public static parseDateTime(string $value) : DateTime|null
Parameters
$value : string
Return values
DateTime|null

priceWithoutVat()

Price without VAT from a price with VAT and a rate in percent (`base = withVat / (1 + p/100)`), rounded half-up to {@see PRICE_SCALE} decimals, the column precision.

public static priceWithoutVat(string $withVat, string|null $vatPercents) : string

Own bcmath calculation instead of OrderCalculator::withoutVat() on purpose: the order calculator works with 3 decimals (document rows are decimal(10,3)) while the price series has 4, so sharing it would cut one decimal off the price on every import.

Parameters
$withVat : string
$vatPercents : string|null
Return values
string

toPriceDecimal()

Converts a money value to the shape of the `price`/`original_price` decimal(15,4) columns. It has the same shape as {@see \App\UI\Api\Eshop\Models\Managers\ProductSetManager::savePriceSnapshot()} writes (`number_format(..., 4)`), so the check "same price means no new snapshot" compares like with like.

public static toPriceDecimal(string $value) : numeric-string
Parameters
$value : string
Return values
numeric-string

toStockDecimal()

Converts a stock quantity to the shape of the Store decimal(10,3) columns (`stock_levels.quantity`, `stock_movements.quantity`, `stock_items.min_quantity`).

public static toStockDecimal(string $value) : numeric-string
Parameters
$value : string
Return values
numeric-string

toWeightDecimal()

Converts a weight to the shape of `product_sets.weight` decimal(10,3).

public static toWeightDecimal(string $value) : numeric-string

IMPORTANT: the writer must use this conversion, not its own number_format((float) ..., 3): a float overflows to INF for large values and the string inf was written into the column.

Parameters
$value : string
Return values
numeric-string

expandScientific()

Expands exponential notation to a plain decimal, exactly and without floats, by shifting the decimal point in the digit string: `1e2` to `100`, `1.5e-3` to `0.0015`.

private static expandScientific(string $value) : string
Parameters
$value : string
Return values
string

isNegativeDecimal()

Exact test of a negative decimal string, without bcmath scale (which would drop non-zero digits below the scale) and without floats. Negative means a minus sign plus at least one non-zero digit; `-0`/`-0.0000` is zero.

private static isNegativeDecimal(string $normalized) : bool
Parameters
$normalized : string

value after normalizeDecimal(); a non-numeric shape counts as non-negative

Return values
bool

isUnsignedIntInRange()

Integer in the range of an int unsigned column. Compared as a string (bcmath), not with `(int)`: on 64 bits `99999999999999999999999` does not fit an int and the cast yields a value that passes the gate.

private static isUnsignedIntInRange(string $value, int $min) : bool
Parameters
$value : string
$min : int
Return values
bool

roundHalfUp()

bcmath half-up rounding (`bcadd`/`bcdiv` truncate on their own), same approach as `OrderCalculator::round3()`.

private static roundHalfUp(numeric-string $value, int $scale) : numeric-string
Parameters
$value : numeric-string
$scale : int
Return values
numeric-string
On this page

Search results