API use injector for DataObject::newClassInstance()

API Fail on invalid class type change
This commit is contained in:
Damian Mooyman 2016-09-05 18:18:52 +12:00
parent 2fbd1658dd
commit efb004b72a
No known key found for this signature in database
GPG Key ID: 78B823A10DE27D1A
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.
*
* @param string $className The new ClassName attribute (a subclass of {@link DataObject})
* @return DataObject $this
* @return $this
*/
public function setClassName($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->setField("ClassName", $className);
$this->setField('RecordClassName', $className);
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.
*/
public function newClassInstance($newClassName) {
$originalClass = $this->ClassName;
$newInstance = new $newClassName(array_merge(
$this->record,
array(
'ClassName' => $originalClass,
'RecordClassName' => $originalClass,
)
), false, $this->model);
if (!is_subclass_of($newClassName, __CLASS__)) {
throw new InvalidArgumentException("$newClassName is not a valid subclass of DataObject");
}
$originalClass = $this->ClassName;
/** @var DataObject $newInstance */
$newInstance = Injector::inst()->create($newClassName, $this->record, false, $this->model);
// Modify ClassName
if($newClassName != $originalClass) {
$newInstance->setClassName($newClassName);
$newInstance->populateDefaults();

View File

@ -1264,14 +1264,21 @@ class DataObjectTest extends SapphireTest {
// Don't write the record, it will reset changed fields
$this->assertInstanceOf('DataObjectTest_SubTeam', $changedDO);
$this->assertEquals($changedDO->ClassName, 'DataObjectTest_SubTeam');
$this->assertEquals($changedDO->RecordClassName, 'DataObjectTest_SubTeam');
$this->assertContains('ClassName', array_keys($changedFields));
$this->assertEquals($changedFields['ClassName']['before'], 'DataObjectTest_Team');
$this->assertEquals($changedFields['ClassName']['after'], 'DataObjectTest_SubTeam');
$this->assertEquals($changedFields['RecordClassName']['before'], 'DataObjectTest_Team');
$this->assertEquals($changedFields['RecordClassName']['after'], 'DataObjectTest_SubTeam');
$changedDO->write();
$this->assertInstanceOf('DataObjectTest_SubTeam', $changedDO);
$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() {