From e53b2b249f40e7803c1daa20b1db7c5fa5e3c04f Mon Sep 17 00:00:00 2001 From: Guy Sartorelli Date: Fri, 31 Jan 2025 14:06:23 +1300 Subject: [PATCH] API Provide minimum and maximum comparison values for numeric DBFields This will be used with handling WithinRangeFilter in searchable fields so that if only one of the two ends of a range is filled in, the other can be automatically populated. --- .../FieldValidation/BigIntFieldValidator.php | 20 +++-------------- .../FieldValidation/IntFieldValidator.php | 17 +++----------- src/ORM/FieldType/DBBigInt.php | 15 +++++++++++++ src/ORM/FieldType/DBDate.php | 10 +++++++++ src/ORM/FieldType/DBDatetime.php | 10 +++++++++ src/ORM/FieldType/DBDecimal.php | 10 +++++++++ src/ORM/FieldType/DBField.php | 16 ++++++++++++++ src/ORM/FieldType/DBFloat.php | 10 +++++++++ src/ORM/FieldType/DBForeignKey.php | 8 +------ src/ORM/FieldType/DBInt.php | 22 +++++++++++++++++++ src/ORM/FieldType/DBPercentage.php | 4 ++-- src/ORM/FieldType/DBTime.php | 10 +++++++++ src/ORM/FieldType/DBYear.php | 8 +++---- 13 files changed, 116 insertions(+), 44 deletions(-) diff --git a/src/Core/Validation/FieldValidation/BigIntFieldValidator.php b/src/Core/Validation/FieldValidation/BigIntFieldValidator.php index ee9d8c5b12b..4e48ef15b6a 100644 --- a/src/Core/Validation/FieldValidation/BigIntFieldValidator.php +++ b/src/Core/Validation/FieldValidation/BigIntFieldValidator.php @@ -4,6 +4,7 @@ use RunTimeException; use SilverStripe\Core\Validation\ValidationResult; +use SilverStripe\ORM\FieldType\DBBigInt; /** * A field validator for 64-bit integers @@ -11,21 +12,6 @@ */ class BigIntFieldValidator extends IntFieldValidator { - /** - * The minimum value for a signed 64-bit integer. - * Defined as string instead of int otherwise will end up as a float - * on 64-bit systems - * - * When this is cast to an int in IntFieldValidator::__construct() - * it will be properly cast to an int - */ - protected const MIN_INT = '-9223372036854775808'; - - /** - * The maximum value for a signed 64-bit integer. - */ - protected const MAX_INT = '9223372036854775807'; - public function __construct( string $name, mixed $value, @@ -51,10 +37,10 @@ protected function validateValue(): ValidationResult // int values that are too large or too small will be cast to float // on 64-bit systems and will fail the validation in IntFieldValidator if (is_string($this->value)) { - if (!is_null($this->minValue) && bccomp($this->value, static::MIN_INT) === -1) { + if (!is_null($this->minValue) && bccomp($this->value, DBBigInt::getMinValue()) === -1) { $result->addFieldError($this->name, $this->getTooSmallMessage()); } - if (!is_null($this->maxValue) && bccomp($this->value, static::MAX_INT) === 1) { + if (!is_null($this->maxValue) && bccomp($this->value, DBBigInt::getMaxValue()) === 1) { $result->addFieldError($this->name, $this->getTooLargeMessage()); } } diff --git a/src/Core/Validation/FieldValidation/IntFieldValidator.php b/src/Core/Validation/FieldValidation/IntFieldValidator.php index 28c677b036d..95701d03b7d 100644 --- a/src/Core/Validation/FieldValidation/IntFieldValidator.php +++ b/src/Core/Validation/FieldValidation/IntFieldValidator.php @@ -3,24 +3,13 @@ namespace SilverStripe\Core\Validation\FieldValidation; use SilverStripe\Core\Validation\ValidationResult; +use SilverStripe\ORM\FieldType\DBInt; /** * Validates that a value is a 32-bit signed integer */ class IntFieldValidator extends NumericNonStringFieldValidator { - /** - * The minimum value for a signed 32-bit integer. - * Defined as string instead of int because be cast to a float - * on 32-bit systems if defined as an int - */ - protected const MIN_INT = '-2147483648'; - - /** - * The maximum value for a signed 32-bit integer. - */ - protected const MAX_INT = '2147483647'; - public function __construct( string $name, mixed $value, @@ -28,10 +17,10 @@ public function __construct( ?int $maxValue = null ) { if (is_null($minValue)) { - $minValue = (int) static::MIN_INT; + $minValue = (int) DBInt::getMinValue(); } if (is_null($maxValue)) { - $maxValue = (int) static::MAX_INT; + $maxValue = (int) DBInt::getMaxValue(); } parent::__construct($name, $value, $minValue, $maxValue); } diff --git a/src/ORM/FieldType/DBBigInt.php b/src/ORM/FieldType/DBBigInt.php index af888e8f0bf..c40b80399a3 100644 --- a/src/ORM/FieldType/DBBigInt.php +++ b/src/ORM/FieldType/DBBigInt.php @@ -14,6 +14,21 @@ */ class DBBigInt extends DBInt { + /** + * The minimum value for a signed 64-bit integer. + * Defined as string instead of int otherwise will end up as a float + * on 64-bit systems + * + * When this is cast to an int in IntFieldValidator::__construct() + * it will be properly cast to an int + */ + protected const MIN_INT = '-9223372036854775808'; + + /** + * The maximum value for a signed 64-bit integer. + */ + protected const MAX_INT = '9223372036854775807'; + private static array $field_validators = [ // Remove parent validator and add BigIntValidator instead IntFieldValidator::class => null, diff --git a/src/ORM/FieldType/DBDate.php b/src/ORM/FieldType/DBDate.php index 39b84e7b01b..e8eb1a1000c 100644 --- a/src/ORM/FieldType/DBDate.php +++ b/src/ORM/FieldType/DBDate.php @@ -619,4 +619,14 @@ protected function explodeDateString($value) $parts[] = $matches['time']; return $parts; } + + public static function getMinValue(): string + { + return '0000-00-00'; + } + + public static function getMaxValue(): string + { + return '9999-12-31'; + } } diff --git a/src/ORM/FieldType/DBDatetime.php b/src/ORM/FieldType/DBDatetime.php index 0ba5a201b03..62f03e4913b 100644 --- a/src/ORM/FieldType/DBDatetime.php +++ b/src/ORM/FieldType/DBDatetime.php @@ -369,4 +369,14 @@ public function getISOFormat(): string { return DBDatetime::ISO_DATETIME; } + + public static function getMinValue(): string + { + return '0000-00-00 00:00:00'; + } + + public static function getMaxValue(): string + { + return '9999-12-31 23:59:59'; + } } diff --git a/src/ORM/FieldType/DBDecimal.php b/src/ORM/FieldType/DBDecimal.php index 0a32e0aeaef..a07049109a9 100644 --- a/src/ORM/FieldType/DBDecimal.php +++ b/src/ORM/FieldType/DBDecimal.php @@ -135,4 +135,14 @@ public function prepValueForDB(mixed $value): array|float|int|null return (float) $value; } + + public static function getMinValue(): float + { + return PHP_FLOAT_MIN; + } + + public static function getMaxValue(): float + { + return PHP_FLOAT_MAX; + } } diff --git a/src/ORM/FieldType/DBField.php b/src/ORM/FieldType/DBField.php index 29e326c41c0..64cec20fa97 100644 --- a/src/ORM/FieldType/DBField.php +++ b/src/ORM/FieldType/DBField.php @@ -571,4 +571,20 @@ public function scalarValueOnly(): bool { return true; } + + /** + * @return mixed The minimum value for comparisons with this field - or null if that's not determinable. + */ + public static function getMinValue(): mixed + { + return null; + } + + /** + * @return mixed The maximum value for comparisons with this field - or null if that's not determinable. + */ + public static function getMaxValue(): mixed + { + return null; + } } diff --git a/src/ORM/FieldType/DBFloat.php b/src/ORM/FieldType/DBFloat.php index 367957a4242..5764dff8528 100644 --- a/src/ORM/FieldType/DBFloat.php +++ b/src/ORM/FieldType/DBFloat.php @@ -89,4 +89,14 @@ public function prepValueForDB(mixed $value): array|float|int|null return $value; } + + public static function getMinValue(): float + { + return PHP_FLOAT_MIN; + } + + public static function getMaxValue(): float + { + return PHP_FLOAT_MAX; + } } diff --git a/src/ORM/FieldType/DBForeignKey.php b/src/ORM/FieldType/DBForeignKey.php index 6f30348688f..1d6dceb2b90 100644 --- a/src/ORM/FieldType/DBForeignKey.php +++ b/src/ORM/FieldType/DBForeignKey.php @@ -2,14 +2,8 @@ namespace SilverStripe\ORM\FieldType; -use SilverStripe\Assets\File; -use SilverStripe\Assets\Image; -use SilverStripe\Core\Injector\Injector; use SilverStripe\Core\Validation\FieldValidation\IntFieldValidator; -use SilverStripe\Forms\FileHandleField; use SilverStripe\Forms\FormField; -use SilverStripe\Forms\SearchableDropdownField; -use SilverStripe\ORM\DataList; use SilverStripe\ORM\DataObject; use SilverStripe\Model\ModelData; @@ -78,7 +72,7 @@ public function setValue(mixed $value, null|array|ModelData $record = null, bool return parent::setValue($value, $record, $markChanged); } - public function getMinValue(): int + public static function getMinValue(): int { return 0; } diff --git a/src/ORM/FieldType/DBInt.php b/src/ORM/FieldType/DBInt.php index 7426b56d6a0..505fa5fa0cc 100644 --- a/src/ORM/FieldType/DBInt.php +++ b/src/ORM/FieldType/DBInt.php @@ -16,6 +16,18 @@ */ class DBInt extends DBField { + /** + * The minimum value for a signed 32-bit integer. + * Defined as string instead of int because be cast to a float + * on 32-bit systems if defined as an int + */ + protected const MIN_INT = '-2147483648'; + + /** + * The maximum value for a signed 32-bit integer. + */ + protected const MAX_INT = '2147483647'; + private static array $field_validators = [ IntFieldValidator::class ]; @@ -102,4 +114,14 @@ public function prepValueForDB(mixed $value): array|int|null return (int)$value; } + + public static function getMinValue(): string|int + { + return static::MIN_INT; + } + + public static function getMaxValue(): string|int + { + return static::MAX_INT; + } } diff --git a/src/ORM/FieldType/DBPercentage.php b/src/ORM/FieldType/DBPercentage.php index 1cac39e38c1..b1e6b173775 100644 --- a/src/ORM/FieldType/DBPercentage.php +++ b/src/ORM/FieldType/DBPercentage.php @@ -39,12 +39,12 @@ public function __construct(?string $name = null, int $precision = 4) parent::__construct($name, $precision + 1, $precision); } - public function getMinValue(): float + public static function getMinValue(): float { return 0.0; } - public function getMaxValue(): float + public static function getMaxValue(): float { return 1.0; } diff --git a/src/ORM/FieldType/DBTime.php b/src/ORM/FieldType/DBTime.php index 5b44cc6fac3..476038f2083 100644 --- a/src/ORM/FieldType/DBTime.php +++ b/src/ORM/FieldType/DBTime.php @@ -181,4 +181,14 @@ public function getTimestamp(): int } return 0; } + + public static function getMinValue(): string + { + return '00:00:00'; + } + + public static function getMaxValue(): string + { + return '23:59:59'; + } } diff --git a/src/ORM/FieldType/DBYear.php b/src/ORM/FieldType/DBYear.php index 04c26c09dc4..0f05443b528 100644 --- a/src/ORM/FieldType/DBYear.php +++ b/src/ORM/FieldType/DBYear.php @@ -21,8 +21,8 @@ class DBYear extends DBField private static $field_validators = [ YearFieldValidator::class => [ - 'minValue' => 'getMinYear', - 'maxValue' => 'getMaxYear' + 'minValue' => 'getMinValue', + 'maxValue' => 'getMaxValue' ], ]; @@ -70,12 +70,12 @@ public function setValue(mixed $value, null|array|ModelData $record = null, bool return $this; } - public function getMinYear(): int + public static function getMinValue(): int { return DBYear::MIN_YEAR; } - public function getMaxYear(): int + public static function getMaxValue(): int { return DBYear::MAX_YEAR; }