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.
|
* Returns the manifest of all classes which are present in the database.
|
||||||
* @param string $class Class name to check enum values for ClassName field
|
* @param string $class Class name to check enum values for ClassName field
|
||||||
*/
|
*/
|
||||||
static function getValidSubClasses($class = 'SiteTree') {
|
static function getValidSubClasses($class = 'SiteTree', $includeUnbacked = false) {
|
||||||
return DB::getConn()->enumValuesForField($class, 'ClassName');
|
$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) {
|
public static function database_fields($class) {
|
||||||
if(get_parent_class($class) == 'DataObject') {
|
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 (
|
return array_merge (
|
||||||
array (
|
array (
|
||||||
'ClassName' => "Enum('" . implode(', ', ClassInfo::subclassesFor($class)) . "')",
|
'ClassName' => "Enum('" . implode(', ', array_unique(array_merge($existing, ClassInfo::subclassesFor($class)))) . "')",
|
||||||
'Created' => 'SS_Datetime',
|
'Created' => 'SS_Datetime',
|
||||||
'LastEdited' => '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.
|
* Set the ClassName attribute. {@link $class} is also updated.
|
||||||
* Warning: This will produce an inconsistent record, as the object
|
* Warning: This will produce an inconsistent record, as the object
|
||||||
@ -986,15 +1000,32 @@ class DataObject extends ViewableData implements DataObjectInterface, i18nEntity
|
|||||||
$this->brokenOnWrite = true;
|
$this->brokenOnWrite = true;
|
||||||
$isNewRecord = false;
|
$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();
|
$valid = $this->validate();
|
||||||
if(!$valid->valid()) {
|
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
|
// Used by DODs to clean up after themselves, eg, Versioned
|
||||||
$this->extend('onAfterSkippedWrite');
|
$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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
$this->onBeforeWrite();
|
$this->onBeforeWrite();
|
||||||
if($this->brokenOnWrite) {
|
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.
|
* Generate the given field on the table, modifying whatever already exists as necessary.
|
||||||
* @param string $table The table name.
|
* @param string $table The table name.
|
||||||
|
@ -1103,7 +1103,7 @@ class Versioned_Version extends ViewableData {
|
|||||||
$record['ID'] = $record['RecordID'];
|
$record['ID'] = $record['RecordID'];
|
||||||
$className = $record['ClassName'];
|
$className = $record['ClassName'];
|
||||||
|
|
||||||
$this->object = new $className($record);
|
$this->object = ClassInfo::exists($className) ? new $className($record) : new DataObject($record);
|
||||||
$this->failover = $this->object;
|
$this->failover = $this->object;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
Loading…
Reference in New Issue
Block a user