diff --git a/model/DataObject.php b/model/DataObject.php index 2c4ec7c97..1ac147fcd 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -1781,6 +1781,12 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity $extraFields = $this->manyManyExtraFieldsForComponent($componentName) ?: array(); $result = ManyManyList::create($componentClass, $table, $componentField, $parentField, $extraFields); + + // Store component data in query meta-data + $result = $result->alterDataQuery(function($query) use ($extraFields) { + $query->setQueryParam('Component.ExtraFields', $extraFields); + }); + if($this->model) $result->setDataModel($this->model); $this->extend('updateManyManyComponents', $result); @@ -2687,6 +2693,28 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity return $this; } + /** + * {@inheritdoc} + */ + public function castingHelper($field) { + if ($fieldSpec = $this->db($field)) { + return $fieldSpec; + } + + // many_many_extraFields aren't presented by db(), so we check if the source query params + // provide us with meta-data for a many_many relation we can inspect for extra fields. + $queryParams = $this->getSourceQueryParams(); + if (!empty($queryParams['Component.ExtraFields'])) { + $extraFields = $queryParams['Component.ExtraFields']; + + if (isset($extraFields[$field])) { + return $extraFields[$field]; + } + } + + return parent::castingHelper($field); + } + /** * Returns true if the given field exists in a database column on any of * the objects tables and optionally look up a dynamic getter with diff --git a/tests/model/DataObjectTest.php b/tests/model/DataObjectTest.php index ff04389f2..3ca70a887 100644 --- a/tests/model/DataObjectTest.php +++ b/tests/model/DataObjectTest.php @@ -919,6 +919,16 @@ class DataObjectTest extends SapphireTest { $this->assertEmpty($fields); } + public function testCastingHelper() { + $team = $this->objFromFixture('DataObjectTest_Team', 'team1'); + + $this->assertEquals('Varchar', $team->castingHelper('Title'), 'db field wasn\'t casted correctly'); + $this->assertEquals('HTMLVarchar', $team->castingHelper('DatabaseField'), 'db field wasn\'t casted correctly'); + + $sponsor = $team->Sponsors()->first(); + $this->assertEquals('Int', $sponsor->castingHelper('SponsorFee'), 'many_many_extraFields not casted correctly'); + } + public function testSummaryFieldsCustomLabels() { $team = $this->objFromFixture('DataObjectTest_Team', 'team1'); $summaryFields = $team->summaryFields(); diff --git a/view/ViewableData.php b/view/ViewableData.php index 982b9440c..c65e88d26 100644 --- a/view/ViewableData.php +++ b/view/ViewableData.php @@ -287,6 +287,12 @@ class ViewableData extends Object implements IteratorAggregate { */ public function castingHelper($field) { if($this->hasMethod('db') && $fieldSpec = $this->db($field)) { + Deprecation::notice( + '4.0', + 'ViewableData::castingHelper() will no longer extract casting information "db". Please override + castingHelper in your ViewableData subclass.', + Deprecation::SCOPE_GLOBAL + ); return $fieldSpec; }