mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
FIX Ensure getters and setters are respected (#10708)
This commit is contained in:
parent
981e20e298
commit
e3a94b9d10
@ -46,7 +46,11 @@ class DBBoolean extends DBField
|
||||
{
|
||||
$fieldName = $this->name;
|
||||
if ($fieldName) {
|
||||
$dataObject->setField($fieldName, $this->value ? 1 : 0);
|
||||
if ($this->value instanceof DBField) {
|
||||
$this->value->saveInto($dataObject);
|
||||
} else {
|
||||
$dataObject->__set($fieldName, $this->value ? 1 : 0);
|
||||
}
|
||||
} else {
|
||||
$class = static::class;
|
||||
throw new \RuntimeException("DBField::saveInto() Called on a nameless '$class' object");
|
||||
|
@ -221,8 +221,12 @@ abstract class DBComposite extends DBField
|
||||
{
|
||||
foreach ($this->compositeDatabaseFields() as $field => $spec) {
|
||||
// Save into record
|
||||
if ($this->value instanceof DBField) {
|
||||
$this->value->saveInto($dataObject);
|
||||
} else {
|
||||
$key = $this->getName() . $field;
|
||||
$dataObject->setField($key, $this->getField($field));
|
||||
$dataObject->__set($key, $this->getField($field));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,8 +88,12 @@ class DBDecimal extends DBField
|
||||
$fieldName = $this->name;
|
||||
|
||||
if ($fieldName) {
|
||||
if ($this->value instanceof DBField) {
|
||||
$this->value->saveInto($dataObject);
|
||||
} else {
|
||||
$value = (float) preg_replace('/[^0-9.\-\+]/', '', $this->value ?? '');
|
||||
$dataObject->setField($fieldName, $value);
|
||||
$dataObject->__set($fieldName, $value);
|
||||
}
|
||||
} else {
|
||||
throw new \UnexpectedValueException(
|
||||
"DBField::saveInto() Called on a nameless '" . static::class . "' object"
|
||||
|
@ -542,7 +542,11 @@ abstract class DBField extends ViewableData implements DBIndexable
|
||||
"DBField::saveInto() Called on a nameless '" . static::class . "' object"
|
||||
);
|
||||
}
|
||||
$dataObject->setField($fieldName, $this->value);
|
||||
if ($this->value instanceof self) {
|
||||
$this->value->saveInto($dataObject);
|
||||
} else {
|
||||
$dataObject->__set($fieldName, $this->value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ class DBPercentage extends DBDecimal
|
||||
|
||||
$fieldName = $this->name;
|
||||
if ($fieldName && $dataObject->$fieldName > 1.0) {
|
||||
$dataObject->setField($fieldName, 1.0);
|
||||
$dataObject->__set($fieldName, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@ use SilverStripe\ORM\FieldType\DBTime;
|
||||
use SilverStripe\ORM\FieldType\DBVarchar;
|
||||
use SilverStripe\ORM\FieldType\DBText;
|
||||
use SilverStripe\Dev\SapphireTest;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
use SilverStripe\ORM\FieldType\DBYear;
|
||||
|
||||
/**
|
||||
@ -34,6 +35,9 @@ use SilverStripe\ORM\FieldType\DBYear;
|
||||
*/
|
||||
class DBFieldTest extends SapphireTest
|
||||
{
|
||||
protected static $extra_dataobjects = [
|
||||
DBFieldTest\TestDataObject::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* Test the nullValue() method on DBField.
|
||||
@ -322,4 +326,73 @@ class DBFieldTest extends SapphireTest
|
||||
$this->assertEquals('<P>ÅÄÖ</P>', DBHTMLText::create_field('HTMLFragment', '<p>åäö</p>')->UpperCase());
|
||||
$this->assertEquals('<p>åäö</p>', DBHTMLText::create_field('HTMLFragment', '<p>ÅÄÖ</p>')->LowerCase());
|
||||
}
|
||||
|
||||
public function testSaveInto()
|
||||
{
|
||||
$obj = new DBFieldTest\TestDataObject();
|
||||
/** @var DBField $field */
|
||||
$field = $obj->dbObject('Title');
|
||||
$field->setValue('New Value');
|
||||
$field->saveInto($obj);
|
||||
|
||||
$this->assertEquals('New Value', $obj->getField('Title'));
|
||||
$this->assertEquals(1, $field->saveIntoCalledCount);
|
||||
$this->assertEquals(1, $obj->setFieldCalledCount);
|
||||
}
|
||||
|
||||
public function testSaveIntoNoRecursion()
|
||||
{
|
||||
$obj = new DBFieldTest\TestDataObject();
|
||||
/** @var DBField $field */
|
||||
$field = $obj->dbObject('Title');
|
||||
$value = new DBFieldTest\TestDbField('Title');
|
||||
$value->setValue('New Value');
|
||||
$field->setValue($value);
|
||||
$field->saveInto($obj);
|
||||
|
||||
$this->assertEquals('New Value', $obj->getField('Title'));
|
||||
$this->assertEquals(1, $field->saveIntoCalledCount);
|
||||
$this->assertEquals(1, $obj->setFieldCalledCount);
|
||||
}
|
||||
|
||||
public function testSaveIntoAsProperty()
|
||||
{
|
||||
$obj = new DBFieldTest\TestDataObject();
|
||||
/** @var DBField $field */
|
||||
$field = $obj->dbObject('Title');
|
||||
$field->setValue('New Value');
|
||||
$obj->Title = $field;
|
||||
|
||||
$this->assertEquals('New Value', $obj->getField('Title'));
|
||||
$this->assertEquals(1, $field->saveIntoCalledCount);
|
||||
// Called twice because $obj->setField($field) => $field->saveInto() => $obj->setField('New Value')
|
||||
$this->assertEquals(2, $obj->setFieldCalledCount);
|
||||
}
|
||||
|
||||
public function testSaveIntoNoRecursionAsProperty()
|
||||
{
|
||||
$obj = new DBFieldTest\TestDataObject();
|
||||
/** @var DBField $field */
|
||||
$field = $obj->dbObject('Title');
|
||||
$value = new DBFieldTest\TestDbField('Title');
|
||||
$value->setValue('New Value');
|
||||
$field->setValue($value);
|
||||
$obj->Title = $field;
|
||||
|
||||
$this->assertEquals('New Value', $obj->getField('Title'));
|
||||
$this->assertEquals(1, $field->saveIntoCalledCount);
|
||||
// Called twice because $obj->setField($field) => $field->saveInto() => $obj->setField('New Value')
|
||||
$this->assertEquals(2, $obj->setFieldCalledCount);
|
||||
}
|
||||
|
||||
public function testSaveIntoRespectsSetters()
|
||||
{
|
||||
$obj = new DBFieldTest\TestDataObject();
|
||||
/** @var DBField $field */
|
||||
$field = $obj->dbObject('MyTestField');
|
||||
$field->setValue('New Value');
|
||||
$obj->MyTestField = $field;
|
||||
|
||||
$this->assertEquals('new value', $obj->getField('MyTestField'));
|
||||
}
|
||||
}
|
||||
|
29
tests/php/ORM/DBFieldTest/TestDataObject.php
Normal file
29
tests/php/ORM/DBFieldTest/TestDataObject.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\ORM\Tests\DBFieldTest;
|
||||
|
||||
use SilverStripe\Dev\TestOnly;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class TestDataObject extends DataObject implements TestOnly
|
||||
{
|
||||
private static $table_name = 'DBFieldTest_TestDataObject';
|
||||
|
||||
private static $db = [
|
||||
'Title' => TestDbField::class,
|
||||
'MyTestField' => TestDbField::class,
|
||||
];
|
||||
|
||||
public $setFieldCalledCount = 0;
|
||||
|
||||
public function setField($fieldName, $val)
|
||||
{
|
||||
$this->setFieldCalledCount++;
|
||||
return parent::setField($fieldName, $val);
|
||||
}
|
||||
|
||||
public function setMyTestField($val)
|
||||
{
|
||||
return $this->setField('MyTestField', strtolower($val));
|
||||
}
|
||||
}
|
42
tests/php/ORM/DBFieldTest/TestDbField.php
Normal file
42
tests/php/ORM/DBFieldTest/TestDbField.php
Normal file
@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\ORM\Tests\DBFieldTest;
|
||||
|
||||
use SilverStripe\Core\Config\Config;
|
||||
use SilverStripe\Dev\TestOnly;
|
||||
use SilverStripe\ORM\DB;
|
||||
use SilverStripe\ORM\FieldType\DBField;
|
||||
|
||||
class TestDbField extends DBField implements TestOnly
|
||||
{
|
||||
public function requireField()
|
||||
{
|
||||
// Basically the same as DBVarchar but we don't want to test with DBVarchar in case something
|
||||
// changes in that class eventually.
|
||||
$charset = Config::inst()->get(MySQLDatabase::class, 'charset');
|
||||
$collation = Config::inst()->get(MySQLDatabase::class, 'collation');
|
||||
|
||||
$parts = [
|
||||
'datatype' => 'varchar',
|
||||
'precision' => 255,
|
||||
'character set' => $charset,
|
||||
'collate' => $collation,
|
||||
'arrayValue' => $this->arrayValue
|
||||
];
|
||||
|
||||
$values = [
|
||||
'type' => 'varchar',
|
||||
'parts' => $parts
|
||||
];
|
||||
|
||||
DB::require_field($this->tableName, $this->name, $values);
|
||||
}
|
||||
|
||||
public $saveIntoCalledCount = 0;
|
||||
|
||||
public function saveInto($dataObject)
|
||||
{
|
||||
$this->saveIntoCalledCount++;
|
||||
return parent::saveInto($dataObject);
|
||||
}
|
||||
}
|
@ -66,6 +66,7 @@ class DataObjectTest extends SapphireTest
|
||||
DataObjectTest\TreeNode::class,
|
||||
DataObjectTest\OverriddenDataObject::class,
|
||||
DataObjectTest\InjectedDataObject::class,
|
||||
DataObjectTest\SettersAndGetters::class,
|
||||
];
|
||||
|
||||
protected function setUp(): void
|
||||
@ -2667,4 +2668,14 @@ class DataObjectTest extends SapphireTest
|
||||
$vals = ['25.25', '50.00', '75.00', '100.50'];
|
||||
$this->assertSame(array_combine($vals ?? [], $vals ?? []), $obj->dbObject('MyEnumWithDots')->enumValues());
|
||||
}
|
||||
|
||||
public function testSettersAndGettersAreRespected()
|
||||
{
|
||||
$obj = new DataObjectTest\SettersAndGetters();
|
||||
$obj->MyTestField = 'Some Value';
|
||||
// Setter overrides it with all lower case
|
||||
$this->assertSame('some value', $obj->getField('MyTestField'));
|
||||
// Getter overrides it with all upper case
|
||||
$this->assertSame('SOME VALUE', $obj->MyTestField);
|
||||
}
|
||||
}
|
||||
|
25
tests/php/ORM/DataObjectTest/SettersAndGetters.php
Normal file
25
tests/php/ORM/DataObjectTest/SettersAndGetters.php
Normal file
@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace SilverStripe\ORM\Tests\DataObjectTest;
|
||||
|
||||
use SilverStripe\Dev\TestOnly;
|
||||
use SilverStripe\ORM\DataObject;
|
||||
|
||||
class SettersAndGetters extends DataObject implements TestOnly
|
||||
{
|
||||
private static $table_name = 'DataObjectTest_SettersAndGetters';
|
||||
|
||||
private static $db = [
|
||||
'MyTestField' => 'Varchar(255)',
|
||||
];
|
||||
|
||||
public function setMyTestField($val)
|
||||
{
|
||||
$this->setField('MyTestField', strtolower($val));
|
||||
}
|
||||
|
||||
public function getMyTestField()
|
||||
{
|
||||
return strtoupper($this->getField('MyTestField'));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user