From 5138bf1b7fe9a660574444d77ac5324b5687f40d Mon Sep 17 00:00:00 2001 From: Damian Mooyman Date: Thu, 21 Jan 2016 17:08:35 +1300 Subject: [PATCH] API Refactor out Page default classname hack Fixes #1932 --- model/DataObject.php | 9 +++++++++ model/connect/DBSchemaManager.php | 2 -- model/fieldtypes/DBClassName.php | 7 +++++++ tests/model/DBClassNameTest.php | 27 +++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 2 deletions(-) diff --git a/model/DataObject.php b/model/DataObject.php index 9e990a398..f411bfed2 100644 --- a/model/DataObject.php +++ b/model/DataObject.php @@ -94,6 +94,15 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity */ private static $api_access = false; + /** + * Allows specification of a default value for the ClassName field. + * Configure this value only in subclasses of DataObject. + * + * @config + * @var string + */ + private static $default_classname = null; + /** * True if this DataObject has been destroyed. * @var boolean diff --git a/model/connect/DBSchemaManager.php b/model/connect/DBSchemaManager.php index f7e8ffa2d..372b3edf8 100644 --- a/model/connect/DBSchemaManager.php +++ b/model/connect/DBSchemaManager.php @@ -632,7 +632,6 @@ abstract class DBSchemaManager { } else if ($fieldValue != $specValue) { // If enums/sets are being modified, then we need to fix existing data in the table. // Update any records where the enum is set to a legacy value to be set to the default. - // One hard-coded exception is SiteTree - the default for this is Page. foreach (array('enum', 'set') as $enumtype) { if (preg_match("/^$enumtype/i", $specValue)) { $newStr = preg_replace("/(^$enumtype\s*\(')|('$\).*)/i", "", $spec_orig); @@ -650,7 +649,6 @@ abstract class DBSchemaManager { if (count($holder)) { $default = explode('default ', $spec_orig); $default = $default[1]; - if ($default == "'SiteTree'") $default = "'Page'"; $query = "UPDATE \"$table\" SET $field=$default WHERE $field IN ("; for ($i = 0; $i + 1 < count($holder); $i++) { $query .= "'{$holder[$i]}', "; diff --git a/model/fieldtypes/DBClassName.php b/model/fieldtypes/DBClassName.php index 3d9f9343d..84dd1eba1 100644 --- a/model/fieldtypes/DBClassName.php +++ b/model/fieldtypes/DBClassName.php @@ -194,6 +194,13 @@ class DBClassName extends Enum { if($default) { return $default; } + + // Allow classes to set default class + $baseClass = $this->getBaseClass(); + $defaultClass = Config::inst()->get($baseClass, 'default_classname'); + if($defaultClass && class_exists($defaultClass)) { + return $defaultClass; + } // Fallback to first option $enum = $this->getEnum(); diff --git a/tests/model/DBClassNameTest.php b/tests/model/DBClassNameTest.php index c620e4d49..98a05d008 100644 --- a/tests/model/DBClassNameTest.php +++ b/tests/model/DBClassNameTest.php @@ -63,29 +63,41 @@ class DBClassNameTest extends SapphireTest { // Explicit DataObject $field1 = new DBClassName('MyClass', 'DataObject'); $this->assertEquals('DataObject', $field1->getBaseClass()); + $this->assertNotEquals('DataObject', $field1->getDefault()); // Explicit base class $field2 = new DBClassName('MyClass', 'DBClassNameTest_Object'); $this->assertEquals('DBClassNameTest_Object', $field2->getBaseClass()); + $this->assertEquals('DBClassNameTest_Object', $field2->getDefault()); // Explicit subclass $field3 = new DBClassName('MyClass'); $field3->setValue(null, new DBClassNameTest_ObjectSubClass()); $this->assertEquals('DBClassNameTest_Object', $field3->getBaseClass()); + $this->assertEquals('DBClassNameTest_Object', $field3->getDefault()); // Implicit table $field4 = new DBClassName('MyClass'); $field4->setTable('DBClassNameTest_ObjectSubClass_versions'); $this->assertEquals('DBClassNameTest_Object', $field4->getBaseClass()); + $this->assertEquals('DBClassNameTest_Object', $field4->getDefault()); // Missing $field5 = new DBClassName('MyClass'); $this->assertEquals('DataObject', $field5->getBaseClass()); + $this->assertNotEquals('DataObject', $field5->getDefault()); // Invalid class $field6 = new DBClassName('MyClass'); $field6->setTable('InvalidTable'); $this->assertEquals('DataObject', $field6->getBaseClass()); + $this->assertNotEquals('DataObject', $field6->getDefault()); + + // Custom default_classname + $field7 = new DBClassName('MyClass'); + $field7->setTable('DBClassNameTest_CustomDefault'); + $this->assertEquals('DBClassNameTest_CustomDefault', $field7->getBaseClass()); + $this->assertEquals('DBClassNameTest_CustomDefaultSubclass', $field7->getDefault()); } } @@ -118,4 +130,19 @@ class DBClassNameTest_OtherClass extends DataObject implements TestOnly { private static $db = array( 'Title' => 'Varchar' ); +} + +class DBClassNameTest_CustomDefault extends DataObject implements TestOnly { + + private static $default_classname = 'DBClassNameTest_CustomDefaultSubclass'; + + private static $db = array( + 'Title' => 'Varchar' + ); +} + +class DBClassNameTest_CustomDefaultSubclass extends DBClassNameTest_CustomDefault implements TestOnly { + private static $db = array( + 'Content' => 'HTMLText' + ); } \ No newline at end of file