mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 12:05:37 +00:00
BUGFIX #4605 DataObject::newClassInstance() should repopulate it's defaults after changing to an instance of a different class, otherwise databases will complain of NULL values being written to columns that don't accept NULL values.
git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@88956 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
parent
57ab419736
commit
559bbfcca8
@ -410,12 +410,17 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance of a different class from this object's record
|
* Create a new instance of a different class from this object's record.
|
||||||
* This is useful when dynamically changing the type of an instance. Specifically,
|
* This is useful when dynamically changing the type of an instance. Specifically,
|
||||||
* it ensures that the instance of the class is a match for the className of the
|
* it ensures that the instance of the class is a match for the className of the
|
||||||
* record. Don't set the {@link DataObject->class} or {@link DataObject->ClassName}
|
* record. Don't set the {@link DataObject->class} or {@link DataObject->ClassName}
|
||||||
* property manually before calling this method, as it will confuse change detection.
|
* property manually before calling this method, as it will confuse change detection.
|
||||||
*
|
*
|
||||||
|
* If the new class is different to the original class, defaults are populated again
|
||||||
|
* because this will only occur automatically on instantiation of a DataObject if
|
||||||
|
* there is no record, or the record has no ID. In this case, we do have an ID but
|
||||||
|
* we still need to repopulate the defaults.
|
||||||
|
*
|
||||||
* @param string $newClassName The name of the new class
|
* @param string $newClassName The name of the new class
|
||||||
*
|
*
|
||||||
* @return DataObject The new instance of the new class, The exact type will be of the class name provided.
|
* @return DataObject The new instance of the new class, The exact type will be of the class name provided.
|
||||||
@ -425,12 +430,14 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$newInstance = new $newClassName(array_merge(
|
$newInstance = new $newClassName(array_merge(
|
||||||
$this->record,
|
$this->record,
|
||||||
array(
|
array(
|
||||||
'ClassName'=>$originalClass,
|
'ClassName' => $originalClass,
|
||||||
'RecordClassName'=>$originalClass,
|
'RecordClassName' => $originalClass,
|
||||||
)
|
)
|
||||||
));
|
));
|
||||||
if($newClassName != $this->ClassName) {
|
|
||||||
|
if($newClassName != $originalClass) {
|
||||||
$newInstance->setClassName($newClassName);
|
$newInstance->setClassName($newClassName);
|
||||||
|
$newInstance->populateDefaults();
|
||||||
$newInstance->forceChange();
|
$newInstance->forceChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,10 @@ class RedirectorPage extends Page {
|
|||||||
"ExternalURL" => "Varchar(255)",
|
"ExternalURL" => "Varchar(255)",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static $defaults = array(
|
||||||
|
"RedirectionType" => "Internal"
|
||||||
|
);
|
||||||
|
|
||||||
static $has_one = array(
|
static $has_one = array(
|
||||||
"LinkTo" => "SiteTree",
|
"LinkTo" => "SiteTree",
|
||||||
);
|
);
|
||||||
|
@ -767,6 +767,7 @@ class Translatable extends DataObjectDecorator implements PermissionProvider {
|
|||||||
if($translations) foreach($translations as $translation) {
|
if($translations) foreach($translations as $translation) {
|
||||||
$translation->setClassName($this->owner->ClassName);
|
$translation->setClassName($this->owner->ClassName);
|
||||||
$translation = $translation->newClassInstance($translation->ClassName);
|
$translation = $translation->newClassInstance($translation->ClassName);
|
||||||
|
$translation->populateDefaults();
|
||||||
$translation->forceChange();
|
$translation->forceChange();
|
||||||
$translation->write();
|
$translation->write();
|
||||||
}
|
}
|
||||||
|
@ -641,9 +641,9 @@ class DataObjectTest extends SapphireTest {
|
|||||||
$changedFields = $changedPage->getChangedFields();
|
$changedFields = $changedPage->getChangedFields();
|
||||||
|
|
||||||
// Don't write the record, it will reset changed fields
|
// Don't write the record, it will reset changed fields
|
||||||
|
|
||||||
$this->assertType('RedirectorPage', $changedPage);
|
$this->assertType('RedirectorPage', $changedPage);
|
||||||
$this->assertEquals($changedPage->ClassName, 'RedirectorPage');
|
$this->assertEquals($changedPage->ClassName, 'RedirectorPage');
|
||||||
|
$this->assertEquals($changedPage->RedirectionType, 'Internal');
|
||||||
//$this->assertEquals($changedPage->RecordClassName, 'RedirectorPage');
|
//$this->assertEquals($changedPage->RecordClassName, 'RedirectorPage');
|
||||||
$this->assertContains('ClassName', array_keys($changedFields));
|
$this->assertContains('ClassName', array_keys($changedFields));
|
||||||
$this->assertEquals($changedFields['ClassName']['before'], 'Page');
|
$this->assertEquals($changedFields['ClassName']['before'], 'Page');
|
||||||
|
@ -684,8 +684,8 @@ class TranslatableTest extends FunctionalTest {
|
|||||||
$translatedPageID = $translatedPage->ID;
|
$translatedPageID = $translatedPage->ID;
|
||||||
|
|
||||||
// change page type
|
// change page type
|
||||||
$origPage->ClassName = 'RedirectorPage';
|
$newPage = $origPage->newClassInstance('RedirectorPage');
|
||||||
$origPage->write();
|
$newPage->write();
|
||||||
|
|
||||||
// re-fetch original page with new instance
|
// re-fetch original page with new instance
|
||||||
$origPageChanged = DataObject::get_by_id('RedirectorPage', $origPageID);
|
$origPageChanged = DataObject::get_by_id('RedirectorPage', $origPageID);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user