diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index 1f46fcc91..52821b6f9 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -2045,6 +2045,8 @@ class MenuBlock extends DisplayBlock $this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:UnlinkAll:', Dict::S('Class:SynchroReplica/Action:unlink_all'),'unlink'); $this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:UnLinkSynchroAll:', Dict::S('Class:SynchroReplica/Action:unlinksynchro_all'),'unlinksynchro'); $this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:SynchroAll:', Dict::S('Class:SynchroReplica/Action:synchro_all'),'synchro'); + $this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:AllowDeleteAll:', Dict::S('Class:SynchroReplica/Action:allowdelete_all'),'allowdelete'); + $this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:DenyDeleteAll:', Dict::S('Class:SynchroReplica/Action:denydelete_all'),'denydelete'); } else { $this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:ModifyAll:'.$sSelectedAlias, Dict::Format('UI:Menu:ModifyAll_'.$sActionLabelCodeSuffix, $sSelectedClassName)); } diff --git a/dictionaries/en.dictionary.itop.core.php b/dictionaries/en.dictionary.itop.core.php index ca254e9cf..617976be9 100644 --- a/dictionaries/en.dictionary.itop.core.php +++ b/dictionaries/en.dictionary.itop.core.php @@ -964,8 +964,8 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of 'Class:SynchroDataSource/Error:DataTableAlreadyExists' => 'The table %1$s already exists in the database. Please use another name for the synchro data table.', 'Core:SynchroReplica:PublicData' => 'Public Data', 'Core:SynchroReplica:PrivateDetails' => 'Private Details', - 'Core:SynchroReplica:BackToDataSource' => 'Go Back to the Synchro Data Source: %1$s', - 'Core:SynchroReplica:ListOfReplicas' => 'List of Replica', + 'Core:SynchroReplica:BackToDataSource' => 'Back to the Synchro Data Source', + 'Core:SynchroReplica:ListOfReplicas' => 'Replicas of the data source: %1$s', 'Core:SynchroAttExtKey:ReconciliationById' => 'id (Primary Key)', 'Core:SynchroAtt:attcode' => 'Attribute', 'Core:SynchroAtt:attcode+' => 'Field of the object', @@ -1065,6 +1065,10 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of 'Class:SynchroReplica/Action:unlinksynchro+' => 'Unlink replica with destination object and execute synchronization with this replica', 'Class:SynchroReplica/Action:synchro' => 'Synchro', 'Class:SynchroReplica/Action:synchro+' => 'Execute synchronization with this replica', + 'Class:SynchroReplica/Action:allowdelete' => 'Allow delete of object linked to this synchro replica', + 'Class:SynchroReplica/Action:allowdelete+' => 'Object linked to a deleted replica is deleted', + 'Class:SynchroReplica/Action:denydelete' => 'Deny delete of object linked to this synchro replica', + 'Class:SynchroReplica/Action:denydelete+' => 'Object linked to a deleted replica is not deleted', 'Class:SynchroReplica/Action:unlink_all' => 'Unlink Synchro Replica objects', 'Class:SynchroReplica/Action:unlink_all+' => 'Unlink replica with destination object', @@ -1072,6 +1076,10 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of 'Class:SynchroReplica/Action:unlinksynchro_all+' => 'Unlink replica with destination object and execute synchronization with this replica', 'Class:SynchroReplica/Action:synchro_all' => 'Synchronize Synchro Replica objects', 'Class:SynchroReplica/Action:synchro_all+' => 'Execute synchronization with this replica', + 'Class:SynchroReplica/Action:allowdelete_all' => 'Allow delete of objects linked to Synchro Replica', + 'Class:SynchroReplica/Action:allowdelete_all+' => 'Object linked to a deleted replica is deleted', + 'Class:SynchroReplica/Action:denydelete_all' => 'Deny delete of objects linked to Synchro Replica', + 'Class:SynchroReplica/Action:denydelete_all+' => 'Object linked to a deleted replica is not deleted', 'UI:UnlinkAllTabTitle' => 'Unlink Synchro Replica objects', 'UI:UnlinkAllPageTitle' => 'Unlink Synchro Replica objects', @@ -1079,6 +1087,10 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of 'UI:UnlinkSynchroAllPageTitle' => ' Unlink & Synchronize Synchro Replica objects', 'UI:SynchroAllTabTitle' => 'Synchronize Synchro Replica objects', 'UI:SynchroAllPageTitle' => 'Synchronize Synchro Replica objects', + 'UI:AllowDeleteAllTabTitle' => 'Allow delete of objects linked to Synchro Replica', + 'UI:AllowDeleteAllPageTitle' => 'Allow delete of objects linked to Synchro Replica', + 'UI:DenyDeleteAllTabTitle' => 'Deny delete of objects linked to Synchro Replica', + 'UI:DenyDeleteAllPageTitle' => 'Deny delete of objects linked to Synchro Replica', 'Class:appUserPreferences' => 'User Preferences', 'Class:appUserPreferences/Attribute:userid' => 'User', diff --git a/pages/UI.php b/pages/UI.php index 0148001d3..d894a24e8 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -644,6 +644,13 @@ try SynchroReplicaController::OperationUnlinkAll($oP, $oAppContext,'synchro'); break; + case 'form_for_allowdelete_all': // Form to modify multiple objects (bulk modify) + SynchroReplicaController::OperationUnlinkAll($oP, $oAppContext,'allowdelete'); + break; + case 'form_for_denydelete_all': // Form to modify multiple objects (bulk modify) + SynchroReplicaController::OperationUnlinkAll($oP, $oAppContext,'denydelete'); + break; + /////////////////////////////////////////////////////////////////////////////////////////// case 'preview_or_modify_all': // Preview or apply bulk modify diff --git a/sources/Controller/Links/SynchroReplicaController.php b/sources/Controller/Links/SynchroReplicaController.php index 71a59a0e9..c0bda2e43 100644 --- a/sources/Controller/Links/SynchroReplicaController.php +++ b/sources/Controller/Links/SynchroReplicaController.php @@ -84,14 +84,20 @@ class SynchroReplicaController extends Controller $bResult = true; try { if (in_array($sOperation, ['unlink', 'unlinksynchro'])) { - \IssueLog::Error('unlinking replica '.$oReplica->GetKey()); - $oReplica->UnLink(); + $oReplica->UnLink(); } if (in_array($sOperation, ['synchro', 'unlinksynchro'])) { - \IssueLog::Error('synchro replica '.$oReplica->GetKey()); $oStatLog = $oReplica->ReSynchro(); $aErrors = $oStatLog->GetTraces(); } + if ($sOperation == 'allowdelete') { + $oReplica->Set('status_dest_creator', 1); + $oReplica->DBUpdate(); + } + if ($sOperation == 'denydelete') { + $oReplica->Set('status_dest_creator', 0); + $oReplica->DBUpdate(); + } } catch (Exception $e) { $bResult = false; diff --git a/sources/Controller/UI.php b/sources/Controller/UI.php index e8eb7cf03..92829c715 100644 --- a/sources/Controller/UI.php +++ b/sources/Controller/UI.php @@ -38,7 +38,7 @@ class UI $aDisplayParams = [ 'icon' => MetaModel::GetClassIcon($sClass, false), - 'title' => Dict::Format('UI:Modify_ObjectsOf_Class', $sClassName), + 'title' => Dict::Format($sTitleCode, $sClassName), ]; IssueLog::Error('OperationSelectForModifyAll'); self::DisplayMultipleSelectionForm($oP, $oFilter, $sNextOperation, $oChecker, [], $aDisplayParams); diff --git a/synchro/replica.php b/synchro/replica.php index 21e3a3898..9351b8985 100644 --- a/synchro/replica.php +++ b/synchro/replica.php @@ -17,6 +17,8 @@ * You should have received a copy of the GNU Affero General Public License */ +use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory; +use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory; use Combodo\iTop\Application\WebPage\iTopWebPage; use UI; @@ -47,21 +49,26 @@ try { break; case 'oql': + $iSourceId = utils::ReadParam('datasource', null); + if ($iSourceId != null) { + $oSource = MetaModel::GetObject('SynchroDataSource', $iSourceId); + //$oP->p(Dict::Format('Core:SynchroReplica:BackToDataSource', $oSource->GetHyperlink()).''); + //$oBackButton = ButtonUIBlockFactory::MakeIconLink('fas fa-chevron-left', Dict::Format('Core:SynchroReplica:BackToDataSource', $oSource->GetName()), ApplicationContext::MakeObjectUrl('SynchroDataSource', $iSourceId)); + $oBackButton = ButtonUIBlockFactory::MakeLinkNeutral( ApplicationContext::MakeObjectUrl('SynchroDataSource', $iSourceId), Dict::S('Core:SynchroReplica:BackToDataSource'), 'fas fa-chevron-left'); + $oP->AddUiBlock($oBackButton); + $oP->AddUiBlock(TitleUIBlockFactory::MakeForPage(Dict::Format('Core:SynchroReplica:ListOfReplicas', $oSource->GetName()))); + } + $sOQL = utils::ReadParam('oql', null, false, 'raw_data'); if ($sOQL == null) { throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'oql')); } $oFilter = DBObjectSearch::FromOQL($sOQL); - $oBlock1 = new DisplayBlock($oFilter, 'search', false, array('menu' => false, 'table_id' => '1')); + $oBlock1 = new DisplayBlock($oFilter, 'search', false, array('menu' => true, 'table_id' => '1')); $oBlock1->Display($oP, 0); - $oP->add('
'.MetaModel::GetClassIcon('SynchroReplica').Dict::S('Core:SynchroReplica:ListOfReplicas').'
'); - $iSourceId = utils::ReadParam('datasource', null); - if ($iSourceId != null) { - $oSource = MetaModel::GetObject('SynchroDataSource', $iSourceId); - $oP->p(Dict::Format('Core:SynchroReplica:BackToDataSource', $oSource->GetHyperlink()).''); - } - $oBlock = new DisplayBlock($oFilter, 'list', false, array('menu' => false)); - $oBlock->Display($oP, 1); + + //$oBlock = new DisplayBlock($oFilter, 'list', false, array('menu' => true)); + //$oBlock->Display($oP, 1); break; case 'delete': @@ -103,6 +110,27 @@ try { } $oReplica = MetaModel::GetObject('SynchroReplica', $iId); $oStatLog = $oReplica->ReSynchro(); + $oReplica->DisplayDetails($oP); + break; + + case 'allowdelete': + $iId = utils::ReadParam('id', null); + if ($iId == null) { + throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id')); + } + $oReplica = MetaModel::GetObject('SynchroReplica', $iId); + $oStatLog = $oReplica->Set('status_dest_creator',1); + $oReplica->DisplayDetails($oP); + break; + + case 'denydelete': // Select the list of objects to be modified (bulk modify) + $iId = utils::ReadParam('id', null); + if ($iId == null) { + throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id')); + } + $oReplica = MetaModel::GetObject('SynchroReplica', $iId); + $oStatLog = $oReplica->Set('status_dest_creator', 0); + $oReplica->DisplayDetails($oP); break; case 'select_for_unlink_all': // Select the list of objects to be modified (bulk modify) @@ -116,6 +144,14 @@ try { case 'select_for_synchro_all': // Select the list of objects to be modified (bulk modify) UI::OperationSelectForModifyAll($oP,'UI:SynchroAllTabTitle', 'UI:SynchroAllPageTitle','form_for_synchro_all'); break; + + case 'select_for_allowdelete_all': // Select the list of objects to be modified (bulk modify) + UI::OperationSelectForModifyAll($oP,'UI:AllowDeleteAllTabTitle', 'UI:AllowDeleteAllPageTitle','form_for_allowdelete_all'); + break; + + case 'select_for_denydelete_all': // Select the list of objects to be modified (bulk modify) + UI::OperationSelectForModifyAll($oP,'UI:DenyDeleteAllTabTitle', 'UI:DenyDeleteAllPageTitle','form_for_denydelete_all'); + break; } } catch(CoreException $e) diff --git a/synchro/synchrodatasource.class.inc.php b/synchro/synchrodatasource.class.inc.php index ae5b3a658..377cc7973 100644 --- a/synchro/synchrodatasource.class.inc.php +++ b/synchro/synchrodatasource.class.inc.php @@ -2929,6 +2929,22 @@ class SynchroReplica extends DBObject implements iDisplay 'url' => $sUrl, 'tooltip' => Dict::S('Class:SynchroReplica/Action:synchro+'), ]; + + if ($this->Get('status_dest_creator') == 1) { + $sUrl = "{$sRootUrl}synchro/replica.php?operation=denydelete&class=$sClass&id=$sId{$sContext}"; + $aActions['Class:SynchroReplica/Action:denydelete'] = [ + 'label' => Dict::S('Class:SynchroReplica/Action:denydelete'), + 'url' => $sUrl, + 'tooltip' => Dict::S('Class:SynchroReplica/Action:denydelete+'), + ]; + } else { + $sUrl = "{$sRootUrl}synchro/replica.php?operation=allowdelete&class=$sClass&id=$sId{$sContext}"; + $aActions['Class:SynchroReplica/Action:allowdelete'] = [ + 'label' => Dict::S('Class:SynchroReplica/Action:allowdelete'), + 'url' => $sUrl, + 'tooltip' => Dict::S('Class:SynchroReplica/Action:allowdelete+'), + ]; + } } if (count($aActions) > 0) { $sRegularActionsMenuTogglerId = "ibo-regular-actions-menu-toggler-{$sId}";