Merge pull request #5950 from open-sausages/pulls/4.0/change-class-cleanup

API use injector for DataObject::newClassInstance()
This commit is contained in:
Daniel Hensby 2016-09-06 07:53:51 +01:00 committed by GitHub
commit 10f429d8d8
2 changed files with 21 additions and 10 deletions

View File

@ -553,14 +553,17 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* or destroy and reinstanciate the record. * or destroy and reinstanciate the record.
* *
* @param string $className The new ClassName attribute (a subclass of {@link DataObject}) * @param string $className The new ClassName attribute (a subclass of {@link DataObject})
* @return DataObject $this * @return $this
*/ */
public function setClassName($className) { public function setClassName($className) {
$className = trim($className); $className = trim($className);
if(!$className || !is_subclass_of($className, 'SilverStripe\ORM\DataObject')) return; if(!$className || !is_subclass_of($className, 'SilverStripe\ORM\DataObject')) {
return $this;
}
$this->class = $className; $this->class = $className;
$this->setField("ClassName", $className); $this->setField("ClassName", $className);
$this->setField('RecordClassName', $className);
return $this; return $this;
} }
@ -581,15 +584,16 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
* @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.
*/ */
public function newClassInstance($newClassName) { public function newClassInstance($newClassName) {
$originalClass = $this->ClassName; if (!is_subclass_of($newClassName, __CLASS__)) {
$newInstance = new $newClassName(array_merge( throw new InvalidArgumentException("$newClassName is not a valid subclass of DataObject");
$this->record, }
array(
'ClassName' => $originalClass,
'RecordClassName' => $originalClass,
)
), false, $this->model);
$originalClass = $this->ClassName;
/** @var DataObject $newInstance */
$newInstance = Injector::inst()->create($newClassName, $this->record, false, $this->model);
// Modify ClassName
if($newClassName != $originalClass) { if($newClassName != $originalClass) {
$newInstance->setClassName($newClassName); $newInstance->setClassName($newClassName);
$newInstance->populateDefaults(); $newInstance->populateDefaults();

View File

@ -1264,14 +1264,21 @@ class DataObjectTest extends SapphireTest {
// Don't write the record, it will reset changed fields // Don't write the record, it will reset changed fields
$this->assertInstanceOf('DataObjectTest_SubTeam', $changedDO); $this->assertInstanceOf('DataObjectTest_SubTeam', $changedDO);
$this->assertEquals($changedDO->ClassName, 'DataObjectTest_SubTeam'); $this->assertEquals($changedDO->ClassName, 'DataObjectTest_SubTeam');
$this->assertEquals($changedDO->RecordClassName, 'DataObjectTest_SubTeam');
$this->assertContains('ClassName', array_keys($changedFields)); $this->assertContains('ClassName', array_keys($changedFields));
$this->assertEquals($changedFields['ClassName']['before'], 'DataObjectTest_Team'); $this->assertEquals($changedFields['ClassName']['before'], 'DataObjectTest_Team');
$this->assertEquals($changedFields['ClassName']['after'], 'DataObjectTest_SubTeam'); $this->assertEquals($changedFields['ClassName']['after'], 'DataObjectTest_SubTeam');
$this->assertEquals($changedFields['RecordClassName']['before'], 'DataObjectTest_Team');
$this->assertEquals($changedFields['RecordClassName']['after'], 'DataObjectTest_SubTeam');
$changedDO->write(); $changedDO->write();
$this->assertInstanceOf('DataObjectTest_SubTeam', $changedDO); $this->assertInstanceOf('DataObjectTest_SubTeam', $changedDO);
$this->assertEquals($changedDO->ClassName, 'DataObjectTest_SubTeam'); $this->assertEquals($changedDO->ClassName, 'DataObjectTest_SubTeam');
// Test invalid classes fail
$this->setExpectedException('InvalidArgumentException', "Controller is not a valid subclass of DataObject");
$dataObject->newClassInstance('Controller');
} }
public function testMultipleManyManyWithSameClass() { public function testMultipleManyManyWithSameClass() {