mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
Merge pull request #750 from silverstripe-rebelalliance/open/5971
FIX If ClassName read from DB doesnt exist, dont break
This commit is contained in:
commit
57ad36e11d
@ -58,8 +58,10 @@ class ClassInfo {
|
||||
* Returns the manifest of all classes which are present in the database.
|
||||
* @param string $class Class name to check enum values for ClassName field
|
||||
*/
|
||||
static function getValidSubClasses($class = 'SiteTree') {
|
||||
return DB::getConn()->enumValuesForField($class, 'ClassName');
|
||||
static function getValidSubClasses($class = 'SiteTree', $includeUnbacked = false) {
|
||||
$classes = DB::getConn()->enumValuesForField($class, 'ClassName');
|
||||
if (!$includeUnbacked) $classes = array_filter($classes, array('ClassInfo', 'exists'));
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -181,9 +181,12 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
*/
|
||||
public static function database_fields($class) {
|
||||
if(get_parent_class($class) == 'DataObject') {
|
||||
$db = DB::getConn();
|
||||
$existing = $db->hasField($class, 'ClassName') ? $db->query("SELECT DISTINCT \"ClassName\" FROM \"$class\"")->column() : array();
|
||||
|
||||
return array_merge (
|
||||
array (
|
||||
'ClassName' => "Enum('" . implode(', ', ClassInfo::subclassesFor($class)) . "')",
|
||||
'ClassName' => "Enum('" . implode(', ', array_unique(array_merge($existing, ClassInfo::subclassesFor($class)))) . "')",
|
||||
'Created' => 'SS_Datetime',
|
||||
'LastEdited' => 'SS_Datetime'
|
||||
),
|
||||
@ -444,6 +447,17 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
}
|
||||
}
|
||||
|
||||
function getObsoleteClassName() {
|
||||
$className = $this->getField("ClassName");
|
||||
if (!ClassInfo::exists($className)) return $className;
|
||||
}
|
||||
|
||||
function getClassName() {
|
||||
$className = $this->getField("ClassName");
|
||||
if (!ClassInfo::exists($className)) return get_class($this);
|
||||
return $className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ClassName attribute. {@link $class} is also updated.
|
||||
* Warning: This will produce an inconsistent record, as the object
|
||||
@ -986,15 +1000,32 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
||||
$this->brokenOnWrite = true;
|
||||
$isNewRecord = false;
|
||||
|
||||
if(self::get_validation_enabled()) {
|
||||
$writeException = null;
|
||||
|
||||
if ($this->ObsoleteClassName) {
|
||||
$writeException = new ValidationException(
|
||||
"Object is of class '{$this->ObsoleteClassName}' which doesn't exist - ".
|
||||
"you need to change the ClassName before you can write it",
|
||||
E_USER_WARNING
|
||||
);
|
||||
}
|
||||
else if(self::get_validation_enabled()) {
|
||||
$valid = $this->validate();
|
||||
if (!$valid->valid()) {
|
||||
$writeException = new ValidationException(
|
||||
$valid,
|
||||
"Validation error writing a $this->class object: " . $valid->message() . ". Object not written.",
|
||||
E_USER_WARNING
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if($writeException) {
|
||||
// Used by DODs to clean up after themselves, eg, Versioned
|
||||
$this->extend('onAfterSkippedWrite');
|
||||
throw new ValidationException($valid, "Validation error writing a $this->class object: " . $valid->message() . ". Object not written.", E_USER_WARNING);
|
||||
throw $writeException;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->onBeforeWrite();
|
||||
if($this->brokenOnWrite) {
|
||||
|
@ -439,6 +439,18 @@ abstract class SS_Database {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the table exists and already has a the field specified
|
||||
* @param string $tableName - The table to check
|
||||
* @param string $fieldName - The field to check
|
||||
* @return bool - True if the table exists and the field exists on the table
|
||||
*/
|
||||
function hasField($tableName, $fieldName) {
|
||||
if (!$this->hasTable($tableName)) return false;
|
||||
$fields = $this->fieldList($tableName);
|
||||
return array_key_exists($fieldName, $fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the given field on the table, modifying whatever already exists as necessary.
|
||||
* @param string $table The table name.
|
||||
|
@ -1103,7 +1103,7 @@ class Versioned_Version extends ViewableData {
|
||||
$record['ID'] = $record['RecordID'];
|
||||
$className = $record['ClassName'];
|
||||
|
||||
$this->object = new $className($record);
|
||||
$this->object = ClassInfo::exists($className) ? new $className($record) : new DataObject($record);
|
||||
$this->failover = $this->object;
|
||||
|
||||
parent::__construct();
|
||||
|
Loading…
Reference in New Issue
Block a user