diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php
index ec9a16391b..06f98fa2cd 100644
--- a/core/attributedef.class.inc.php
+++ b/core/attributedef.class.inc.php
@@ -453,11 +453,49 @@ abstract class AttributeDefinition
/**
* @return bool true if the attribute value comes from the database in one way or another
*/
- public static function LoadFromDB()
+ public static function LoadFromClassTables()
{
return true;
}
+ /**
+ * Write attribute values outside the current class tables
+ *
+ * @param \DBObject $oHostObject
+ *
+ * @return void
+ * @since 3.1.0
+ */
+ public function WriteExternalValues(DBObject $oHostObject): void
+ {
+ }
+
+ /**
+ * Read the data from where it has been stored (outside the current class tables).
+ * This verb must be implemented as soon as LoadFromClassTables returns false and LoadInObject returns true
+ *
+ * @param DBObject $oHostObject
+ *
+ * @return mixed|null
+ * @since 3.1.0
+ */
+ public function ReadExternalValues(DBObject $oHostObject)
+ {
+ return null;
+ }
+
+ /**
+ * Cleanup data upon object deletion (outside the current class tables)
+ * object id still available here
+ *
+ * @param \DBObject $oHostObject
+ *
+ * @since 3.1.0
+ */
+ public function DeleteExternalValues(DBObject $oHostObject): void
+ {
+ }
+
/**
* @return bool true if the attribute should be loaded anytime (in addition to the column selected by the user)
*/
@@ -7068,19 +7106,6 @@ class AttributeExternalKey extends AttributeDBFieldVoid
return $oRet;
}
- /**
- * Return the deletion option for the target attribute
- * i.e. should the target object be deleted when the host object is deleted
- *
- * @return int DEL_AUTO (yes explicit), DEL_SILENT (yes implicit), DEL_MANUAL (no = default)
- *
- * @since 3.1.0
- */
- public function GetDeletionOptionForTargetObject(): int
- {
- return $this->GetOptional('on_host_delete', DEL_MANUAL);
- }
-
public static function GetFormFieldClass()
{
return '\\Combodo\\iTop\\Form\\Field\\SelectObjectField';
@@ -12827,7 +12852,7 @@ class AttributeCustomFields extends AttributeDefinition
return true;
}
- public static function LoadFromDB()
+ public static function LoadFromClassTables()
{
return false;
} // See ReadValue...
@@ -12970,14 +12995,15 @@ class AttributeCustomFields extends AttributeDefinition
}
/**
- * Read the data from where it has been stored. This verb must be implemented as soon as LoadFromDB returns false
+ * Read the data from where it has been stored. This verb must be implemented as soon as LoadFromClassTables returns false
* and LoadInObject returns true
*
- * @param $oHostObject
+ * @param DBObject $oHostObject
*
- * @return ormCustomFieldsValue
+ * @return mixed|null
+ * @since 3.1.0
*/
- public function ReadValue($oHostObject)
+ public function ReadExternalValues(DBObject $oHostObject)
{
try
{
@@ -12997,11 +13023,13 @@ class AttributeCustomFields extends AttributeDefinition
* It is assumed that the data has been checked prior to calling Write()
*
* @param DBObject $oHostObject
- * @param ormCustomFieldsValue|null $oValue (null is the default value)
+ *
+ * @since 3.1.0
*/
- public function WriteValue(DBObject $oHostObject, ormCustomFieldsValue $oValue = null)
+ public function WriteExternalValues(DBObject $oHostObject): void
{
- if (is_null($oValue))
+ $oValue = $oHostObject->Get($this->GetCode());
+ if (!($oValue instanceof ormCustomFieldsValue))
{
$oHandler = $this->GetHandler();
$aValues = array();
@@ -13015,7 +13043,7 @@ class AttributeCustomFields extends AttributeDefinition
$aValues = $oForm->GetCurrentValues();
}
- return $oHandler->WriteValues($oHostObject, $aValues);
+ $oHandler->WriteValues($oHostObject, $aValues);
}
/**
@@ -13074,15 +13102,15 @@ class AttributeCustomFields extends AttributeDefinition
*
* @param DBObject $oHostObject
*
- * @return
* @throws \CoreException
+ * @since 3.1.0
*/
- public function DeleteValue(DBObject $oHostObject)
+ public function DeleteExternalValues(DBObject $oHostObject): void
{
$oValue = $oHostObject->Get($this->GetCode());
$oHandler = $this->GetHandler($oValue->GetValues());
- return $oHandler->DeleteValues($oHostObject);
+ $oHandler->DeleteValues($oHostObject);
}
public function GetAsHTML($value, $oHostObject = null, $bLocalize = true)
diff --git a/core/datamodel.core.xml b/core/datamodel.core.xml
index 3a9750c961..68e0c3ff62 100644
--- a/core/datamodel.core.xml
+++ b/core/datamodel.core.xml
@@ -371,25 +371,25 @@
target
false
string
- ''
+
default_value
false
string
- ''
+
attribute_definition_list
false
string
- ''
+
attribute_definition_exclusion_list
false
string
- ''
+
min_up
@@ -502,7 +502,7 @@
working_time_computing
false
string
- ''
+
diff --git a/core/dbobject.class.php b/core/dbobject.class.php
index 61817ecff3..1ff6290d7a 100644
--- a/core/dbobject.class.php
+++ b/core/dbobject.class.php
@@ -464,13 +464,14 @@ abstract class DBObject implements iDisplay
foreach($aAttList as $sAttCode=>$oAttDef)
{
// Skip links (could not be loaded by the mean of this query)
+ /** @var \AttributeDefinition $oAttDef */
if ($oAttDef->IsLinkSet()) continue;
if (!$oAttDef->LoadInObject()) continue;
unset($value);
$bIsDefined = false;
- if ($oAttDef->LoadFromDB())
+ if ($oAttDef->LoadFromClassTables())
{
// Note: we assume that, for a given attribute, if it can be loaded,
// then one column will be found with an empty suffix, the others have a suffix
@@ -496,8 +497,7 @@ abstract class DBObject implements iDisplay
}
else
{
- /** @var \AttributeCustomFields $oAttDef */
- $value = $oAttDef->ReadValue($this);
+ $value = $oAttDef->ReadExternalValues($this);
$bIsDefined = true;
}
@@ -2674,11 +2674,9 @@ abstract class DBObject implements iDisplay
foreach (MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode => $oAttDef)
{
if (!$oAttDef->LoadInObject()) continue;
- if ($oAttDef->LoadFromDB()) continue;
if (!array_key_exists($sAttCode, $this->m_aTouchedAtt)) continue;
- if (array_key_exists($sAttCode, $this->m_aModifiedAtt) && ($this->m_aModifiedAtt[$sAttCode] == false)) continue;
- /** @var \AttributeCustomFields $oAttDef */
- $oAttDef->WriteValue($this, $this->m_aCurrValues[$sAttCode]);
+ if (array_key_exists($sAttCode, $this->m_aModifiedAtt) && ($this->m_aModifiedAtt[$sAttCode] === false)) continue;
+ $oAttDef->WriteExternalValues($this);
}
}
@@ -3676,11 +3674,7 @@ abstract class DBObject implements iDisplay
}
MetaModel::HKReplugBranch($iNewLeft, $iNewLeft + $iDelta - 1, $oAttDef, $sTable);
}
- elseif (!$oAttDef->LoadFromDB())
- {
- /** @var \AttributeCustomFields $oAttDef */
- $oAttDef->DeleteValue($this);
- }
+ $oAttDef->DeleteExternalValues($this);
}
$iTransactionRetry = 1;
$bIsTransactionEnabled = MetaModel::GetConfig()->Get('db_core_transactions_enabled');
@@ -4890,18 +4884,6 @@ abstract class DBObject implements iDisplay
}
$aVisited[$sClass] = $iThisId;
- // Delete possible target objects
- foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
- if ($oAttDef instanceof AttributeExternalKey && $oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
- $iOption = $oAttDef->GetDeletionOptionForTargetObject();
- if ($iOption === DEL_SILENT || $iOption === DEL_AUTO) {
- // Delete target object
- $oTargetObject = MetaModel::GetObject($oAttDef->GetTargetClass(), $this->Get($sAttCode));
- $oTargetObject->MakeDeletionPlan($oDeletionPlan, $aVisited, $iOption);
- }
- }
- }
-
if ($iDeleteOption == DEL_MANUAL)
{
// Stop the recursion here
diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php
index 1d2c99020d..bb39522514 100644
--- a/setup/compiler.class.inc.php
+++ b/setup/compiler.class.inc.php
@@ -3914,7 +3914,11 @@ PHP;
$aDefinition['type'] = $oNode->GetText();
}
if ($oNode = $oProperty->GetOptionalElement('default')) {
- $aDefinition['default'] = $oNode->GetText();
+ if ($aDefinition['type'] === 'string') {
+ $aDefinition['default'] = $oNode->GetText('');
+ } else {
+ $aDefinition['default'] = $oNode->GetText();
+ }
}
return $aDefinition;