diff --git a/core/dbobject.class.php b/core/dbobject.class.php index 854390796..8e930f43d 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -3220,6 +3220,9 @@ abstract class DBObject implements iDisplay $this->m_aOrigValues[$sAttCode] = $value; } + // Prevent DBUpdate at this point (reentrance protection) + //MetaModel::StartReentranceProtection($this); + try { $this->PostInsertActions(); } diff --git a/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml b/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml index c0e45d451..703bd2ed6 100755 --- a/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml +++ b/datamodels/2.x/itop-profiles-itil/datamodel.itop-profiles-itil.xml @@ -544,19 +544,6 @@ - - - - User profile %1$s cannot be standalone. You should add - other profiles otherwise you may encounter access issue with this user. - - - - - Le profil %1$s ne peut être seul. Sans le rajout d'autres - profiles, l'utilisateur peut rencontrer des problèmes dans iTop. - - - + diff --git a/datamodels/2.x/itop-profiles-itil/dictionaries/en.dict.itop-profiles-itil.php b/datamodels/2.x/itop-profiles-itil/dictionaries/en.dict.itop-profiles-itil.php new file mode 100644 index 000000000..6f562335a --- /dev/null +++ b/datamodels/2.x/itop-profiles-itil/dictionaries/en.dict.itop-profiles-itil.php @@ -0,0 +1,13 @@ + 'Profile %1$s cannot be standalone. You should add other profiles to user %2$s otherwise you may encounter access issue with this user.', + 'Class:User/NonStandaloneProfileWarning-ReparationMessage' => 'Profile %1$s cannot be standalone. User %2$s has been completed with another profile: %3$s.', +)); + diff --git a/datamodels/2.x/itop-profiles-itil/dictionaries/fr.dict.itop-profiles-itil.php b/datamodels/2.x/itop-profiles-itil/dictionaries/fr.dict.itop-profiles-itil.php new file mode 100644 index 000000000..f9d9accc3 --- /dev/null +++ b/datamodels/2.x/itop-profiles-itil/dictionaries/fr.dict.itop-profiles-itil.php @@ -0,0 +1,13 @@ + 'Le profil %1$s ne peut être seul. Sans le rajout d\'autres profiles, l\'utilisateur %2$s peut rencontrer des problèmes dans iTop.', + 'Class:User/NonStandaloneProfileWarning-ReparationMessage' => 'Le profil %1$s ne peut être seul. Le user %2$s a été complété par le profil %3$s.', +)); + diff --git a/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php b/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php index 7a9da7ab7..6bfa0bfc9 100644 --- a/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php +++ b/datamodels/2.x/itop-profiles-itil/src/UserProfilesEventListener.php @@ -284,7 +284,7 @@ class UserProfilesEventListener implements iEventServiceSetup throw new \Exception(sprintf("%s is badly configured. profile $sRepairProfileName does not exist.", self::USERPROFILE_REPAIR_ITOP_PARAM_NAME)); } - $this->aNonStandaloneProfilesMap[$sNonStandaloneProfileName] = $aProfiles[$sRepairProfileName]; + $this->aNonStandaloneProfilesMap[$sNonStandaloneProfileName] = [ 'name' => $sRepairProfileName, 'id' => $aProfiles[$sRepairProfileName]]; } $this->bIsRepairmentEnabled = true; @@ -311,20 +311,21 @@ class UserProfilesEventListener implements iEventServiceSetup public function RepairUserChangesOrWarn(\User $oUser, string $sSingleProfileName) : void { if (array_key_exists($sSingleProfileName, $this->aNonStandaloneProfilesMap)) { - $sRepairingProfileId = $this->aNonStandaloneProfilesMap[$sSingleProfileName]; - $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning", $sSingleProfileName); - if (is_null($sRepairingProfileId)){ + $aRepairingProfileInfo = $this->aNonStandaloneProfilesMap[$sSingleProfileName]; + if (is_null($aRepairingProfileInfo)){ //Notify current user via session messages that there will be an issue //Without preventing from commiting //$oUser::SetSessionMessage(get_class($oUser), $oUser->GetKey(), 1, $sMessage, 'WARNING', 1); + $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning", $sSingleProfileName, $oUser->Get('friendlyname')); throw new \CoreCannotSaveObjectException(array('issues' => [$sMessage], 'class' => get_class($oUser), 'id' => $oUser->GetKey())); } else { //Completing profiles profiles by adding repairing one : by default portal user to a power portal user $oUserProfile = new \URP_UserProfile(); - $oUserProfile->Set('profileid', $sRepairingProfileId); + $oUserProfile->Set('profileid', $aRepairingProfileInfo['id']); $oCurrentUserProfileSet = $oUser->Get('profile_list'); $oCurrentUserProfileSet->AddItem($oUserProfile); $oUser->Set('profile_list', $oCurrentUserProfileSet); + $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning-ReparationMessage", $sSingleProfileName, $oUser->Get('friendlyname'), $aRepairingProfileInfo['name']); $oUser::SetSessionMessage(get_class($oUser), $oUser->GetKey(), 1, $sMessage, 'WARNING', 1); } } @@ -336,14 +337,14 @@ class UserProfilesEventListener implements iEventServiceSetup } if (array_key_exists($sSingleProfileName, $this->aNonStandaloneProfilesMap)) { - $sRepairingProfileId = $this->aNonStandaloneProfilesMap[$sSingleProfileName]; - $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning", $sSingleProfileName); - if (is_null($sRepairingProfileId) - || ($sRepairingProfileId === $sRemovedProfileId) //cannot repair by readding same remove profile as it will raise uniqueness rule + $aRepairingProfileInfo = $this->aNonStandaloneProfilesMap[$sSingleProfileName]; + if (is_null($aRepairingProfileInfo) + || ($aRepairingProfileInfo['id'] === $sRemovedProfileId) //cannot repair by readding same remove profile as it will raise uniqueness rule ){ //Notify current user via session messages that there will be an issue //Without preventing from commiting //$oURP_UserProfile::SetSessionMessage(get_class($oURP_UserProfile), $oURP_UserProfile->GetKey(), 1, $sMessage, 'WARNING', 1); + $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning", $sSingleProfileName, $oUser->Get('friendlyname')); if ($bIsRemoval){ $oURP_UserProfile->AddDeleteIssue($sMessage); } else { @@ -352,12 +353,13 @@ class UserProfilesEventListener implements iEventServiceSetup } else { //Completing profiles profiles by adding repairing one : by default portal user to a power portal user $oUserProfile = new \URP_UserProfile(); - $oUserProfile->Set('profileid', $sRepairingProfileId); + $oUserProfile->Set('profileid', $aRepairingProfileInfo['id']); $oCurrentUserProfileSet = $oUser->Get('profile_list'); $oCurrentUserProfileSet->AddItem($oUserProfile); $oUser->Set('profile_list', $oCurrentUserProfileSet); $oUser->DBWrite(); + $sMessage = \Dict::Format("Class:User/NonStandaloneProfileWarning-ReparationMessage", $sSingleProfileName, $oUser->Get('friendlyname'), $aRepairingProfileInfo['name']); $oURP_UserProfile::SetSessionMessage(get_class($oURP_UserProfile), $oURP_UserProfile->GetKey(), 1, $sMessage, 'WARNING', 1); } } diff --git a/sources/Service/Events/EventService.php b/sources/Service/Events/EventService.php index 072b77473..197f05de4 100644 --- a/sources/Service/Events/EventService.php +++ b/sources/Service/Events/EventService.php @@ -134,8 +134,8 @@ final class EventService return; } - $oLastException = null; - $sLastExceptionMessage = null; + $oFirstException = null; + $sFirstExceptionMessage = null; $bEventFired = false; foreach (self::GetListeners($sEvent, $eventSource) as $aEventCallback) { if (!self::MatchContext($aEventCallback['context'])) { @@ -153,9 +153,12 @@ final class EventService throw $e; } catch (Exception $e) { - $sLastExceptionMessage = "Event '$sLogEventName' for '$sName' id {$aEventCallback['id']} failed with non-blocking error: ".$e->getMessage(); - EventServiceLog::Error($sLastExceptionMessage); - $oLastException = $e; + $sExceptionMessage = "Event '$sLogEventName' for '$sName' id {$aEventCallback['id']} failed with non-blocking error: ".$e->getMessage(); + EventServiceLog::Error($sExceptionMessage); + if (is_null($oFirstException)){ + $oFirstException = $e; + $sFirstExceptionMessage = $sExceptionMessage; + } } } if ($bEventFired) { @@ -163,9 +166,9 @@ final class EventService } $oKPI->ComputeStats('FireEvent', $sEvent); - if (!is_null($oLastException)) { - EventServiceLog::Error("Throwing the last exception caught: $sLastExceptionMessage"); - throw $oLastException; + if (!is_null($oFirstException)) { + EventServiceLog::Error("Throwing the last exception caught: $sFirstExceptionMessage"); + throw $oFirstException; } }