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;