mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-20 09:08:42 +02:00
N°4157 - Relations, modify one and add it again fails, the adding is ignored - check uniqueness rule before saving object
This commit is contained in:
@@ -2062,15 +2062,13 @@ abstract class DBObject implements iDisplay
|
||||
if ($bHasDuplicates)
|
||||
{
|
||||
$bIsBlockingRule = $aUniquenessRuleProperties['is_blocking'];
|
||||
if (is_null($bIsBlockingRule))
|
||||
{
|
||||
if (is_null($bIsBlockingRule)) {
|
||||
$bIsBlockingRule = true;
|
||||
}
|
||||
|
||||
$sErrorMessage = $this->GetUniquenessRuleMessage($sUniquenessRuleId);
|
||||
$sErrorMessage = $this->GetUniquenessRuleMessage($sUniquenessRuleId, $this);
|
||||
|
||||
if ($bIsBlockingRule)
|
||||
{
|
||||
if ($bIsBlockingRule) {
|
||||
$this->m_aCheckIssues[] = $sErrorMessage;
|
||||
continue;
|
||||
}
|
||||
@@ -2081,32 +2079,32 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
*
|
||||
* @internal
|
||||
*
|
||||
* @param string $sUniquenessRuleId
|
||||
* @param DBObject $oObj
|
||||
*
|
||||
* @return string dict key : Class:$sClassName/UniquenessRule:$sUniquenessRuleId if none then will use Core:UniquenessDefaultError
|
||||
* Dictionary keys can contain "$this" placeholders
|
||||
*
|
||||
* @since 2.6.0 N°659 uniqueness constraint
|
||||
*/
|
||||
protected function GetUniquenessRuleMessage($sUniquenessRuleId)
|
||||
protected function GetUniquenessRuleMessage($sUniquenessRuleId, $oObj)
|
||||
{
|
||||
$sCurrentClass = get_class($this);
|
||||
$sCurrentClass = get_class($oObj);
|
||||
$sClass = MetaModel::GetRootClassForUniquenessRule($sUniquenessRuleId, $sCurrentClass);
|
||||
$sMessageKey = "Class:$sClass/UniquenessRule:$sUniquenessRuleId";
|
||||
$sTemplate = Dict::S($sMessageKey, '');
|
||||
|
||||
if (empty($sTemplate))
|
||||
{
|
||||
if (empty($sTemplate)) {
|
||||
// we could add also a specific message if user is admin ("dict key is missing")
|
||||
return Dict::Format('Core:UniquenessDefaultError', $sUniquenessRuleId);
|
||||
}
|
||||
|
||||
$oString = new TemplateString($sTemplate);
|
||||
|
||||
return $oString->Render(array('this' => $this));
|
||||
return $oString->Render(array('this' => $oObj));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2205,20 +2203,41 @@ abstract class DBObject implements iDisplay
|
||||
$aCurrentRemoteIds = [];
|
||||
$aDuplicatesFields = [];
|
||||
$value->rewind();
|
||||
$oOneLnkFaill = null;
|
||||
while ($oCurrentLnk = $value->current()) {
|
||||
$iExtKeyToRemote = $oCurrentLnk->Get($sExtKeyToRemote);
|
||||
if (isset($aCurrentRemoteIds[$iExtKeyToRemote])) {
|
||||
$aDuplicatesFields[] = $oCurrentLnk->Get($sExtKeyToRemote.'_friendlyname');
|
||||
} else {
|
||||
$aCurrentRemoteIds[$iExtKeyToRemote] = true;
|
||||
$oOneLnkFaill = $oCurrentLnk;
|
||||
}
|
||||
$value->next();
|
||||
}
|
||||
|
||||
if (!empty($aDuplicatesFields)) {
|
||||
$this->m_aCheckWarnings[] = Dict::Format('Core:AttributeLinkedSetDuplicatesFound',
|
||||
$oAttDef->GetLabel(),
|
||||
implode(', ', $aDuplicatesFields));
|
||||
//check uniqueness rule in order to stop saving object if necessary
|
||||
$sCurrentClass = $value->GetClass();
|
||||
$aUniquenessRules = MetaModel::GetUniquenessRules($sCurrentClass);
|
||||
|
||||
foreach ($aUniquenessRules as $sUniquenessRuleId => $aUniquenessRuleProperties) {
|
||||
$bIsBlockingRule = $aUniquenessRuleProperties['is_blocking'];
|
||||
if (is_null($bIsBlockingRule)) {
|
||||
$bIsBlockingRule = true;
|
||||
}
|
||||
|
||||
if ($bIsBlockingRule || $aUniquenessRuleProperties['disabled'] === true) {
|
||||
$sErrorMessage = $this->GetUniquenessRuleMessage($sUniquenessRuleId, $oOneLnkFaill);
|
||||
$this->m_aCheckIssues[] = $sErrorMessage;
|
||||
$this->m_aCheckIssues[] = Dict::Format('Core:AttributeLinkedSetDuplicatesFound',
|
||||
$oAttDef->GetLabel(),
|
||||
implode(', ', $aDuplicatesFields));
|
||||
} else {
|
||||
$this->m_aCheckWarnings[] = Dict::Format('Core:AttributeLinkedSetDuplicatesFound',
|
||||
$oAttDef->GetLabel(),
|
||||
implode(', ', $aDuplicatesFields));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3174,8 +3193,7 @@ abstract class DBObject implements iDisplay
|
||||
$this->OnUpdate();
|
||||
|
||||
$aChanges = $this->ListChanges();
|
||||
if (count($aChanges) == 0)
|
||||
{
|
||||
if (count($aChanges) == 0) {
|
||||
// Attempting to update an unchanged object
|
||||
unset($aUpdateReentrance[$sKey]);
|
||||
|
||||
@@ -3184,12 +3202,11 @@ abstract class DBObject implements iDisplay
|
||||
|
||||
// Ultimate check - ensure DB integrity
|
||||
list($bRes, $aIssues) = $this->CheckToWrite();
|
||||
if (!$bRes)
|
||||
{
|
||||
if (!$bRes) {
|
||||
throw new CoreCannotSaveObjectException(array(
|
||||
'issues' => $aIssues,
|
||||
'class' => get_class($this),
|
||||
'id' => $this->GetKey()
|
||||
'class' => get_class($this),
|
||||
'id' => $this->GetKey(),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -3283,8 +3300,7 @@ abstract class DBObject implements iDisplay
|
||||
}
|
||||
|
||||
// Update scalar attributes
|
||||
if (count($aDBChanges) != 0)
|
||||
{
|
||||
if (count($aDBChanges) != 0) {
|
||||
$oFilter = new DBObjectSearch(get_class($this));
|
||||
$oFilter->AddCondition('id', $this->m_iKey, '=');
|
||||
$oFilter->AllowAllData();
|
||||
|
||||
Reference in New Issue
Block a user