diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 48b27e305e..e51e0a73e8 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -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();