diff --git a/src/ORM/ArrayList.php b/src/ORM/ArrayList.php index a8436d450..ae0a8e865 100644 --- a/src/ORM/ArrayList.php +++ b/src/ORM/ArrayList.php @@ -583,7 +583,15 @@ class ArrayList extends ViewableData implements SS_List, Filterable, Sortable, L $firstRecord = $this->first(); - return is_array($firstRecord) ? array_key_exists($by, $firstRecord) : property_exists($firstRecord, $by ?? ''); + if (is_array($firstRecord)) { + return array_key_exists($by, $firstRecord); + } + + if ($firstRecord instanceof ViewableData) { + return $firstRecord->hasField($by); + } + + return property_exists($firstRecord, $by ?? ''); } /** diff --git a/src/ORM/DataObject.php b/src/ORM/DataObject.php index 948800b71..b0514fc7b 100644 --- a/src/ORM/DataObject.php +++ b/src/ORM/DataObject.php @@ -1447,7 +1447,7 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $specification = $schema->fieldSpec( $class, $fieldName, - DataObjectSchema::DB_ONLY | DataObjectSchema::UNINHERITED + DataObjectSchema::UNINHERITED ); if (!$specification) { continue; diff --git a/tests/php/ORM/ArrayListTest.php b/tests/php/ORM/ArrayListTest.php index 8a13ee084..dc8a1ef05 100644 --- a/tests/php/ORM/ArrayListTest.php +++ b/tests/php/ORM/ArrayListTest.php @@ -6,6 +6,7 @@ use SilverStripe\Dev\SapphireTest; use SilverStripe\ORM\ArrayList; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\Filterable; +use SilverStripe\View\ArrayData; use stdClass; class ArrayListTest extends SapphireTest @@ -1208,6 +1209,20 @@ class ArrayListTest extends SapphireTest $this->assertFalse($list->canFilterBy('Age')); } + public function testCanFilterByArrayData() + { + $list = new ArrayList( + [ + new ArrayData(['Name' => 'Steve']), + new ArrayData(['Name' => 'Bob']), + new ArrayData(['Name' => 'John']) + ] + ); + + $this->assertTrue($list->canFilterBy('Name')); + $this->assertFalse($list->canFilterBy('Age')); + } + public function testCanFilterByEmpty() { $list = new ArrayList(); diff --git a/tests/php/ORM/DBCompositeTest.php b/tests/php/ORM/DBCompositeTest.php index 4afd93ff0..6f096628b 100644 --- a/tests/php/ORM/DBCompositeTest.php +++ b/tests/php/ORM/DBCompositeTest.php @@ -51,7 +51,8 @@ class DBCompositeTest extends SapphireTest $this->assertEquals( [ 'MyMoney' => 'Money', - 'OverriddenMoney' => 'Money' + 'OverriddenMoney' => 'Money', + 'DoubleMoney' => DBCompositeTest\DBDoubleMoney::class ], $schema->compositeFields(DBCompositeTest\TestObject::class) ); @@ -66,6 +67,7 @@ class DBCompositeTest extends SapphireTest 'MyMoney' => 'Money', 'OtherMoney' => 'Money', 'OverriddenMoney' => 'Money', + 'DoubleMoney' => DBCompositeTest\DBDoubleMoney::class ], $schema->compositeFields(DBCompositeTest\SubclassedDBFieldObject::class) ); @@ -120,4 +122,22 @@ class DBCompositeTest extends SapphireTest $object = new DBCompositeTest\TestObject(); $object->MyMoney->abc = 'def'; } + + public function testWriteToManipuationIsCalledWhenWritingDataObject() + { + $obj = DBCompositeTest\TestObject::create(); + $obj->DoubleMoney = ['Amount' => 10, 'Currency' => 'CAD']; + $moneyField = $obj->dbObject('DoubleMoney'); + $this->assertEquals(10, $moneyField->getAmount()); + + $obj->write(); + + // Custom money class should double the amount before writing + $this->assertEquals(20, $moneyField->getAmount()); + + // Note: these would fail since dbObject will return a new instance + // of the DoubleMoney field based on the initial values + // $this->assertSame($moneyField, $obj->dbObject('DoubleMoney')); + // $this->assertEquals(20, $obj->dbObject('DoubleMoney')->getAmount()); + } } diff --git a/tests/php/ORM/DBCompositeTest/DBDoubleMoney.php b/tests/php/ORM/DBCompositeTest/DBDoubleMoney.php new file mode 100644 index 000000000..1952e3cec --- /dev/null +++ b/tests/php/ORM/DBCompositeTest/DBDoubleMoney.php @@ -0,0 +1,17 @@ +setAmount($this->getAmount() * 2); + + parent::writeToManipulation($manipulation); + } +} diff --git a/tests/php/ORM/DBCompositeTest/TestObject.php b/tests/php/ORM/DBCompositeTest/TestObject.php index cfc74b2d9..10658c693 100644 --- a/tests/php/ORM/DBCompositeTest/TestObject.php +++ b/tests/php/ORM/DBCompositeTest/TestObject.php @@ -12,6 +12,7 @@ class TestObject extends DataObject implements TestOnly private static $db = [ 'Title' => 'Text', 'MyMoney' => 'Money', - 'OverriddenMoney' => 'Money' + 'OverriddenMoney' => 'Money', + 'DoubleMoney' => DBDoubleMoney::class, ]; }