diff --git a/model/DataObject.php b/model/DataObject.php index 80bd7c696..112e8b019 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -2056,7 +2056,11 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity // TableField sets the record ID to "new" on new row data, so don't try doing anything in that case if(!is_numeric($this->record['ID'])) return false; - $dataQuery->where("\"$tableClass\".\"ID\" = {$this->record['ID']}")->limit(1); + // Limit query to the current record, unless it has the Versioned extension, + // in which case it requires special handling through augmentLoadLazyFields() + if (!isset($this->record['Version'])){ + $dataQuery->where("\"$tableClass\".\"ID\" = {$this->record['ID']}")->limit(1); + } $columns = array(); // Add SQL for fields, both simple & multi-value @@ -2069,7 +2073,8 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity } if ($columns) { - $query = $dataQuery->query(); // eh? + $query = $dataQuery->query(); + $this->extend('augmentLoadLazyFields', $query, $dataQuery, $this->record); $this->extend('augmentSQL', $query, $dataQuery); $dataQuery->setQueriedColumns($columns); diff --git a/model/Versioned.php b/model/Versioned.php index 11409f209..ac7140c5b 100644 --- a/model/Versioned.php +++ b/model/Versioned.php @@ -257,6 +257,21 @@ class Versioned extends DataExtension { . $dataQuery->getQueryParam('Versioned.mode')); } } + + /** + * For lazy loaded fields requiring extra sql manipulation, ie versioning + * @param SQLQuery $query + * @param DataQuery $dataQuery + * @param array $record + */ + function augmentLoadLazyFields(SQLQuery &$query, DataQuery &$dataQuery = null, $record) { + $dataClass = $dataQuery->dataClass(); + if (isset($record['Version'])){ + $dataQuery->where("\"$dataClass\".\"RecordID\" = " . $record['ID']); + $dataQuery->where("\"$dataClass\".\"Version\" = " . $record['Version']); + $dataQuery->setQueryParam('Versioned.mode', 'all_versions'); + } + } /** * Keep track of the archive tables that have been created diff --git a/tests/model/DataObjectLazyLoadingTest.php b/tests/model/DataObjectLazyLoadingTest.php index 37e8e8c64..7549b565f 100644 --- a/tests/model/DataObjectLazyLoadingTest.php +++ b/tests/model/DataObjectLazyLoadingTest.php @@ -6,9 +6,12 @@ class DataObjectLazyLoadingTest extends SapphireTest { - static $fixture_file = 'DataObjectTest.yml'; + static $fixture_file = array( + 'DataObjectTest.yml', + 'VersionedTest.yml' + ); - // These are all defined in DataObjectTest.php + // These are all defined in DataObjectTest.php and VersionedTest.php protected $extraDataObjects = array( 'DataObjectTest_Team', 'DataObjectTest_Fixture', @@ -18,7 +21,9 @@ class DataObjectLazyLoadingTest extends SapphireTest { 'DataObjectTest_FieldlessSubTable', 'DataObjectTest_ValidatedObject', 'DataObjectTest_Player', - 'DataObjectTest_TeamComment' + 'DataObjectTest_TeamComment', + 'VersionedTest_DataObject', + 'VersionedTest_Subclass' ); public function testQueriedColumnsID() { @@ -244,4 +249,32 @@ class DataObjectLazyLoadingTest extends SapphireTest { $this->assertArrayNotHasKey('SubclassDatabaseField_Lazy', $subteam1Lazy->toMap()); $this->assertArrayHasKey('SubclassDatabaseField', $subteam1Lazy->toMap()); } + + public function testLazyLoadedFieldsOnVersionedRecords() { + // Save another record, sanity check that we're getting the right one + $obj2 = new VersionedTest_Subclass(); + $obj2->Name = "test2"; + $obj2->ExtraField = "foo2"; + $obj2->write(); + + // Save the actual inspected record + $obj1 = new VersionedTest_Subclass(); + $obj1->Name = "test"; + $obj1->ExtraField = "foo"; + $obj1->write(); + $version1 = $obj1->Version; + $obj1->Name = "test2"; + $obj1->ExtraField = "baz"; + $obj1->write(); + $version2 = $obj1->Version; + + $reloaded = Versioned::get_version('VersionedTest_Subclass', $obj1->ID, $version1); + $this->assertEquals($reloaded->Name, 'test'); + $this->assertEquals($reloaded->ExtraField, 'foo'); + + $reloaded = Versioned::get_version('VersionedTest_Subclass', $obj1->ID, $version2); + $this->assertEquals($reloaded->Name, 'test2'); + $this->assertEquals($reloaded->ExtraField, 'baz'); + $obj1->delete(); + } }