From b80aa236f2ab4ce1b3cf522ae1c45239726ef17d Mon Sep 17 00:00:00 2001 From: Anne-Cath Date: Fri, 17 Oct 2025 17:14:10 +0200 Subject: [PATCH] =?UTF-8?q?N=C2=B08807=20-=20Error=20saving=20when=20a=20D?= =?UTF-8?q?oCheckToWrite=20check=20of=20the=20linkset=20fails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CoreCannotSaveObjectException.php | 8 +++-- core/ormlinkset.class.inc.php | 9 ++++++ dictionaries/en.dictionary.itop.ui.php | 1 + .../Base/Layout/ObjectController.php | 31 ++++++++++++++++--- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/application/exceptions/CoreCannotSaveObjectException.php b/application/exceptions/CoreCannotSaveObjectException.php index 14adb2a745..cb4365ef30 100644 --- a/application/exceptions/CoreCannotSaveObjectException.php +++ b/application/exceptions/CoreCannotSaveObjectException.php @@ -40,12 +40,16 @@ public function __construct($aContextData, $oPrevious = null) /** * @return string + * @since 3.2.3 add param $bWithHeader */ - public function getHtmlMessage() + public function getHtmlMessage($bWithHeader = false) { $sTitle = Dict::S('UI:Error:SaveFailed'); $sContent = "".utils::HtmlEntities($sTitle).""; - + if ($bWithHeader) { + $oObject = MetaModel::GetObject($this->sObjectClass, $this->iObjectId, true, true); + $sContent .= " ".$oObject->Get('friendlyname').""; + } if (count($this->aIssues) == 1) { $sIssue = reset($this->aIssues); $sContent .= " ".utils::HtmlEntities($sIssue).""; diff --git a/core/ormlinkset.class.inc.php b/core/ormlinkset.class.inc.php index 66c951996f..ade9c6b184 100644 --- a/core/ormlinkset.class.inc.php +++ b/core/ormlinkset.class.inc.php @@ -859,6 +859,15 @@ public function ToDBObjectSet($bShowObsolete = true) return $oLinkSet; } + public function RemoveRemoved() + { + $this->aRemoved = []; + } + public function GetRemoved() + { + return $this->aRemoved ; + } + /** * GetValues. * diff --git a/dictionaries/en.dictionary.itop.ui.php b/dictionaries/en.dictionary.itop.ui.php index 584b572f9f..6b1248441b 100644 --- a/dictionaries/en.dictionary.itop.ui.php +++ b/dictionaries/en.dictionary.itop.ui.php @@ -968,6 +968,7 @@ 'UI:SystemIntrusion' => 'Access denied. You have requested an operation that is not allowed for you.', 'UI:FatalErrorMessage' => 'Fatal error, '.ITOP_APPLICATION_SHORT.' cannot continue.', 'UI:Error_Details' => 'Error: %1$s.', + 'UI:LinkedSet:RemovedObjectsDuringRefresh' => 'Warning: removed object(s) in %1$s are there again :
%2$s', 'UI:PageTitle:ProfileProjections' => ITOP_APPLICATION_SHORT.' user management - profile projections', 'UI:UserManagement:Class' => 'Class', diff --git a/sources/Controller/Base/Layout/ObjectController.php b/sources/Controller/Base/Layout/ObjectController.php index 84db6f59ee..dc27a944f7 100644 --- a/sources/Controller/Base/Layout/ObjectController.php +++ b/sources/Controller/Base/Layout/ObjectController.php @@ -6,6 +6,7 @@ namespace Combodo\iTop\Controller\Base\Layout; +use AttributeLinkedSet; use Combodo\iTop\Application\WebPage\AjaxPage; use ApplicationContext; use ApplicationException; @@ -661,13 +662,35 @@ public function OperationApplyModify(){ // Found issues, explain and give the user a second chance // $bDisplayDetails = false; - $aIssues = $e->getIssues(); if ($this->IsHandlingXmlHttpRequest()) { $aResult['data'] = ['error_message' => $e->getHtmlMessage()]; } else { - $oPage->AddHeaderMessage($e->getHtmlMessage(), 'message_error'); - $oObj->DisplayModifyForm($oPage, - array('wizard_container' => true)); // wizard_container: display the wizard border and the title + //8807 - displayModifyForm fail if a linkset is removed -> remove removed linkset and display a specific message + $bWithLinkedSetRemoved = false; + foreach ($oObj->ListChanges() as $sAttCode => $aChange) { + $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); + if ($oAttDef instanceof AttributeLinkedSet) { + $aRemoved = $aChange->GetRemoved(); + if (count($aRemoved) > 0) { + $bWithLinkedSetRemoved = true; + $sLinkedClass = $oAttDef->GetLinkedClass(); + $aRemovedObjectFriendlyName = []; + foreach ($aRemoved as $key=>$value) { + $oLinkedObject = MetaModel::GetObject($sLinkedClass, $key, true, true); + $aRemovedObjectFriendlyName[] = $oLinkedObject->Get('friendlyname'); + } + $aChange->RemoveRemoved(); + $sRemovedMessage = Dict::Format('UI:LinkedSet:RemovedObjectsDuringRefresh', $oAttDef->GetLabel(), implode('
', $aRemovedObjectFriendlyName)); + $oPage->AddHeaderMessage($sRemovedMessage, 'message_info'); + } + } + } + if($bWithLinkedSetRemoved) { + $oPage->AddHeaderMessage($e->getHtmlMessage(true), 'message_error'); + } else { + $oPage->AddHeaderMessage($e->getHtmlMessage(), 'message_error'); + } + $oObj->DisplayModifyForm($oPage, array('wizard_container' => true)); // wizard_container: display the wizard border and the title } }