ColumnLimits
in package
Single source of truth for column limits used by validation gates.
The schema declares length/precision/scale on many columns, but nothing enforces
them: the hydrator ignores them, DecimalType::convertToDatabaseValue() is a passthrough
and the database outcome depends on sql_mode: strict fails the whole save with a generic
database error, non-strict throws no exception and silently truncates ('abc' becomes
0.000, 25 characters into varchar(20) are cut). Every write path therefore has to guard the limits itself, and when
each path copied them by hand, a gate sooner or later measured a different number than the
column holds.
The limits are read by reflection from the #[ORM\Column] attribute of the entity, the
same place Doctrine reads them from. After a schema change (migration + entity) the gates
follow on their own. Works with promoted constructor properties too, which most entities use.
Usage in a form:
$form->addText('email', …)
->addRule($form::MAX_LENGTH, $t('email.rules.long'), ColumnLimits::length(User::class, 'email'));
Table of Contents
Properties
- $cache : array<string, array<string, array{length: int|null, precision: int|null, scale: int|null, type: string|null, unsigned: bool}>>
Methods
- decimalMaxExclusive() : numeric-string
- Returns the upper bound of a decimal column as an exclusive limit in decimal notation (`10^(precision-scale)`).
- decimalPrecision() : int
- Returns the total number of digits of a decimal column (`precision`).
- describe() : array{length: int|null, precision: int|null, scale: int|null, type: string|null, unsigned: bool}|null
- Describes the column of a property, or returns null when the entity has no such property or it is not a `#[ORM\Column]` (a relation, a transient field). For a form gate that maps controls to columns by name ({@see \App\Core\Forms\ColumnGate::guard()}), where "not a column" is a normal answer, not a typo.
- integerRange() : array{0: int, 1: int}
- Returns the inclusive range of an integer column (`smallint`/`integer`/`bigint`, signed or `unsigned`), the bounds of the MySQL type.
- length() : int
- Returns the maximum number of characters of a column (`length` from `#[ORM\Column]`).
- scale() : int
- Returns the number of decimal places of a column (`scale`).
- read() : array{length: int|null, precision: int|null, scale: int|null, type: string|null, unsigned: bool}
Properties
$cache
private
static array<string, array<string, array{length: int|null, precision: int|null, scale: int|null, type: string|null, unsigned: bool}>>
$cache
= []
Methods
decimalMaxExclusive()
Returns the upper bound of a decimal column as an exclusive limit in decimal notation (`10^(precision-scale)`).
public
static decimalMaxExclusive(class-string $entity, string $property) : numeric-string
Returns a string on purpose: (float) overflows to INF for large values and any
comparison with it lies. Compare with bcmath over the value after rounding, that is,
over what is actually written, not over the raw input.
Parameters
- $entity : class-string
- $property : string
Return values
numeric-stringdecimalPrecision()
Returns the total number of digits of a decimal column (`precision`).
public
static decimalPrecision(class-string $entity, string $property) : int
Parameters
- $entity : class-string
- $property : string
Return values
intdescribe()
Describes the column of a property, or returns null when the entity has no such property or it is not a `#[ORM\Column]` (a relation, a transient field). For a form gate that maps controls to columns by name ({@see \App\Core\Forms\ColumnGate::guard()}), where "not a column" is a normal answer, not a typo.
public
static describe(class-string $entity, string $property) : array{length: int|null, precision: int|null, scale: int|null, type: string|null, unsigned: bool}|null
The type falls back to the PHP type of the property when the attribute omits it (Doctrine infers
it the same way); a string without length is 255, the Doctrine default.
Parameters
- $entity : class-string
- $property : string
Return values
array{length: int|null, precision: int|null, scale: int|null, type: string|null, unsigned: bool}|nullintegerRange()
Returns the inclusive range of an integer column (`smallint`/`integer`/`bigint`, signed or `unsigned`), the bounds of the MySQL type.
public
static integerRange(class-string $entity, string $property) : array{0: int, 1: int}
A form integer field without it let 99999999999 through Form::INTEGER; strict sql_mode then
failed the whole save with a generic database error, non-strict stored the type maximum.
NOTE: bigint is capped at PHP_INT_MAX, the largest value a form integer can carry anyway.
Parameters
- $entity : class-string
- $property : string
Return values
array{0: int, 1: int}length()
Returns the maximum number of characters of a column (`length` from `#[ORM\Column]`).
public
static length(class-string $entity, string $property) : int
Parameters
- $entity : class-string
- $property : string
Tags
Return values
intscale()
Returns the number of decimal places of a column (`scale`).
public
static scale(class-string $entity, string $property) : int
Parameters
- $entity : class-string
- $property : string
Return values
intread()
private
static read(class-string $entity, string $property) : array{length: int|null, precision: int|null, scale: int|null, type: string|null, unsigned: bool}
Parameters
- $entity : class-string
- $property : string