mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Compare commits
2 Commits
a594c7f42f
...
226e278719
Author | SHA1 | Date | |
---|---|---|---|
|
226e278719 | ||
|
0d824ccaab |
@ -16,8 +16,8 @@ class DateFieldValidator extends FieldValidator
|
||||
protected function validateValue(): ValidationResult
|
||||
{
|
||||
$result = ValidationResult::create();
|
||||
// Allow empty values
|
||||
if (!$this->value) {
|
||||
// Allow empty strings
|
||||
if ($this->value === '') {
|
||||
return $result;
|
||||
}
|
||||
// Not using symfony/validator because it was allowing d-m-Y format strings
|
||||
|
@ -117,6 +117,31 @@ class TextField extends FormField implements TippableFieldInterface
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate this field
|
||||
*
|
||||
* @param Validator $validator
|
||||
* @return bool
|
||||
*/
|
||||
public function validate($validator)
|
||||
{
|
||||
$result = true;
|
||||
if (!is_null($this->maxLength) && mb_strlen($this->value ?? '') > $this->maxLength) {
|
||||
$name = strip_tags($this->Title() ? $this->Title() : $this->getName());
|
||||
$validator->validationError(
|
||||
$this->name,
|
||||
_t(
|
||||
'SilverStripe\\Forms\\TextField.VALIDATEMAXLENGTH',
|
||||
'The value for {name} must not exceed {maxLength} characters in length',
|
||||
['name' => $name, 'maxLength' => $this->maxLength]
|
||||
),
|
||||
"validation"
|
||||
);
|
||||
$result = false;
|
||||
}
|
||||
return $this->extendValidationResult($result, $validator);
|
||||
}
|
||||
|
||||
public function getSchemaValidation()
|
||||
{
|
||||
$rules = parent::getSchemaValidation();
|
||||
|
@ -31,6 +31,9 @@ class DBCurrency extends DBDecimal
|
||||
*/
|
||||
public function Nice(): string
|
||||
{
|
||||
if (!is_float($this->value)) {
|
||||
return '';
|
||||
}
|
||||
$val = static::config()->get('currency_symbol') . number_format(abs($this->value ?? 0.0) ?? 0.0, 2);
|
||||
if ($this->value < 0) {
|
||||
return "($val)";
|
||||
@ -44,6 +47,9 @@ class DBCurrency extends DBDecimal
|
||||
*/
|
||||
public function Whole(): string
|
||||
{
|
||||
if (!is_float($this->value)) {
|
||||
return '';
|
||||
}
|
||||
$val = static::config()->get('currency_symbol') . number_format(abs($this->value ?? 0.0) ?? 0.0, 0);
|
||||
if ($this->value < 0) {
|
||||
return "($val)";
|
||||
@ -53,15 +59,14 @@ class DBCurrency extends DBDecimal
|
||||
|
||||
public function setValue(mixed $value, null|array|ModelData $record = null, bool $markChanged = true): static
|
||||
{
|
||||
$matches = null;
|
||||
if (is_numeric($value)) {
|
||||
$this->value = $value;
|
||||
} elseif (preg_match('/-?\$?[0-9,]+(.[0-9]+)?([Ee][0-9]+)?/', $value ?? '', $matches)) {
|
||||
$this->value = str_replace(['$', ',', static::config()->get('currency_symbol')], '', $matches[0] ?? '');
|
||||
} else {
|
||||
$this->value = 0;
|
||||
parent::setValue($value, $record, $markChanged);
|
||||
if (is_string($this->value)) {
|
||||
$symbol = static::config()->get('currency_symbol');
|
||||
$val = str_replace(['$', ',', $symbol], '', $this->value);
|
||||
if (is_numeric($val)) {
|
||||
$this->value = (float) $val;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -57,6 +57,11 @@ class DBDate extends DBField
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function nullValue(): string
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse timestamp or iso8601-ish date into standard iso8601 format
|
||||
*
|
||||
|
@ -27,11 +27,6 @@ class DBDecimal extends DBField
|
||||
*/
|
||||
protected int $decimalSize = 2;
|
||||
|
||||
/**
|
||||
* Default value
|
||||
*/
|
||||
protected float|int|string $defaultValue = 0;
|
||||
|
||||
/**
|
||||
* Create a new Decimal field.
|
||||
*/
|
||||
@ -70,7 +65,7 @@ class DBDecimal extends DBField
|
||||
$parts = [
|
||||
'datatype' => 'decimal',
|
||||
'precision' => "$this->wholeSize,$this->decimalSize",
|
||||
'default' => $this->defaultValue,
|
||||
'default' => $this->getDefaultValue(),
|
||||
'arrayValue' => $this->arrayValue
|
||||
];
|
||||
|
||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\ORM\FieldType;
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Core\Validation\FieldValidation\EnumFieldValidator;
|
||||
use SilverStripe\Core\Validation\FieldValidation\MultiEnumFieldValidator;
|
||||
use SilverStripe\Core\Validation\FieldValidation\StringFieldValidator;
|
||||
use SilverStripe\Forms\CheckboxSetField;
|
||||
use SilverStripe\Forms\MultiSelectField;
|
||||
use SilverStripe\ORM\Connect\MySQLDatabase;
|
||||
@ -16,7 +17,8 @@ use SilverStripe\ORM\DB;
|
||||
class DBMultiEnum extends DBEnum
|
||||
{
|
||||
private static array $field_validators = [
|
||||
// disable parent field validator
|
||||
// disable parent field validators
|
||||
StringFieldValidator::class => null,
|
||||
EnumFieldValidator::class => null,
|
||||
// enable multi enum field validator
|
||||
MultiEnumFieldValidator::class => ['getEnum'],
|
||||
|
@ -1691,7 +1691,7 @@ class Member extends DataObject
|
||||
|
||||
// Overwrite the Password property with the hashed value
|
||||
$this->Password = $encryption_details['password'];
|
||||
$this->Salt = $encryption_details['salt'];
|
||||
$this->Salt = $encryption_details['salt'] ?: '';
|
||||
$this->PasswordEncryption = $encryption_details['algorithm'];
|
||||
|
||||
// If we haven't manually set a password expiry
|
||||
|
@ -11,20 +11,20 @@ class BooleanFieldValidatorTest extends SapphireTest
|
||||
public static function provideValidate(): array
|
||||
{
|
||||
return [
|
||||
'valid-int-1' => [
|
||||
'value' => 1,
|
||||
'expected' => true,
|
||||
],
|
||||
'valid-int-0' => [
|
||||
'value' => 0,
|
||||
'expected' => true,
|
||||
],
|
||||
'invvalid-true' => [
|
||||
'valid-true' => [
|
||||
'value' => true,
|
||||
'expected' => true,
|
||||
],
|
||||
'valid-false' => [
|
||||
'value' => false,
|
||||
'expected' => true,
|
||||
],
|
||||
'invalid-int-1' => [
|
||||
'value' => 1,
|
||||
'expected' => false,
|
||||
],
|
||||
'invalid-false' => [
|
||||
'value' => false,
|
||||
'invalid-int-0' => [
|
||||
'value' => 0,
|
||||
'expected' => false,
|
||||
],
|
||||
'invalid-string-1' => [
|
||||
|
@ -15,6 +15,10 @@ class DateFieldValidatorTest extends SapphireTest
|
||||
'value' => '2020-09-15',
|
||||
'expected' => true,
|
||||
],
|
||||
'valid-blank-string' => [
|
||||
'value' => '',
|
||||
'expected' => true,
|
||||
],
|
||||
'invalid' => [
|
||||
'value' => '2020-02-30',
|
||||
'expected' => false,
|
||||
|
@ -21,16 +21,16 @@ class EnumFieldValidatorTest extends SapphireTest
|
||||
'allowedValues' => [123, 456],
|
||||
'expected' => true,
|
||||
],
|
||||
'valid-none' => [
|
||||
'value' => '',
|
||||
'allowedValues' => ['cat', 'dog'],
|
||||
'expected' => true,
|
||||
],
|
||||
'invalid' => [
|
||||
'value' => 'fish',
|
||||
'allowedValues' => ['cat', 'dog'],
|
||||
'expected' => false,
|
||||
],
|
||||
'invalid-none' => [
|
||||
'value' => '',
|
||||
'allowedValues' => ['cat', 'dog'],
|
||||
'expected' => false,
|
||||
],
|
||||
'invalid-null' => [
|
||||
'value' => null,
|
||||
'allowedValues' => ['cat', 'dog'],
|
||||
|
@ -6,7 +6,6 @@ use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\Forms\TextField;
|
||||
use SilverStripe\Forms\RequiredFields;
|
||||
use SilverStripe\Forms\Tip;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
class TextFieldTest extends SapphireTest
|
||||
{
|
||||
@ -46,42 +45,4 @@ class TextFieldTest extends SapphireTest
|
||||
$textField->setTip(new Tip('TestTip'));
|
||||
$this->assertArrayHasKey('tip', $textField->getSchemaDataDefaults());
|
||||
}
|
||||
|
||||
public static function provideSetValue(): array
|
||||
{
|
||||
return [
|
||||
'string' => [
|
||||
'value' => 'fish',
|
||||
'expected' => 'fish',
|
||||
],
|
||||
'string-blank' => [
|
||||
'value' => '',
|
||||
'expected' => '',
|
||||
],
|
||||
'null' => [
|
||||
'value' => null,
|
||||
'expected' => '',
|
||||
],
|
||||
'zero' => [
|
||||
'value' => 0,
|
||||
'expected' => 0,
|
||||
],
|
||||
'true' => [
|
||||
'value' => true,
|
||||
'expected' => true,
|
||||
],
|
||||
'false' => [
|
||||
'value' => false,
|
||||
'expected' => false,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('provideSetValue')]
|
||||
public function testSetValue(mixed $value, mixed $expected): void
|
||||
{
|
||||
$field = new TextField('TestField');
|
||||
$field->setValue($value);
|
||||
$this->assertSame($expected, $field->getValue());
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ namespace SilverStripe\ORM\Tests;
|
||||
use SilverStripe\Forms\CurrencyField;
|
||||
use SilverStripe\ORM\FieldType\DBCurrency;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
|
||||
class DBCurrencyTest extends SapphireTest
|
||||
{
|
||||
@ -15,11 +16,6 @@ class DBCurrencyTest extends SapphireTest
|
||||
// Test basic operation
|
||||
'$50.00' => ['$50.00', '$50'],
|
||||
|
||||
// Test removal of junk text
|
||||
'this is -50.29 dollars' => ['($50.29)', '($50)'],
|
||||
'this is -50.79 dollars' => ['($50.79)', '($51)'],
|
||||
'this is 50.79 dollars' => ['$50.79', '$51'],
|
||||
|
||||
// Test negative numbers
|
||||
'-1000' => ['($1,000.00)','($1,000)'],
|
||||
'-$2,000' => ['($2,000.00)', '($2,000)'],
|
||||
@ -30,9 +26,6 @@ class DBCurrencyTest extends SapphireTest
|
||||
// Test scientific notation
|
||||
'5.68434188608E-14' => ['$0.00', '$0'],
|
||||
'5.68434188608E7' => ['$56,843,418.86', '$56,843,419'],
|
||||
"Sometimes Es are still bad: 51 dollars, even though they\'re used in scientific notation"
|
||||
=> ['$51.00', '$51'],
|
||||
"What about 5.68434188608E7 in the middle of a string" => ['$56,843,418.86', '$56,843,419'],
|
||||
];
|
||||
|
||||
foreach ($tests as $value => $niceValues) {
|
||||
@ -51,4 +44,75 @@ class DBCurrencyTest extends SapphireTest
|
||||
|
||||
$this->assertInstanceOf(CurrencyField::class, $scaffoldedField);
|
||||
}
|
||||
|
||||
public static function provideSetValue(): array
|
||||
{
|
||||
// Most test cases covered by DBCurrencyTest, only testing a subset here
|
||||
return [
|
||||
'currency' => [
|
||||
'value' => '$1.23',
|
||||
'expected' => 1.23,
|
||||
],
|
||||
'negative-currency' => [
|
||||
'value' => "-$1.23",
|
||||
'expected' => -1.23,
|
||||
],
|
||||
'scientific-1' => [
|
||||
'value' => 5.68434188608E-14,
|
||||
'expected' => 5.68434188608E-14,
|
||||
],
|
||||
'scientific-2' => [
|
||||
'value' => 5.68434188608E7,
|
||||
'expected' => 56843418.8608,
|
||||
],
|
||||
'scientific-1-string' => [
|
||||
'value' => '5.68434188608E-14',
|
||||
'expected' => 5.68434188608E-14,
|
||||
],
|
||||
'scientific-2-string' => [
|
||||
'value' => '5.68434188608E7',
|
||||
'expected' => 56843418.8608,
|
||||
],
|
||||
'int' => [
|
||||
'value' => 1,
|
||||
'expected' => 1.0,
|
||||
],
|
||||
'string-int' => [
|
||||
'value' => "1",
|
||||
'expected' => 1.0,
|
||||
],
|
||||
'string-float' => [
|
||||
'value' => '1.2',
|
||||
'expected' => 1.2,
|
||||
],
|
||||
'value-in-string' => [
|
||||
'value' => 'this is 50.29 dollars',
|
||||
'expected' => 'this is 50.29 dollars',
|
||||
],
|
||||
'scientific-value-in-string' => [
|
||||
'value' => '5.68434188608E7 a string',
|
||||
'expected' => '5.68434188608E7 a string',
|
||||
],
|
||||
'value-in-brackets' => [
|
||||
'value' => '(100)',
|
||||
'expected' => '(100)',
|
||||
],
|
||||
'non-numeric' => [
|
||||
'value' => 'fish',
|
||||
'expected' => 'fish',
|
||||
],
|
||||
'null' => [
|
||||
'value' => null,
|
||||
'expected' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[DataProvider('provideSetValue')]
|
||||
public function testSetValue(mixed $value, mixed $expected): void
|
||||
{
|
||||
$field = new DBCurrency('MyField');
|
||||
$field->setValue($value);
|
||||
$this->assertSame($expected, $field->getValue());
|
||||
}
|
||||
}
|
||||
|
@ -79,24 +79,6 @@ class DBDatetimeTest extends SapphireTest
|
||||
);
|
||||
}
|
||||
|
||||
public function testSetNullAndZeroValues()
|
||||
{
|
||||
$date = DBDatetime::create_field('Datetime', '');
|
||||
$this->assertNull($date->getValue(), 'Empty string evaluates to NULL');
|
||||
|
||||
$date = DBDatetime::create_field('Datetime', null);
|
||||
$this->assertNull($date->getValue(), 'NULL is set as NULL');
|
||||
|
||||
$date = DBDatetime::create_field('Datetime', false);
|
||||
$this->assertNull($date->getValue(), 'Boolean FALSE evaluates to NULL');
|
||||
|
||||
$date = DBDatetime::create_field('Datetime', '0');
|
||||
$this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'String zero is UNIX epoch time');
|
||||
|
||||
$date = DBDatetime::create_field('Datetime', 0);
|
||||
$this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'Numeric zero is UNIX epoch time');
|
||||
}
|
||||
|
||||
public function testExtendedDateTimes()
|
||||
{
|
||||
$date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
|
||||
|
@ -159,11 +159,11 @@ class DBEnumTest extends SapphireTest
|
||||
],
|
||||
'empty-string' => [
|
||||
'value' => '',
|
||||
'expected' => 'blue',
|
||||
'expected' => '',
|
||||
],
|
||||
'null' => [
|
||||
'value' => null,
|
||||
'expected' => 'blue',
|
||||
'expected' => null,
|
||||
],
|
||||
];
|
||||
}
|
||||
@ -175,4 +175,14 @@ class DBEnumTest extends SapphireTest
|
||||
$field->setValue($value);
|
||||
$this->assertSame($expected, $field->getValue());
|
||||
}
|
||||
|
||||
public function testSaveDefaultValue()
|
||||
{
|
||||
$obj = new FieldType\DBEnumTestObject();
|
||||
$obj->Colour = null;
|
||||
$id = $obj->write();
|
||||
// Fetch the object from the database
|
||||
$colour = FieldType\DBEnumTestObject::get()->byID($id)->Colour;
|
||||
$this->assertEquals('Red', $colour);
|
||||
}
|
||||
}
|
||||
|
@ -425,16 +425,20 @@ class DBFieldTest extends SapphireTest
|
||||
{
|
||||
$expectedBaseDefault = null;
|
||||
$expectedDefaults = [
|
||||
DBBoolean::class => 0,
|
||||
DBBoolean::class => false,
|
||||
DBDecimal::class => 0.0,
|
||||
DBInt::class => 0,
|
||||
DBFloat::class => 0.0,
|
||||
];
|
||||
$count = 0;
|
||||
$classes = ClassInfo::subclassesFor(DBField::class);
|
||||
foreach ($classes as $class) {
|
||||
if (is_a($class, TestOnly::class, true)) {
|
||||
continue;
|
||||
}
|
||||
if (!str_starts_with($class, 'SilverStripe\ORM\FieldType')) {
|
||||
continue;
|
||||
}
|
||||
$reflector = new ReflectionClass($class);
|
||||
if ($reflector->isAbstract()) {
|
||||
continue;
|
||||
@ -448,7 +452,11 @@ class DBFieldTest extends SapphireTest
|
||||
}
|
||||
$field = new $class('TestField');
|
||||
$this->assertSame($expected, $field->getValue(), $class);
|
||||
$count++;
|
||||
}
|
||||
// Assert that we have tested all classes e.g. namespace wasn't changed, no new classes were added
|
||||
// that haven't been tested
|
||||
$this->assertSame(29, $count);
|
||||
}
|
||||
|
||||
public function testFieldValidatorConfig(): void
|
||||
|
@ -17,7 +17,7 @@ class DBForiegnKeyTest extends SapphireTest
|
||||
],
|
||||
'string' => [
|
||||
'value' => '2',
|
||||
'expected' => '2',
|
||||
'expected' => 2,
|
||||
],
|
||||
'zero' => [
|
||||
'value' => 0,
|
||||
|
@ -24,22 +24,23 @@ class DecimalTest extends SapphireTest
|
||||
{
|
||||
parent::setUp();
|
||||
$this->testDataObject = $this->objFromFixture(DecimalTest\TestObject::class, 'test-dataobject');
|
||||
$x=1;
|
||||
}
|
||||
|
||||
public function testDefaultValue()
|
||||
{
|
||||
$this->assertEquals(
|
||||
$this->testDataObject->MyDecimal1,
|
||||
$this->assertSame(
|
||||
0,
|
||||
$this->testDataObject->MyDecimal1,
|
||||
'Database default for Decimal type is 0'
|
||||
);
|
||||
}
|
||||
|
||||
public function testSpecifiedDefaultValue()
|
||||
{
|
||||
$this->assertEquals(
|
||||
$this->testDataObject->MyDecimal2,
|
||||
$this->assertSame(
|
||||
2.5,
|
||||
$this->testDataObject->MyDecimal2,
|
||||
'Default value for Decimal type is set to 2.5'
|
||||
);
|
||||
}
|
||||
@ -61,28 +62,28 @@ class DecimalTest extends SapphireTest
|
||||
|
||||
public function testLongValueStoredCorrectly()
|
||||
{
|
||||
$this->assertEquals(
|
||||
$this->testDataObject->MyDecimal5,
|
||||
$this->assertSame(
|
||||
1.0,
|
||||
$this->testDataObject->MyDecimal5,
|
||||
'Long default long decimal value is rounded correctly'
|
||||
);
|
||||
|
||||
$this->assertEqualsWithDelta(
|
||||
$this->testDataObject->MyDecimal5,
|
||||
0.99999999999999999999,
|
||||
$this->testDataObject->MyDecimal5,
|
||||
PHP_FLOAT_EPSILON,
|
||||
'Long default long decimal value is correct within float epsilon'
|
||||
);
|
||||
|
||||
$this->assertEquals(
|
||||
$this->testDataObject->MyDecimal6,
|
||||
$this->assertSame(
|
||||
8.0,
|
||||
$this->testDataObject->MyDecimal6,
|
||||
'Long decimal value with a default value is rounded correctly'
|
||||
);
|
||||
|
||||
$this->assertEqualsWithDelta(
|
||||
$this->testDataObject->MyDecimal6,
|
||||
7.99999999999999999999,
|
||||
$this->testDataObject->MyDecimal6,
|
||||
PHP_FLOAT_EPSILON,
|
||||
'Long decimal value is within epsilon if longer than allowed number of float digits'
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user