diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 60696cded..285db9460 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -2681,7 +2681,7 @@ abstract class MetaModel } return $aResult; } - public static function EnumReferencingClasses($sClass, $bSkipLinkingClasses = false) + public static function EnumReferencingClasses($sClass, $bSkipLinkingClasses = false, $bInnerJoinsOnly = false) { self::_check_subclass($sClass); @@ -2699,6 +2699,8 @@ abstract class MetaModel if (self::$m_aAttribOrigins[$sSomeClass][$sAttCode] != $sSomeClass) continue; if ($oAttDef->IsExternalKey() && ($oAttDef->GetTargetClass() == $sClass)) { + if ($bInnerJoinsOnly && $oAttDef->IsNullAllowed()) continue; + // Ok, I want this one $aExtKeys[] = $sAttCode; } } diff --git a/pages/UI.php b/pages/UI.php index b854e357f..ec6136aac 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -469,25 +469,88 @@ switch($operation) break; case 'delete': + case 'delete_confirmed': $sClass = utils::ReadParam('class', ''); $sClassLabel = MetaModel::GetName($sClass); $id = utils::ReadParam('id', ''); $oObj = $oContext->GetObject($sClass, $id); $sName = $oObj->GetName(); - $oMyChange = MetaModel::NewObject("CMDBChange"); - $oMyChange->Set("date", time()); - if (UserRights::GetUser() != UserRights::GetRealUser()) + if ($operation == 'delete_confirmed') { - $sUserString = UserRights::GetRealUser()." on behalf of ".UserRights::GetUser(); + $oMyChange = MetaModel::NewObject("CMDBChange"); + $oMyChange->Set("date", time()); + if (UserRights::GetUser() != UserRights::GetRealUser()) + { + $sUserString = UserRights::GetRealUser()." on behalf of ".UserRights::GetUser(); + } + else + { + $sUserString = UserRights::GetUser(); + } + $oMyChange->Set("userinfo", $sUserString); + $oMyChange->DBInsert(); + $oObj->DBDeleteTracked($oMyChange); + $oP->add("

".$sName." - $sClassLabel deleted

\n"); } else { - $sUserString = UserRights::GetUser(); + // Evaluate the consequences onto the DB integrity + // + $aDependentObjects = array(); + $iTotalThreat = 0; + $aRererencingMe = MetaModel::EnumReferencingClasses($sClass, false /*include N-N links*/, true /*inner joins*/); + foreach($aRererencingMe as $sRemoteClass => $aExtKeys) + { + foreach($aExtKeys as $sExtKeyAttCode) + { + //$oAttDef = MetaModel::GetAttributeDef($sClass, $sExtKeyAttCode); + + $oSearch = new DBObjectSearch($sRemoteClass); + $oSearch->AddCondition($sExtKeyAttCode, $id); + $oSet = new CMDBObjectSet($oSearch); + //if ($oSet->Count() > 0) + while ($oDependentObj = $oSet->fetch()) + { + $aDependentObjects[$sRemoteClass][] = $oDependentObj; + $iTotalThreat++; + } + } + } + // Ask for a confirmation, or cancel (back to the object details) + // + if ($iTotalThreat > 0) + { + $oP->p("Warning: $iTotalThreat object(s) are pointing to the object that you would like to delete"); + + foreach ($aDependentObjects as $sRemoteClass => $aPotentialDeletes) + { + $oP->add("

".MetaModel::GetName($sRemoteClass)."\n"); + $oP->add("

\n"); + } + $oP->p("You have to delete those objects prior to deleting ".$oObj->GetHyperLink()); + $oP->add("
\n"); + $oP->add("\n"); + $oP->add("\n"); + $oP->add("
\n"); + } + else + { + $oP->p("Please confirm that you want to delete this object"); + $oP->add("
\n"); + $oP->add("\n"); + $oP->add("\n"); + $oP->add("\n"); + $oP->add("\n"); + $oP->add("\n"); + $oP->add("\n"); + $oP->add("
\n"); + } } - $oMyChange->Set("userinfo", $sUserString); - $oMyChange->DBInsert(); - $oObj->DBDeleteTracked($oMyChange); - $oP->add("

".$sName." - $sClassLabel deleted

\n"); break; case 'apply_new':