Compare commits

...

8 Commits

Author SHA1 Message Date
Anne-Cath
9f5bcd8b27 Update autoload 2026-03-02 14:54:07 +01:00
Anne-Cath
3ff05a6257 Fix rebase 2026-03-02 10:58:56 +01:00
Anne-Cath
b39a39a930 update composer 2026-03-02 10:25:14 +01:00
Anne-Cath
e6b8c49186 Remove IssueLog used for develop 2026-03-02 10:24:48 +01:00
Anne-Cath
3da3c6e79c Added "Allow delete Object" and "deny delete Object" when replica is deleted 2026-03-02 10:24:32 +01:00
Anne-Cath
30466cdd2f WIP
- Add access rights management
- Manage mass updates
- Add tooltips to buttons
2026-03-02 10:23:18 +01:00
acognet
f1526fda06 Add english dictionnary 2026-03-02 09:32:02 +01:00
acognet
9e094a632d Add operation on replica 2026-03-02 09:31:37 +01:00
13 changed files with 820 additions and 355 deletions

View File

@@ -524,6 +524,11 @@ JS
$sLabel = Dict::S('Tag:Synchronized');
$sSynchroTagId = 'synchro_icon-'.$this->GetKey();
$aTags[$sSynchroTagId] = ['title' => $sTip, 'css_classes' => 'ibo-object-details--tag--synchronized', 'decoration_classes' => 'fas fa-lock', 'label' => $sLabel];
if (UserRights::IsActionAllowed('SynchroReplica', UR_ACTION_READ)) {
$sFilter = 'SELECT SynchroReplica WHERE dest_class=\''.get_class($this).'\' AND dest_id='.$this->GetKey();
$sUrlSearchReplica = 'UI.php?operation=search&filter='.urlencode(json_encode([$sFilter, [], []]));
$oPage->add_ready_script("$('#$sSynchroTagId').on('click',function() {window.location = '$sUrlSearchReplica' });");
}
}
}

View File

@@ -1940,7 +1940,7 @@ class MenuBlock extends DisplayBlock
$sSelectedClassName = MetaModel::GetName($sSelectedClass);
// Check rights on class
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject'));
$bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sSelectedClass)) && UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_MODIFY) && (($oReflectionClass->IsSubclassOf('cmdbAbstractObject') || $sSelectedClass === 'SynchroReplica'));
$bIsBulkDeleteAllowed = (bool) UserRights::IsActionAllowed($sSelectedClass, UR_ACTION_BULK_DELETE);
// Refine filter on selected class so bullk actions occur on the right class
@@ -1951,7 +1951,15 @@ class MenuBlock extends DisplayBlock
// Action label dict code has a specific suffix for "Link" / "Remote" aliases to allow dedicated labels in linksets.
$sActionLabelCodeSuffix = in_array($sSelectedAlias, ['Link', 'Remote']) ? $sSelectedAlias : 'Class';
if ($bIsBulkModifyAllowed) {
$this->AddBulkModifyObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:ModifyAll:'.$sSelectedAlias, Dict::Format('UI:Menu:ModifyAll_'.$sActionLabelCodeSuffix, $sSelectedClassName));
if($sSelectedClass === 'SynchroReplica'){
$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));
}
}
if ($bIsBulkDeleteAllowed) {
$this->AddBulkDeleteObjectsMenuAction($aRegularActions, $sSelectedClass, $oSelectedClassFilter->serialize(), 'UI:Menu:BulkDelete:'.$sSelectedAlias, Dict::Format('UI:Menu:BulkDelete_'.$sActionLabelCodeSuffix, $sSelectedClassName));
@@ -2471,11 +2479,11 @@ class MenuBlock extends DisplayBlock
* @since 3.1.0
* @internal
*/
protected function AddBulkModifyObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:ModifyAll', $sActionLabel = 'UI:Menu:ModifyAll'): void
protected function AddBulkModifyObjectsMenuAction(array &$aActions, string $sClass, string $sFilter, string $sActionIdentifier = 'UI:Menu:ModifyAll', $sActionLabel = 'UI:Menu:ModifyAll', $sOperationName = 'modify'): void
{
$aActions[$sActionIdentifier] = [
'label' => Dict::S($sActionLabel),
'url' => $this->PrepareUrlForStandardMenuAction($sClass, "operation=select_for_modify_all&class=$sClass&filter=".urlencode($sFilter)),
'url' => $this->PrepareUrlForStandardMenuAction($sClass, 'operation=select_for_'.$sOperationName.'_all&class='.$sClass.'&filter='.urlencode($sFilter)),
] + $this->GetDefaultParamsForMenuAction();
}

View File

@@ -981,8 +981,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',
@@ -1036,65 +1036,99 @@ The hyperlink is displayed in the tooltip appearing on the “Lock” symbol of
'Class:SynchroAttLinkSet/Attribute:row_separator' => 'Rows separator',
'Class:SynchroAttLinkSet/Attribute:attribute_separator' => 'Attributes separator',
'Class:SynchroLog' => 'Synchro Log',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroLog/Attribute:start_date' => 'Start Date',
'Class:SynchroLog/Attribute:end_date' => 'End Date',
'Class:SynchroLog/Attribute:status' => 'Status',
'Class:SynchroLog/Attribute:status/Value:completed' => 'Completed',
'Class:SynchroLog/Attribute:status/Value:error' => 'Error',
'Class:SynchroLog/Attribute:status/Value:running' => 'Still Running',
'Class:SynchroLog/Attribute:stats_nb_replica_seen' => 'Nb replica seen',
'Class:SynchroLog/Attribute:stats_nb_replica_total' => 'Nb replica total',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted' => 'Nb objects deleted',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted_errors' => 'Nb of errors while deleting',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted' => 'Nb objects obsoleted',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted_errors' => 'Nb of errors while obsoleting',
'Class:SynchroLog/Attribute:stats_nb_obj_created' => 'Nb objects created',
'Class:SynchroLog/Attribute:stats_nb_obj_created_errors' => 'Nb or errors while creating',
'Class:SynchroLog/Attribute:stats_nb_obj_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_updated_errors' => 'Nb errors while updating',
'Class:SynchroLog/Attribute:stats_nb_replica_reconciled_errors' => 'Nb of errors during reconciliation',
'Class:SynchroLog/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroLog/Attribute:start_date' => 'Start Date',
'Class:SynchroLog/Attribute:end_date' => 'End Date',
'Class:SynchroLog/Attribute:status' => 'Status',
'Class:SynchroLog/Attribute:status/Value:completed' => 'Completed',
'Class:SynchroLog/Attribute:status/Value:error' => 'Error',
'Class:SynchroLog/Attribute:status/Value:running' => 'Still Running',
'Class:SynchroLog/Attribute:stats_nb_replica_seen' => 'Nb replica seen',
'Class:SynchroLog/Attribute:stats_nb_replica_total' => 'Nb replica total',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted' => 'Nb objects deleted',
'Class:SynchroLog/Attribute:stats_nb_obj_deleted_errors' => 'Nb of errors while deleting',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted' => 'Nb objects obsoleted',
'Class:SynchroLog/Attribute:stats_nb_obj_obsoleted_errors' => 'Nb of errors while obsoleting',
'Class:SynchroLog/Attribute:stats_nb_obj_created' => 'Nb objects created',
'Class:SynchroLog/Attribute:stats_nb_obj_created_errors' => 'Nb or errors while creating',
'Class:SynchroLog/Attribute:stats_nb_obj_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_updated_errors' => 'Nb errors while updating',
'Class:SynchroLog/Attribute:stats_nb_replica_reconciled_errors' => 'Nb of errors during reconciliation',
'Class:SynchroLog/Attribute:stats_nb_replica_disappeared_no_action' => 'Nb replica disappeared',
'Class:SynchroLog/Attribute:stats_nb_obj_new_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_new_unchanged' => 'Nb objects unchanged',
'Class:SynchroLog/Attribute:last_error' => 'Last error',
'Class:SynchroLog/Attribute:traces' => 'Traces',
'Class:SynchroReplica' => 'Synchro Replica',
'Class:SynchroReplica/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroReplica/Attribute:dest_id' => 'Destination object (ID)',
'Class:SynchroReplica/Attribute:dest_class' => 'Destination type',
'Class:SynchroReplica/Attribute:status_last_seen' => 'Last seen',
'Class:SynchroReplica/Attribute:status' => 'Status',
'Class:SynchroReplica/Attribute:status/Value:modified' => 'Modified',
'Class:SynchroReplica/Attribute:status/Value:new' => 'New',
'Class:SynchroReplica/Attribute:status/Value:obsolete' => 'Obsolete',
'Class:SynchroReplica/Attribute:status/Value:orphan' => 'Orphan',
'Class:SynchroReplica/Attribute:status/Value:synchronized' => 'Synchronized',
'Class:SynchroReplica/Attribute:status_dest_creator' => 'Object Created ?',
'Class:SynchroReplica/Attribute:status_last_error' => 'Last Error',
'Class:SynchroReplica/Attribute:status_last_warning' => 'Warnings',
'Class:SynchroReplica/Attribute:info_creation_date' => 'Creation Date',
'Class:SynchroReplica/Attribute:info_last_modified' => 'Last Modified Date',
'Class:appUserPreferences' => 'User Preferences',
'Class:appUserPreferences/Attribute:userid' => 'User',
'Class:SynchroLog/Attribute:stats_nb_obj_new_updated' => 'Nb objects updated',
'Class:SynchroLog/Attribute:stats_nb_obj_new_unchanged' => 'Nb objects unchanged',
'Class:SynchroLog/Attribute:last_error' => 'Last error',
'Class:SynchroLog/Attribute:traces' => 'Traces',
'Class:SynchroReplica' => 'Synchro Replica',
'Class:SynchroReplica/Attribute:sync_source_id' => 'Synchro Data Source',
'Class:SynchroReplica/Attribute:dest_id' => 'Destination object (ID)',
'Class:SynchroReplica/Attribute:dest_class' => 'Destination type',
'Class:SynchroReplica/Attribute:status_last_seen' => 'Last seen',
'Class:SynchroReplica/Attribute:status' => 'Status',
'Class:SynchroReplica/Attribute:status/Value:modified' => 'Modified',
'Class:SynchroReplica/Attribute:status/Value:new' => 'New',
'Class:SynchroReplica/Attribute:status/Value:obsolete' => 'Obsolete',
'Class:SynchroReplica/Attribute:status/Value:orphan' => 'Orphan',
'Class:SynchroReplica/Attribute:status/Value:synchronized' => 'Synchronized',
'Class:SynchroReplica/Attribute:status_dest_creator' => 'Object Created ?',
'Class:SynchroReplica/Attribute:status_last_error' => 'Last Error',
'Class:SynchroReplica/Attribute:status_last_warning' => 'Warnings',
'Class:SynchroReplica/Attribute:info_creation_date' => 'Creation Date',
'Class:SynchroReplica/Attribute:info_last_modified' => 'Last Modified Date',
'Class:SynchroReplica/Action:delete+' => 'delete replica',
'Class:SynchroReplica/Action:unlink' => 'Unlink',
'Class:SynchroReplica/Action:unlink+' => 'Unlink replica with destination object',
'Class:SynchroReplica/Action:unlinksynchro' => 'Unlink & Synchro',
'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',
'Class:SynchroReplica/Action:unlinksynchro_all' => 'Unlink & Synchronize Synchro Replica objects',
'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',
'UI:UnlinkSynchroAllTabTitle' => 'Unlink & Synchronize Synchro Replica objects',
'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',
'Class:appUserPreferences/Attribute:preferences' => 'Prefs',
'Core:ExecProcess:Code1' => 'Wrong command or command finished with errors (e.g. wrong script name)',
'Core:ExecProcess:Code255' => 'PHP Error (parsing, or runtime)',
'Core:ExecProcess:Code1' => 'Wrong command or command finished with errors (e.g. wrong script name)',
'Core:ExecProcess:Code255' => 'PHP Error (parsing, or runtime)',
// Attribute Duration
'Core:Duration_Seconds' => '%1$ds',
'Core:Duration_Minutes_Seconds' => '%1$dmin %2$ds',
'Core:Duration_Hours_Minutes_Seconds' => '%1$dh %2$dmin %3$ds',
'Core:Duration_Days_Hours_Minutes_Seconds' => '%1$sd %2$dh %3$dmin %4$ds',
'Core:Duration_Seconds' => '%1$ds',
'Core:Duration_Minutes_Seconds' => '%1$dmin %2$ds',
'Core:Duration_Hours_Minutes_Seconds' => '%1$dh %2$dmin %3$ds',
'Core:Duration_Days_Hours_Minutes_Seconds' => '%1$sd %2$dh %3$dmin %4$ds',
// Explain working time computing
'Core:ExplainWTC:ElapsedTime' => 'Time elapsed (stored as "%1$s")',
'Core:ExplainWTC:StopWatch-TimeSpent' => 'Time spent for "%1$s"',
'Core:ExplainWTC:StopWatch-Deadline' => 'Deadline for "%1$s" at %2$d%%',
'Core:ExplainWTC:ElapsedTime' => 'Time elapsed (stored as "%1$s")',
'Core:ExplainWTC:StopWatch-TimeSpent' => 'Time spent for "%1$s"',
'Core:ExplainWTC:StopWatch-Deadline' => 'Deadline for "%1$s" at %2$d%%',
// Bulk export
'Core:BulkExport:MissingParameter_Param' => 'Missing parameter "%1$s"',
'Core:BulkExport:InvalidParameter_Query' => 'Invalid value for the parameter "query". There is no Query Phrasebook corresponding to the id: "%1$s".',
'Core:BulkExport:MissingParameter_Param' => 'Missing parameter "%1$s"',
'Core:BulkExport:InvalidParameter_Query' => 'Invalid value for the parameter "query". There is no Query Phrasebook corresponding to the id: "%1$s".',
'Core:BulkExport:ExportFormatPrompt' => 'Export format:',
'Core:BulkExportOf_Class' => '%1$s Export',
'Core:BulkExport:ClickHereToDownload_FileName' => 'Click here to download %1$s',

View File

@@ -14,7 +14,10 @@ if (PHP_VERSION_ID < 50600) {
echo $err;
}
}
throw new RuntimeException($err);
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';

View File

@@ -347,6 +347,7 @@ return array(
'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => $baseDir . '/sources/Controller/Base/Layout/ObjectController.php',
'Combodo\\iTop\\Controller\\Base\\Layout\\OqlController' => $baseDir . '/sources/Controller/Base/Layout/OqlController.php',
'Combodo\\iTop\\Controller\\Links\\LinkSetController' => $baseDir . '/sources/Controller/Links/LinkSetController.php',
'Combodo\\iTop\\Controller\\Links\\SynchroReplicaController' => $baseDir . '/sources/Controller/Links/SynchroReplicaController.php',
'Combodo\\iTop\\Controller\\Newsroom\\iTopNewsroomController' => $baseDir . '/sources/Controller/Newsroom/iTopNewsroomController.php',
'Combodo\\iTop\\Controller\\Notifications\\ActionController' => $baseDir . '/sources/Controller/Notifications/ActionController.php',
'Combodo\\iTop\\Controller\\Notifications\\NotificationsCenterController' => $baseDir . '/sources/Controller/Notifications/NotificationsCenterController.php',
@@ -1595,8 +1596,6 @@ return array(
'Symfony\\Bridge\\Twig\\Node\\StopwatchNode' => $vendorDir . '/symfony/twig-bridge/Node/StopwatchNode.php',
'Symfony\\Bridge\\Twig\\Node\\TransDefaultDomainNode' => $vendorDir . '/symfony/twig-bridge/Node/TransDefaultDomainNode.php',
'Symfony\\Bridge\\Twig\\Node\\TransNode' => $vendorDir . '/symfony/twig-bridge/Node/TransNode.php',
'Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase' => $vendorDir . '/symfony/twig-bridge/Test/FormLayoutTestCase.php',
'Symfony\\Bridge\\Twig\\Test\\Traits\\RuntimeLoaderProvider' => $vendorDir . '/symfony/twig-bridge/Test/Traits/RuntimeLoaderProvider.php',
'Symfony\\Bridge\\Twig\\TokenParser\\DumpTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/DumpTokenParser.php',
'Symfony\\Bridge\\Twig\\TokenParser\\FormThemeTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/FormThemeTokenParser.php',
'Symfony\\Bridge\\Twig\\TokenParser\\StopwatchTokenParser' => $vendorDir . '/symfony/twig-bridge/TokenParser/StopwatchTokenParser.php',
@@ -2539,13 +2538,6 @@ return array(
'Symfony\\Component\\Form\\SubmitButton' => $vendorDir . '/symfony/form/SubmitButton.php',
'Symfony\\Component\\Form\\SubmitButtonBuilder' => $vendorDir . '/symfony/form/SubmitButtonBuilder.php',
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => $vendorDir . '/symfony/form/SubmitButtonTypeInterface.php',
'Symfony\\Component\\Form\\Test\\FormBuilderInterface' => $vendorDir . '/symfony/form/Test/FormBuilderInterface.php',
'Symfony\\Component\\Form\\Test\\FormIntegrationTestCase' => $vendorDir . '/symfony/form/Test/FormIntegrationTestCase.php',
'Symfony\\Component\\Form\\Test\\FormInterface' => $vendorDir . '/symfony/form/Test/FormInterface.php',
'Symfony\\Component\\Form\\Test\\FormPerformanceTestCase' => $vendorDir . '/symfony/form/Test/FormPerformanceTestCase.php',
'Symfony\\Component\\Form\\Test\\Traits\\RunTestTrait' => $vendorDir . '/symfony/form/Test/Traits/RunTestTrait.php',
'Symfony\\Component\\Form\\Test\\Traits\\ValidatorExtensionTrait' => $vendorDir . '/symfony/form/Test/Traits/ValidatorExtensionTrait.php',
'Symfony\\Component\\Form\\Test\\TypeTestCase' => $vendorDir . '/symfony/form/Test/TypeTestCase.php',
'Symfony\\Component\\Form\\Util\\FormUtil' => $vendorDir . '/symfony/form/Util/FormUtil.php',
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => $vendorDir . '/symfony/form/Util/InheritDataAwareIterator.php',
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => $vendorDir . '/symfony/form/Util/OptionsResolverWrapper.php',
@@ -2843,9 +2835,6 @@ return array(
'Symfony\\Component\\Mailer\\Messenger\\MessageHandler' => $vendorDir . '/symfony/mailer/Messenger/MessageHandler.php',
'Symfony\\Component\\Mailer\\Messenger\\SendEmailMessage' => $vendorDir . '/symfony/mailer/Messenger/SendEmailMessage.php',
'Symfony\\Component\\Mailer\\SentMessage' => $vendorDir . '/symfony/mailer/SentMessage.php',
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailCount' => $vendorDir . '/symfony/mailer/Test/Constraint/EmailCount.php',
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailIsQueued' => $vendorDir . '/symfony/mailer/Test/Constraint/EmailIsQueued.php',
'Symfony\\Component\\Mailer\\Test\\TransportFactoryTestCase' => $vendorDir . '/symfony/mailer/Test/TransportFactoryTestCase.php',
'Symfony\\Component\\Mailer\\Transport' => $vendorDir . '/symfony/mailer/Transport.php',
'Symfony\\Component\\Mailer\\Transport\\AbstractApiTransport' => $vendorDir . '/symfony/mailer/Transport/AbstractApiTransport.php',
'Symfony\\Component\\Mailer\\Transport\\AbstractHttpTransport' => $vendorDir . '/symfony/mailer/Transport/AbstractHttpTransport.php',
@@ -2936,13 +2925,6 @@ return array(
'Symfony\\Component\\Mime\\Part\\SMimePart' => $vendorDir . '/symfony/mime/Part/SMimePart.php',
'Symfony\\Component\\Mime\\Part\\TextPart' => $vendorDir . '/symfony/mime/Part/TextPart.php',
'Symfony\\Component\\Mime\\RawMessage' => $vendorDir . '/symfony/mime/RawMessage.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAddressContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailAddressContains.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAttachmentCount' => $vendorDir . '/symfony/mime/Test/Constraint/EmailAttachmentCount.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHasHeader' => $vendorDir . '/symfony/mime/Test/Constraint/EmailHasHeader.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHeaderSame' => $vendorDir . '/symfony/mime/Test/Constraint/EmailHeaderSame.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHtmlBodyContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailSubjectContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailSubjectContains.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailTextBodyContains' => $vendorDir . '/symfony/mime/Test/Constraint/EmailTextBodyContains.php',
'Symfony\\Component\\OptionsResolver\\Debug\\OptionsResolverIntrospector' => $vendorDir . '/symfony/options-resolver/Debug/OptionsResolverIntrospector.php',
'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => $vendorDir . '/symfony/options-resolver/Exception/AccessException.php',
'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/options-resolver/Exception/ExceptionInterface.php',
@@ -3168,7 +3150,6 @@ return array(
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => $vendorDir . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => $vendorDir . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => $vendorDir . '/symfony/security-core/Signature/SignatureHasher.php',
'Symfony\\Component\\Security\\Core\\Test\\AccessDecisionStrategyTestCase' => $vendorDir . '/symfony/security-core/Test/AccessDecisionStrategyTestCase.php',
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => $vendorDir . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => $vendorDir . '/symfony/security-core/User/ChainUserChecker.php',
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => $vendorDir . '/symfony/security-core/User/ChainUserProvider.php',
@@ -3424,7 +3405,6 @@ return array(
'Symfony\\Component\\Validator\\Mapping\\PropertyMetadataInterface' => $vendorDir . '/symfony/validator/Mapping/PropertyMetadataInterface.php',
'Symfony\\Component\\Validator\\Mapping\\TraversalStrategy' => $vendorDir . '/symfony/validator/Mapping/TraversalStrategy.php',
'Symfony\\Component\\Validator\\ObjectInitializerInterface' => $vendorDir . '/symfony/validator/ObjectInitializerInterface.php',
'Symfony\\Component\\Validator\\Test\\ConstraintValidatorTestCase' => $vendorDir . '/symfony/validator/Test/ConstraintValidatorTestCase.php',
'Symfony\\Component\\Validator\\Util\\PropertyPath' => $vendorDir . '/symfony/validator/Util/PropertyPath.php',
'Symfony\\Component\\Validator\\Validation' => $vendorDir . '/symfony/validator/Validation.php',
'Symfony\\Component\\Validator\\ValidatorBuilder' => $vendorDir . '/symfony/validator/ValidatorBuilder.php',
@@ -3500,7 +3480,6 @@ return array(
'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => $vendorDir . '/symfony/var-dumper/Exception/ThrowingCasterException.php',
'Symfony\\Component\\VarDumper\\Server\\Connection' => $vendorDir . '/symfony/var-dumper/Server/Connection.php',
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => $vendorDir . '/symfony/var-dumper/Server/DumpServer.php',
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => $vendorDir . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
'Symfony\\Component\\VarDumper\\VarDumper' => $vendorDir . '/symfony/var-dumper/VarDumper.php',
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => $vendorDir . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => $vendorDir . '/symfony/var-exporter/Exception/ExceptionInterface.php',
@@ -3855,8 +3834,6 @@ return array(
'Twig\\Source' => $vendorDir . '/twig/twig/src/Source.php',
'Twig\\Template' => $vendorDir . '/twig/twig/src/Template.php',
'Twig\\TemplateWrapper' => $vendorDir . '/twig/twig/src/TemplateWrapper.php',
'Twig\\Test\\IntegrationTestCase' => $vendorDir . '/twig/twig/src/Test/IntegrationTestCase.php',
'Twig\\Test\\NodeTestCase' => $vendorDir . '/twig/twig/src/Test/NodeTestCase.php',
'Twig\\Token' => $vendorDir . '/twig/twig/src/Token.php',
'Twig\\TokenParser\\AbstractTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
'Twig\\TokenParser\\ApplyTokenParser' => $vendorDir . '/twig/twig/src/TokenParser/ApplyTokenParser.php',
@@ -3889,6 +3866,7 @@ return array(
'Twig\\Util\\DeprecationCollector' => $vendorDir . '/twig/twig/src/Util/DeprecationCollector.php',
'Twig\\Util\\ReflectionCallable' => $vendorDir . '/twig/twig/src/Util/ReflectionCallable.php',
'Twig\\Util\\TemplateDirIterator' => $vendorDir . '/twig/twig/src/Util/TemplateDirIterator.php',
'UI' => $baseDir . '/sources/Controller/UI.php',
'UIExtKeyWidget' => $baseDir . '/application/ui.extkeywidget.class.inc.php',
'UIHTMLEditorWidget' => $baseDir . '/application/ui.htmleditorwidget.class.inc.php',
'UILinksWidget' => $baseDir . '/application/ui.linkswidget.class.inc.php',

View File

@@ -28,12 +28,12 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
);
public static $prefixLengthsPsr4 = array (
'T' =>
'T' =>
array (
'Twig\\' => 5,
'TheNetworg\\OAuth2\\Client\\' => 25,
),
'S' =>
'S' =>
array (
'Symfony\\Polyfill\\Php83\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
@@ -82,7 +82,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'ScssPhp\\ScssPhp\\' => 16,
'Sabberworm\\CSS\\' => 15,
),
'P' =>
'P' =>
array (
'Psr\\Log\\' => 8,
'Psr\\Http\\Message\\' => 17,
@@ -93,298 +93,298 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'PhpParser\\' => 10,
'Pelago\\Emogrifier\\' => 18,
),
'L' =>
'L' =>
array (
'League\\OAuth2\\Client\\' => 21,
),
'G' =>
'G' =>
array (
'GuzzleHttp\\Psr7\\' => 16,
'GuzzleHttp\\Promise\\' => 19,
'GuzzleHttp\\' => 11,
),
'F' =>
'F' =>
array (
'Firebase\\JWT\\' => 13,
),
'E' =>
'E' =>
array (
'Egulias\\EmailValidator\\' => 23,
),
'D' =>
'D' =>
array (
'Doctrine\\Common\\Lexer\\' => 22,
),
);
public static $prefixDirsPsr4 = array (
'Twig\\' =>
'Twig\\' =>
array (
0 => __DIR__ . '/..' . '/twig/twig/src',
),
'TheNetworg\\OAuth2\\Client\\' =>
'TheNetworg\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/thenetworg/oauth2-azure/src',
),
'Symfony\\Polyfill\\Php83\\' =>
'Symfony\\Polyfill\\Php83\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php83',
),
'Symfony\\Polyfill\\Mbstring\\' =>
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
),
'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
'Symfony\\Polyfill\\Intl\\Normalizer\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer',
),
'Symfony\\Polyfill\\Intl\\Idn\\' =>
'Symfony\\Polyfill\\Intl\\Idn\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn',
),
'Symfony\\Polyfill\\Intl\\Icu\\' =>
'Symfony\\Polyfill\\Intl\\Icu\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-icu',
),
'Symfony\\Polyfill\\Intl\\Grapheme\\' =>
'Symfony\\Polyfill\\Intl\\Grapheme\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme',
),
'Symfony\\Polyfill\\Ctype\\' =>
'Symfony\\Polyfill\\Ctype\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
),
'Symfony\\Contracts\\Translation\\' =>
'Symfony\\Contracts\\Translation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/translation-contracts',
),
'Symfony\\Contracts\\Service\\' =>
'Symfony\\Contracts\\Service\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/service-contracts',
),
'Symfony\\Contracts\\EventDispatcher\\' =>
'Symfony\\Contracts\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher-contracts',
),
'Symfony\\Contracts\\Cache\\' =>
'Symfony\\Contracts\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache-contracts',
),
'Symfony\\Component\\Yaml\\' =>
'Symfony\\Component\\Yaml\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/yaml',
),
'Symfony\\Component\\VarExporter\\' =>
'Symfony\\Component\\VarExporter\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-exporter',
),
'Symfony\\Component\\VarDumper\\' =>
'Symfony\\Component\\VarDumper\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/var-dumper',
),
'Symfony\\Component\\Validator\\' =>
'Symfony\\Component\\Validator\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/validator',
),
'Symfony\\Component\\String\\' =>
'Symfony\\Component\\String\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/string',
),
'Symfony\\Component\\Stopwatch\\' =>
'Symfony\\Component\\Stopwatch\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/stopwatch',
),
'Symfony\\Component\\Security\\Csrf\\' =>
'Symfony\\Component\\Security\\Csrf\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/security-csrf',
),
'Symfony\\Component\\Security\\Core\\' =>
'Symfony\\Component\\Security\\Core\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/security-core',
),
'Symfony\\Component\\Routing\\' =>
'Symfony\\Component\\Routing\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/routing',
),
'Symfony\\Component\\PropertyInfo\\' =>
'Symfony\\Component\\PropertyInfo\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/property-info',
),
'Symfony\\Component\\PropertyAccess\\' =>
'Symfony\\Component\\PropertyAccess\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/property-access',
),
'Symfony\\Component\\PasswordHasher\\' =>
'Symfony\\Component\\PasswordHasher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/password-hasher',
),
'Symfony\\Component\\OptionsResolver\\' =>
'Symfony\\Component\\OptionsResolver\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/options-resolver',
),
'Symfony\\Component\\Mime\\' =>
'Symfony\\Component\\Mime\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/mime',
),
'Symfony\\Component\\Mailer\\' =>
'Symfony\\Component\\Mailer\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/mailer',
),
'Symfony\\Component\\HttpKernel\\' =>
'Symfony\\Component\\HttpKernel\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-kernel',
),
'Symfony\\Component\\HttpFoundation\\' =>
'Symfony\\Component\\HttpFoundation\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/http-foundation',
),
'Symfony\\Component\\Form\\' =>
'Symfony\\Component\\Form\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/form',
),
'Symfony\\Component\\Finder\\' =>
'Symfony\\Component\\Finder\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/finder',
),
'Symfony\\Component\\Filesystem\\' =>
'Symfony\\Component\\Filesystem\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/filesystem',
),
'Symfony\\Component\\EventDispatcher\\' =>
'Symfony\\Component\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/event-dispatcher',
),
'Symfony\\Component\\ErrorHandler\\' =>
'Symfony\\Component\\ErrorHandler\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/error-handler',
),
'Symfony\\Component\\Dotenv\\' =>
'Symfony\\Component\\Dotenv\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/dotenv',
),
'Symfony\\Component\\DependencyInjection\\' =>
'Symfony\\Component\\DependencyInjection\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/dependency-injection',
),
'Symfony\\Component\\CssSelector\\' =>
'Symfony\\Component\\CssSelector\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/css-selector',
),
'Symfony\\Component\\Console\\' =>
'Symfony\\Component\\Console\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/console',
),
'Symfony\\Component\\Config\\' =>
'Symfony\\Component\\Config\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/config',
),
'Symfony\\Component\\Cache\\' =>
'Symfony\\Component\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/cache',
),
'Symfony\\Bundle\\WebProfilerBundle\\' =>
'Symfony\\Bundle\\WebProfilerBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/web-profiler-bundle',
),
'Symfony\\Bundle\\TwigBundle\\' =>
'Symfony\\Bundle\\TwigBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/twig-bundle',
),
'Symfony\\Bundle\\FrameworkBundle\\' =>
'Symfony\\Bundle\\FrameworkBundle\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/framework-bundle',
),
'Symfony\\Bridge\\Twig\\' =>
'Symfony\\Bridge\\Twig\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/twig-bridge',
),
'Soundasleep\\' =>
'Soundasleep\\' =>
array (
0 => __DIR__ . '/..' . '/soundasleep/html2text/src',
),
'ScssPhp\\ScssPhp\\' =>
'ScssPhp\\ScssPhp\\' =>
array (
0 => __DIR__ . '/..' . '/scssphp/scssphp/src',
),
'Sabberworm\\CSS\\' =>
'Sabberworm\\CSS\\' =>
array (
0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/src',
),
'Psr\\Log\\' =>
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/src',
),
'Psr\\Http\\Message\\' =>
'Psr\\Http\\Message\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-factory/src',
1 => __DIR__ . '/..' . '/psr/http-message/src',
),
'Psr\\Http\\Client\\' =>
'Psr\\Http\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/psr/http-client/src',
),
'Psr\\EventDispatcher\\' =>
'Psr\\EventDispatcher\\' =>
array (
0 => __DIR__ . '/..' . '/psr/event-dispatcher/src',
),
'Psr\\Container\\' =>
'Psr\\Container\\' =>
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
'Psr\\Cache\\' =>
'Psr\\Cache\\' =>
array (
0 => __DIR__ . '/..' . '/psr/cache/src',
),
'PhpParser\\' =>
'PhpParser\\' =>
array (
0 => __DIR__ . '/..' . '/nikic/php-parser/lib/PhpParser',
),
'Pelago\\Emogrifier\\' =>
'Pelago\\Emogrifier\\' =>
array (
0 => __DIR__ . '/..' . '/pelago/emogrifier/src',
),
'League\\OAuth2\\Client\\' =>
'League\\OAuth2\\Client\\' =>
array (
0 => __DIR__ . '/..' . '/league/oauth2-google/src',
1 => __DIR__ . '/..' . '/league/oauth2-client/src',
),
'GuzzleHttp\\Psr7\\' =>
'GuzzleHttp\\Psr7\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
),
'GuzzleHttp\\Promise\\' =>
'GuzzleHttp\\Promise\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/promises/src',
),
'GuzzleHttp\\' =>
'GuzzleHttp\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
),
'Firebase\\JWT\\' =>
'Firebase\\JWT\\' =>
array (
0 => __DIR__ . '/..' . '/firebase/php-jwt/src',
),
'Egulias\\EmailValidator\\' =>
'Egulias\\EmailValidator\\' =>
array (
0 => __DIR__ . '/..' . '/egulias/email-validator/src',
),
'Doctrine\\Common\\Lexer\\' =>
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/src',
),
);
public static $prefixesPsr0 = array (
'C' =>
'C' =>
array (
'Console' =>
'Console' =>
array (
0 => __DIR__ . '/..' . '/pear/console_getopt',
),
),
'A' =>
'A' =>
array (
'Archive_Tar' =>
'Archive_Tar' =>
array (
0 => __DIR__ . '/..' . '/pear/archive_tar',
),
@@ -733,6 +733,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Combodo\\iTop\\Controller\\Base\\Layout\\ObjectController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/ObjectController.php',
'Combodo\\iTop\\Controller\\Base\\Layout\\OqlController' => __DIR__ . '/../..' . '/sources/Controller/Base/Layout/OqlController.php',
'Combodo\\iTop\\Controller\\Links\\LinkSetController' => __DIR__ . '/../..' . '/sources/Controller/Links/LinkSetController.php',
'Combodo\\iTop\\Controller\\Links\\SynchroReplicaController' => __DIR__ . '/../..' . '/sources/Controller/Links/SynchroReplicaController.php',
'Combodo\\iTop\\Controller\\Newsroom\\iTopNewsroomController' => __DIR__ . '/../..' . '/sources/Controller/Newsroom/iTopNewsroomController.php',
'Combodo\\iTop\\Controller\\Notifications\\ActionController' => __DIR__ . '/../..' . '/sources/Controller/Notifications/ActionController.php',
'Combodo\\iTop\\Controller\\Notifications\\NotificationsCenterController' => __DIR__ . '/../..' . '/sources/Controller/Notifications/NotificationsCenterController.php',
@@ -1981,8 +1982,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Bridge\\Twig\\Node\\StopwatchNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/StopwatchNode.php',
'Symfony\\Bridge\\Twig\\Node\\TransDefaultDomainNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/TransDefaultDomainNode.php',
'Symfony\\Bridge\\Twig\\Node\\TransNode' => __DIR__ . '/..' . '/symfony/twig-bridge/Node/TransNode.php',
'Symfony\\Bridge\\Twig\\Test\\FormLayoutTestCase' => __DIR__ . '/..' . '/symfony/twig-bridge/Test/FormLayoutTestCase.php',
'Symfony\\Bridge\\Twig\\Test\\Traits\\RuntimeLoaderProvider' => __DIR__ . '/..' . '/symfony/twig-bridge/Test/Traits/RuntimeLoaderProvider.php',
'Symfony\\Bridge\\Twig\\TokenParser\\DumpTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/DumpTokenParser.php',
'Symfony\\Bridge\\Twig\\TokenParser\\FormThemeTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/FormThemeTokenParser.php',
'Symfony\\Bridge\\Twig\\TokenParser\\StopwatchTokenParser' => __DIR__ . '/..' . '/symfony/twig-bridge/TokenParser/StopwatchTokenParser.php',
@@ -2925,13 +2924,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Form\\SubmitButton' => __DIR__ . '/..' . '/symfony/form/SubmitButton.php',
'Symfony\\Component\\Form\\SubmitButtonBuilder' => __DIR__ . '/..' . '/symfony/form/SubmitButtonBuilder.php',
'Symfony\\Component\\Form\\SubmitButtonTypeInterface' => __DIR__ . '/..' . '/symfony/form/SubmitButtonTypeInterface.php',
'Symfony\\Component\\Form\\Test\\FormBuilderInterface' => __DIR__ . '/..' . '/symfony/form/Test/FormBuilderInterface.php',
'Symfony\\Component\\Form\\Test\\FormIntegrationTestCase' => __DIR__ . '/..' . '/symfony/form/Test/FormIntegrationTestCase.php',
'Symfony\\Component\\Form\\Test\\FormInterface' => __DIR__ . '/..' . '/symfony/form/Test/FormInterface.php',
'Symfony\\Component\\Form\\Test\\FormPerformanceTestCase' => __DIR__ . '/..' . '/symfony/form/Test/FormPerformanceTestCase.php',
'Symfony\\Component\\Form\\Test\\Traits\\RunTestTrait' => __DIR__ . '/..' . '/symfony/form/Test/Traits/RunTestTrait.php',
'Symfony\\Component\\Form\\Test\\Traits\\ValidatorExtensionTrait' => __DIR__ . '/..' . '/symfony/form/Test/Traits/ValidatorExtensionTrait.php',
'Symfony\\Component\\Form\\Test\\TypeTestCase' => __DIR__ . '/..' . '/symfony/form/Test/TypeTestCase.php',
'Symfony\\Component\\Form\\Util\\FormUtil' => __DIR__ . '/..' . '/symfony/form/Util/FormUtil.php',
'Symfony\\Component\\Form\\Util\\InheritDataAwareIterator' => __DIR__ . '/..' . '/symfony/form/Util/InheritDataAwareIterator.php',
'Symfony\\Component\\Form\\Util\\OptionsResolverWrapper' => __DIR__ . '/..' . '/symfony/form/Util/OptionsResolverWrapper.php',
@@ -3229,9 +3221,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Mailer\\Messenger\\MessageHandler' => __DIR__ . '/..' . '/symfony/mailer/Messenger/MessageHandler.php',
'Symfony\\Component\\Mailer\\Messenger\\SendEmailMessage' => __DIR__ . '/..' . '/symfony/mailer/Messenger/SendEmailMessage.php',
'Symfony\\Component\\Mailer\\SentMessage' => __DIR__ . '/..' . '/symfony/mailer/SentMessage.php',
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailCount' => __DIR__ . '/..' . '/symfony/mailer/Test/Constraint/EmailCount.php',
'Symfony\\Component\\Mailer\\Test\\Constraint\\EmailIsQueued' => __DIR__ . '/..' . '/symfony/mailer/Test/Constraint/EmailIsQueued.php',
'Symfony\\Component\\Mailer\\Test\\TransportFactoryTestCase' => __DIR__ . '/..' . '/symfony/mailer/Test/TransportFactoryTestCase.php',
'Symfony\\Component\\Mailer\\Transport' => __DIR__ . '/..' . '/symfony/mailer/Transport.php',
'Symfony\\Component\\Mailer\\Transport\\AbstractApiTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractApiTransport.php',
'Symfony\\Component\\Mailer\\Transport\\AbstractHttpTransport' => __DIR__ . '/..' . '/symfony/mailer/Transport/AbstractHttpTransport.php',
@@ -3322,13 +3311,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Mime\\Part\\SMimePart' => __DIR__ . '/..' . '/symfony/mime/Part/SMimePart.php',
'Symfony\\Component\\Mime\\Part\\TextPart' => __DIR__ . '/..' . '/symfony/mime/Part/TextPart.php',
'Symfony\\Component\\Mime\\RawMessage' => __DIR__ . '/..' . '/symfony/mime/RawMessage.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAddressContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailAddressContains.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailAttachmentCount' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailAttachmentCount.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHasHeader' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailHasHeader.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHeaderSame' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailHeaderSame.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailHtmlBodyContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailHtmlBodyContains.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailSubjectContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailSubjectContains.php',
'Symfony\\Component\\Mime\\Test\\Constraint\\EmailTextBodyContains' => __DIR__ . '/..' . '/symfony/mime/Test/Constraint/EmailTextBodyContains.php',
'Symfony\\Component\\OptionsResolver\\Debug\\OptionsResolverIntrospector' => __DIR__ . '/..' . '/symfony/options-resolver/Debug/OptionsResolverIntrospector.php',
'Symfony\\Component\\OptionsResolver\\Exception\\AccessException' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/AccessException.php',
'Symfony\\Component\\OptionsResolver\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/options-resolver/Exception/ExceptionInterface.php',
@@ -3554,7 +3536,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Security\\Core\\Signature\\Exception\\InvalidSignatureException' => __DIR__ . '/..' . '/symfony/security-core/Signature/Exception/InvalidSignatureException.php',
'Symfony\\Component\\Security\\Core\\Signature\\ExpiredSignatureStorage' => __DIR__ . '/..' . '/symfony/security-core/Signature/ExpiredSignatureStorage.php',
'Symfony\\Component\\Security\\Core\\Signature\\SignatureHasher' => __DIR__ . '/..' . '/symfony/security-core/Signature/SignatureHasher.php',
'Symfony\\Component\\Security\\Core\\Test\\AccessDecisionStrategyTestCase' => __DIR__ . '/..' . '/symfony/security-core/Test/AccessDecisionStrategyTestCase.php',
'Symfony\\Component\\Security\\Core\\User\\AttributesBasedUserProviderInterface' => __DIR__ . '/..' . '/symfony/security-core/User/AttributesBasedUserProviderInterface.php',
'Symfony\\Component\\Security\\Core\\User\\ChainUserChecker' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserChecker.php',
'Symfony\\Component\\Security\\Core\\User\\ChainUserProvider' => __DIR__ . '/..' . '/symfony/security-core/User/ChainUserProvider.php',
@@ -3810,7 +3791,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\Validator\\Mapping\\PropertyMetadataInterface' => __DIR__ . '/..' . '/symfony/validator/Mapping/PropertyMetadataInterface.php',
'Symfony\\Component\\Validator\\Mapping\\TraversalStrategy' => __DIR__ . '/..' . '/symfony/validator/Mapping/TraversalStrategy.php',
'Symfony\\Component\\Validator\\ObjectInitializerInterface' => __DIR__ . '/..' . '/symfony/validator/ObjectInitializerInterface.php',
'Symfony\\Component\\Validator\\Test\\ConstraintValidatorTestCase' => __DIR__ . '/..' . '/symfony/validator/Test/ConstraintValidatorTestCase.php',
'Symfony\\Component\\Validator\\Util\\PropertyPath' => __DIR__ . '/..' . '/symfony/validator/Util/PropertyPath.php',
'Symfony\\Component\\Validator\\Validation' => __DIR__ . '/..' . '/symfony/validator/Validation.php',
'Symfony\\Component\\Validator\\ValidatorBuilder' => __DIR__ . '/..' . '/symfony/validator/ValidatorBuilder.php',
@@ -3886,7 +3866,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Symfony\\Component\\VarDumper\\Exception\\ThrowingCasterException' => __DIR__ . '/..' . '/symfony/var-dumper/Exception/ThrowingCasterException.php',
'Symfony\\Component\\VarDumper\\Server\\Connection' => __DIR__ . '/..' . '/symfony/var-dumper/Server/Connection.php',
'Symfony\\Component\\VarDumper\\Server\\DumpServer' => __DIR__ . '/..' . '/symfony/var-dumper/Server/DumpServer.php',
'Symfony\\Component\\VarDumper\\Test\\VarDumperTestTrait' => __DIR__ . '/..' . '/symfony/var-dumper/Test/VarDumperTestTrait.php',
'Symfony\\Component\\VarDumper\\VarDumper' => __DIR__ . '/..' . '/symfony/var-dumper/VarDumper.php',
'Symfony\\Component\\VarExporter\\Exception\\ClassNotFoundException' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ClassNotFoundException.php',
'Symfony\\Component\\VarExporter\\Exception\\ExceptionInterface' => __DIR__ . '/..' . '/symfony/var-exporter/Exception/ExceptionInterface.php',
@@ -4241,8 +4220,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Twig\\Source' => __DIR__ . '/..' . '/twig/twig/src/Source.php',
'Twig\\Template' => __DIR__ . '/..' . '/twig/twig/src/Template.php',
'Twig\\TemplateWrapper' => __DIR__ . '/..' . '/twig/twig/src/TemplateWrapper.php',
'Twig\\Test\\IntegrationTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/IntegrationTestCase.php',
'Twig\\Test\\NodeTestCase' => __DIR__ . '/..' . '/twig/twig/src/Test/NodeTestCase.php',
'Twig\\Token' => __DIR__ . '/..' . '/twig/twig/src/Token.php',
'Twig\\TokenParser\\AbstractTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/AbstractTokenParser.php',
'Twig\\TokenParser\\ApplyTokenParser' => __DIR__ . '/..' . '/twig/twig/src/TokenParser/ApplyTokenParser.php',
@@ -4275,6 +4252,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'Twig\\Util\\DeprecationCollector' => __DIR__ . '/..' . '/twig/twig/src/Util/DeprecationCollector.php',
'Twig\\Util\\ReflectionCallable' => __DIR__ . '/..' . '/twig/twig/src/Util/ReflectionCallable.php',
'Twig\\Util\\TemplateDirIterator' => __DIR__ . '/..' . '/twig/twig/src/Util/TemplateDirIterator.php',
'UI' => __DIR__ . '/../..' . '/sources/Controller/UI.php',
'UIExtKeyWidget' => __DIR__ . '/../..' . '/application/ui.extkeywidget.class.inc.php',
'UIHTMLEditorWidget' => __DIR__ . '/../..' . '/application/ui.htmleditorwidget.class.inc.php',
'UILinksWidget' => __DIR__ . '/../..' . '/application/ui.linkswidget.class.inc.php',

View File

@@ -36,7 +36,8 @@ if ($issues) {
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
}
}
throw new \RuntimeException(
'Composer detected issues in your platform: ' . implode(' ', $issues)
trigger_error(
'Composer detected issues in your platform: ' . implode(' ', $issues),
E_USER_ERROR
);
}

View File

@@ -9,7 +9,6 @@ use Combodo\iTop\Application\Helper\Session;
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Form\Form;
use Combodo\iTop\Application\UI\Base\Component\GlobalSearch\GlobalSearchHelper;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
@@ -23,6 +22,7 @@ use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Application\WelcomePopup\WelcomePopupService;
use Combodo\iTop\Controller\Base\Layout\ObjectController;
use Combodo\iTop\Controller\Links\SynchroReplicaController;
use Combodo\iTop\Controller\WelcomePopupController;
use Combodo\iTop\Service\Router\Router;
@@ -192,68 +192,6 @@ function DisplaySearchSet($oP, $oFilter, $bSearchForm = true, $sBaseClass = '',
}
}
/**
* Displays a form (checkboxes) to select the objects for which to apply a given action
* Only the objects for which the action is valid can be checked. By default all valid objects are checked
*
* @param WebPage $oP WebPage The page for output
* @param \DBSearch $oFilter DBSearch The filter that defines the list of objects
* @param string $sNextOperation string The next operation (code) to be executed when the form is submitted
* @param ActionChecker $oChecker ActionChecker The helper class/instance used to check for which object the action is valid
* @param array $aExtraFormParams
* @param array $aDisplayParams
*
* @since 3.0.0 $aDisplayParams parameter
*
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \CoreException
*/
function DisplayMultipleSelectionForm(WebPage $oP, DBSearch $oFilter, string $sNextOperation, ActionChecker $oChecker, array $aExtraFormParams = [], array $aDisplayParams = [])
{
$oAppContext = new ApplicationContext();
$iBulkActionAllowed = $oChecker->IsAllowed();
$aExtraParams = ['selection_type' => 'multiple', 'selection_mode' => true, 'display_limit' => false, 'menu' => false];
if ($iBulkActionAllowed == UR_ALLOWED_DEPENDS) {
$aExtraParams['selection_enabled'] = $oChecker->GetAllowedIDs();
} else {
if (UR_ALLOWED_NO) {
throw new ApplicationException(Dict::Format('UI:ActionNotAllowed'));
}
}
$oForm = new Form();
$oForm->SetAction('./UI.php');
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('operation', $sNextOperation));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('class', $oFilter->GetClass()));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('filter', utils::HtmlEntities($oFilter->Serialize())));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('transaction_id', utils::GetNewTransactionId()));
foreach ($aExtraFormParams as $sName => $sValue) {
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden($sName, $sValue));
}
$oForm->AddSubBlock($oAppContext->GetForFormBlock());
$oDisplayBlock = new DisplayBlock($oFilter, 'list', false);
//by default all the elements are selected
$aExtraParams['selectionMode'] = 'negative';
if (array_key_exists('icon', $aDisplayParams) || array_key_exists('title', $aDisplayParams)) {
$aExtraParams['surround_with_panel'] = true;
if (array_key_exists('icon', $aDisplayParams)) {
$aExtraParams['panel_icon'] = $aDisplayParams['icon'];
}
if (array_key_exists('title', $aDisplayParams)) {
$aExtraParams['panel_title'] = $aDisplayParams['title'];
}
}
$oForm->AddSubBlock($oDisplayBlock->GetDisplay($oP, 1, $aExtraParams));
$oToolbarButtons = ToolbarUIBlockFactory::MakeStandard(null);
$oToolbarButtons->AddCSSClass('ibo-toolbar--button');
$oForm->AddSubBlock($oToolbarButtons);
$oToolbarButtons->AddSubBlock(ButtonUIBlockFactory::MakeForCancel(Dict::S('UI:Button:Cancel'), 'cancel')->SetOnClickJsCode('window.history.back()'));
$oToolbarButtons->AddSubBlock(ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Next'), 'next', Dict::S('UI:Button:Next'), true));
$oP->AddUiBlock($oForm);
}
/**
* @param $oP
* @param $aResults
@@ -650,6 +588,23 @@ try {
UI::OperationFormForModifyAll($oP, $oAppContext);
break;
case 'form_for_unlink_all': // Form to modify multiple objects (bulk modify)
SynchroReplicaController::OperationUnlinkAll($oP, $oAppContext,'unlink');
break;
case 'form_for_unlinksynchro_all': // Form to modify multiple objects (bulk modify)
SynchroReplicaController::OperationUnlinkAll($oP, $oAppContext,'unlinksynchro');
break;
case 'form_for_synchro_all': // Form to modify multiple objects (bulk modify)
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
@@ -692,7 +647,7 @@ try {
'title' => Dict::S('UI:BulkDeleteTitle'),
];
$oChecker = new ActionChecker($oFilter, UR_ACTION_BULK_DELETE);
DisplayMultipleSelectionForm($oP, $oFilter, 'bulk_delete', $oChecker, [], $aDisplayParams);
UI::DisplayMultipleSelectionForm($oP, $oFilter, 'bulk_delete', $oChecker, [], $aDisplayParams);
break;
///////////////////////////////////////////////////////////////////////////////////////////
@@ -786,7 +741,7 @@ try {
];
$oChecker = new StimulusChecker($oFilter, $sState, $sStimulus);
$aExtraFormParams = ['stimulus' => $sStimulus, 'state' => $sState];
DisplayMultipleSelectionForm($oP, $oFilter, 'bulk_stimulus', $oChecker, $aExtraFormParams, $aDisplayParams);
UI::DisplayMultipleSelectionForm($oP, $oFilter, 'bulk_stimulus', $oChecker, $aExtraFormParams, $aDisplayParams);
break;
case 'bulk_stimulus':
@@ -1403,99 +1358,3 @@ try {
IssueLog::Debug('UI.php operation='.$sOperationToLog.', error='.$e->getMessage()."\n".$sErrorStackTrace, LogChannels::CONSOLE);
}
class UI
{
/**
* Operation select_for_modify_all
*
* @param iTopWebPage $oP
*
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \OQLException
*/
public static function OperationSelectForModifyAll(iTopWebPage $oP): void
{
$oP->DisableBreadCrumb();
$oP->set_title(Dict::S('UI:ModifyAllPageTitle'));
$sFilter = utils::ReadParam('filter', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
if (empty($sFilter)) {
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'filter'));
}
$oFilter = DBObjectSearch::unserialize($sFilter); //TODO : check that the filter is valid
// Add user filter
$oFilter->UpdateContextFromUser();
$oChecker = new ActionChecker($oFilter, UR_ACTION_BULK_MODIFY);
$sClass = $oFilter->GetClass();
$sClassName = MetaModel::GetName($sClass);
$aDisplayParams = [
'icon' => MetaModel::GetClassIcon($sClass, false),
'title' => Dict::Format('UI:Modify_ObjectsOf_Class', $sClassName),
];
DisplayMultipleSelectionForm($oP, $oFilter, 'form_for_modify_all', $oChecker, [], $aDisplayParams);
}
/**
* Operation form_for_modify_all
*
* @param iTopWebPage $oP
* @param \ApplicationContext $oAppContext
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
* @throws \OQLException
*/
public static function OperationFormForModifyAll(iTopWebPage $oP, ApplicationContext $oAppContext): void
{
$oP->DisableBreadCrumb();
$sFilter = utils::ReadParam('filter', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$sClass = utils::ReadParam('class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
$oFullSetFilter = DBObjectSearch::unserialize($sFilter);
// Add user filter
$oFullSetFilter->UpdateContextFromUser();
$aSelectedObj = utils::ReadMultipleSelection($oFullSetFilter);
$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter).$oAppContext->GetForLink(true);
$aContext = ['filter' => utils::EscapeHtml($sFilter)];
cmdbAbstractObject::DisplayBulkModifyForm($oP, $sClass, $aSelectedObj, 'preview_or_modify_all', $sCancelUrl, [], $aContext);
}
/**
* Operation preview_or_modify_all
*
* @param iTopWebPage $oP
* @param \ApplicationContext $oAppContext
*
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \OQLException
*/
public static function OperationPreviewOrModifyAll(iTopWebPage $oP, ApplicationContext $oAppContext): void
{
$oP->DisableBreadCrumb();
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
$oFilter = DBObjectSearch::unserialize($sFilter); // TO DO : check that the filter is valid
// Add user filter
$oFilter->UpdateContextFromUser();
$sClass = utils::ReadParam('class', '', false, 'class');
$bPreview = utils::ReadParam('preview_mode', '');
$sSelectedObj = utils::ReadParam('selectObj', '', false, 'raw_data');
if (empty($sClass) || empty($sSelectedObj)) { // TO DO: check that the class name is valid !
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'selectObj'));
}
$aSelectedObj = explode(',', $sSelectedObj);
$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter).$oAppContext->GetForLink(true);
$aContext = [
'filter' => utils::EscapeHtml($sFilter),
'selectObj' => $sSelectedObj,
];
cmdbAbstractObject::DoBulkModify($oP, $sClass, $aSelectedObj, 'preview_or_modify_all', $bPreview, $sCancelUrl, $aContext);
}
}

View File

@@ -0,0 +1,138 @@
<?php
namespace Combodo\iTop\Controller\Links;
use ApplicationContext;
use ApplicationException;
use Combodo\iTop\Application\TwigBase\Controller\Controller;
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\DataTable\DataTableUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use DBObjectSearch;
use Dict;
use Exception;
use iTopWebPage;
use MetaModel;
use utils;
class SynchroReplicaController extends Controller
{
public const ROUTE_NAMESPACE = 'synchroreplica';
public function __construct($sViewPath = '', $sModuleName = 'core', $aAdditionalPaths = [])
{
$sViewPath = APPROOT.'synchro';
parent::__construct($sViewPath, $sModuleName, $aAdditionalPaths);
// Previously in index.php
$this->DisableInDemoMode();
$this->AllowOnlyAdmin();
$this->CheckAccess();
}
public static function OperationUnlinkAll(iTopWebPage $oP, ApplicationContext $oAppContext, $sOperation = 'unlink'): void
{
$oP->DisableBreadCrumb();
$sClass = utils::ReadParam('class', '', false, 'class');
$sFilter = utils::ReadPostedParam('filter', '', 'raw_data');
$oFullSetFilter = DBObjectSearch::unserialize($sFilter);
// Add user filter
$oFullSetFilter->UpdateContextFromUser();
$aSelectObject = utils::ReadMultipleSelection($oFullSetFilter);
if ( empty($sClass) || empty($aSelectObject)) // TO DO: check that the class name is valid !
{
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'selectObject[]'));
}
$sCancelUrl = "./UI.php?operation=search&filter=".urlencode($sFilter)."&".$oAppContext->GetForLink();
$aContext = array(
'filter' => utils::EscapeHtml($sFilter),
'selectObj' => $aSelectObject,
);
$aHeaders = array(
'object' => array('label' => MetaModel::GetName($sClass), 'description' => Dict::S('UI:ModifiedObject')),
'status' => array(
'label' => Dict::S('UI:BulkModifyStatus'),
'description' => Dict::S('UI:BulkModifyStatus+'),
),
'errors' => array(
'label' => Dict::S('UI:BulkModifyErrors'),
'description' => Dict::S('UI:BulkModifyErrors+'),
),
);
$aRows = array();
$sHeaderTitle = Dict::Format('UI:Modify_N_ObjectsOf_Class', count($aSelectObject), MetaModel::GetName($sClass));
$sClassIcon = MetaModel::GetClassIcon($sClass, false);
// Not in preview mode, do the update for real
$sTransactionId = utils::ReadPostedParam('transaction_id', '', 'transaction_id');
if (!utils::IsTransactionValid($sTransactionId, false)) {
throw new Exception(Dict::S('UI:Error:ObjectAlreadyUpdated'));
}
utils::RemoveTransaction($sTransactionId);
// Avoid too many events
$iPreviousTimeLimit = ini_get('max_execution_time');
$iLoopTimeLimit = MetaModel::GetConfig()->Get('max_execution_time_per_loop');
$aErrors = [];
foreach ($aSelectObject as $iId) {
set_time_limit(intval($iLoopTimeLimit));
/** @var \cmdbAbstractObject $oObj */
$oReplica = MetaModel::GetObject('SynchroReplica', $iId);
$bResult = true;
try {
if (in_array($sOperation, ['unlink', 'unlinksynchro'])) {
$oReplica->UnLink();
}
if (in_array($sOperation, ['synchro', 'unlinksynchro'])) {
$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;
$aErrors[] = $e->getMessage();
}
catch (Error $e) {
$bResult = false;
$aErrors[] = $e->getMessage();
}
$sStatus = $bResult ? Dict::S('UI:BulkModifyStatusModified') : Dict::S('UI:BulkModifyStatusSkipped');
$aErrorsToDisplay = array_map(function ($sError) {
return utils::HtmlEntities($sError);
}, $aErrors);
$aRows[] = array(
'object' => $oReplica->GetHyperlink(),
'status' => $sStatus,
'errors' => '<p>'.($bResult ? '' : implode('</p><p>', $aErrorsToDisplay)).'</p>',
);
}
set_time_limit(intval($iPreviousTimeLimit));
$oTable = DataTableUIBlockFactory::MakeForForm('BulkModify', $aHeaders, $aRows);
$oTable->AddOption("bFullscreen", true);
$oPanel = PanelUIBlockFactory::MakeForClass($sClass, '');
$oPanel->SetIcon($sClassIcon);
$oPanel->SetTitle($sHeaderTitle);
$oPanel->AddCSSClass('ibo-datatable-panel');
$oPanel->AddSubBlock($oTable);
$oP->AddUiBlock($oPanel);
$oP->AddSubBlock(ButtonUIBlockFactory::MakeForSecondaryAction(Dict::S('UI:Button:Done')))->SetOnClickJsCode("window.location.href='$sCancelUrl'")->AddCSSClass('mt-5');
}
}

166
sources/Controller/UI.php Normal file
View File

@@ -0,0 +1,166 @@
<?php
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Form\Form;
use Combodo\iTop\Application\UI\Base\Component\Input\InputUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
use Combodo\iTop\Application\WebPage\iTopWebPage;
use Combodo\iTop\Application\WebPage\WebPage;
class UI
{
/**
* Operation select_for_modify_all
*
* @param iTopWebPage $oP
*
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \OQLException
*/
public static function OperationSelectForModifyAll(iTopWebPage $oP, $sTitleTab = 'UI:ModifyAllPageTitle', $sTitleCode = 'UI:Modify_ObjectsOf_Class', $sNextOperation = 'form_for_modify_all'): void
{
$oP->DisableBreadCrumb();
$oP->set_title(Dict::S($sTitleTab));
$sFilter = utils::ReadParam('filter', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
if (empty($sFilter)) {
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'filter'));
}
$oFilter = DBObjectSearch::unserialize($sFilter); //TODO : check that the filter is valid
// Add user filter
$oFilter->UpdateContextFromUser();
$oChecker = new ActionChecker($oFilter, UR_ACTION_BULK_MODIFY);
$sClass = $oFilter->GetClass();
$sClassName = MetaModel::GetName($sClass);
$aDisplayParams = [
'icon' => MetaModel::GetClassIcon($sClass, false),
'title' => Dict::Format($sTitleCode, $sClassName),
];
self::DisplayMultipleSelectionForm($oP, $oFilter, $sNextOperation, $oChecker, [], $aDisplayParams);
}
/**
* Operation form_for_modify_all
*
* @param iTopWebPage $oP
* @param \ApplicationContext $oAppContext
*
* @throws \ArchivedObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \MySQLException
* @throws \OQLException
*/
public static function OperationFormForModifyAll(iTopWebPage $oP, ApplicationContext $oAppContext): void
{
$oP->DisableBreadCrumb();
$sFilter = utils::ReadParam('filter', '', false, utils::ENUM_SANITIZATION_FILTER_RAW_DATA);
$sClass = utils::ReadParam('class', '', false, utils::ENUM_SANITIZATION_FILTER_CLASS);
$oFullSetFilter = DBObjectSearch::unserialize($sFilter);
// Add user filter
$oFullSetFilter->UpdateContextFromUser();
$aSelectedObj = utils::ReadMultipleSelection($oFullSetFilter);
$sCancelUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&filter=' . urlencode($sFilter) . '&' . $oAppContext->GetForLink();
$aContext = array('filter' => utils::EscapeHtml($sFilter));
cmdbAbstractObject::DisplayBulkModifyForm($oP, $sClass, $aSelectedObj, 'preview_or_modify_all', $sCancelUrl, array(), $aContext);
}
/**
* Operation preview_or_modify_all
*
* @param iTopWebPage $oP
* @param \ApplicationContext $oAppContext
*
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \DictExceptionMissingString
* @throws \OQLException
*/
public static function OperationPreviewOrModifyAll(iTopWebPage $oP, ApplicationContext $oAppContext): void
{
$oP->DisableBreadCrumb();
$sFilter = utils::ReadParam('filter', '', false, 'raw_data');
$oFilter = DBObjectSearch::unserialize($sFilter); // TO DO : check that the filter is valid
// Add user filter
$oFilter->UpdateContextFromUser();
$sClass = utils::ReadParam('class', '', false, 'class');
$bPreview = utils::ReadParam('preview_mode', '');
$sSelectedObj = utils::ReadParam('selectObj', '', false, 'raw_data');
if (empty($sClass) || empty($sSelectedObj)) // TO DO: check that the class name is valid !
{
throw new ApplicationException(Dict::Format('UI:Error:2ParametersMissing', 'class', 'selectObj'));
}
$aSelectedObj = explode(',', $sSelectedObj);
$sCancelUrl = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?operation=search&filter=' . urlencode($sFilter) . '&' . $oAppContext->GetForLink();
$aContext = array(
'filter' => utils::EscapeHtml($sFilter),
'selectObj' => $sSelectedObj,
);
cmdbAbstractObject::DoBulkModify($oP, $sClass, $aSelectedObj, 'preview_or_modify_all', $bPreview, $sCancelUrl, $aContext);
}/**
* Displays a form (checkboxes) to select the objects for which to apply a given action
* Only the objects for which the action is valid can be checked. By default all valid objects are checked
*
* @param WebPage $oP WebPage The page for output
* @param \DBSearch $oFilter DBSearch The filter that defines the list of objects
* @param string $sNextOperation string The next operation (code) to be executed when the form is submitted
* @param ActionChecker $oChecker ActionChecker The helper class/instance used to check for which object the action is valid
* @param array $aExtraFormParams
* @param array $aDisplayParams
*
* @throws \ApplicationException
* @throws \ArchivedObjectException
* @throws \CoreException
*@since 3.0.0 $aDisplayParams parameter
*
*/
public static function DisplayMultipleSelectionForm(WebPage $oP, DBSearch $oFilter, string $sNextOperation, ActionChecker $oChecker, array $aExtraFormParams = [], array $aDisplayParams = [])
{
$oAppContext = new ApplicationContext();
$iBulkActionAllowed = $oChecker->IsAllowed();
$aExtraParams = ['selection_type' => 'multiple', 'selection_mode' => true, 'display_limit' => false, 'menu' => false];
if ($iBulkActionAllowed == UR_ALLOWED_DEPENDS) {
$aExtraParams['selection_enabled'] = $oChecker->GetAllowedIDs();
} else {
if (UR_ALLOWED_NO) {
throw new ApplicationException(Dict::Format('UI:ActionNotAllowed'));
}
}
$oForm = new Form();
$oForm->SetAction( utils::GetAbsoluteUrlAppRoot().'pages/UI.php');
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('operation', $sNextOperation));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('class', $oFilter->GetClass()));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('filter', utils::HtmlEntities($oFilter->Serialize())));
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden('transaction_id', utils::GetNewTransactionId()));
foreach ($aExtraFormParams as $sName => $sValue) {
$oForm->AddSubBlock(InputUIBlockFactory::MakeForHidden($sName, $sValue));
}
$oForm->AddSubBlock($oAppContext->GetForFormBlock());
$oDisplayBlock = new DisplayBlock($oFilter, 'list', false);
//by default all the elements are selected
$aExtraParams['selectionMode'] = 'negative';
if (array_key_exists('icon', $aDisplayParams) || array_key_exists('title', $aDisplayParams)) {
$aExtraParams['surround_with_panel'] = true;
if (array_key_exists('icon', $aDisplayParams)) {
$aExtraParams['panel_icon'] = $aDisplayParams['icon'];
}
if (array_key_exists('title', $aDisplayParams)) {
$aExtraParams['panel_title'] = $aDisplayParams['title'];
}
}
$oForm->AddSubBlock($oDisplayBlock->GetDisplay($oP, 1, $aExtraParams));
$oToolbarButtons = ToolbarUIBlockFactory::MakeStandard(null);
$oToolbarButtons->AddCSSClass('ibo-toolbar--button');
$oForm->AddSubBlock($oToolbarButtons);
$oToolbarButtons->AddSubBlock(ButtonUIBlockFactory::MakeForCancel(Dict::S('UI:Button:Cancel'), 'cancel')->SetOnClickJsCode('window.history.back()'));
$oToolbarButtons->AddSubBlock(ButtonUIBlockFactory::MakeForPrimaryAction(Dict::S('UI:Button:Next'), 'next', Dict::S('UI:Button:Next'), true));
$oP->AddUiBlock($oForm);
}
}

View File

@@ -114,4 +114,8 @@ class AttributeObjectKey extends AttributeDBFieldVoid
return (int)$proposedValue;
}
public function GetTargetClass($iType = EXTKEY_RELATIVE)
{
return '';
}
}

View File

@@ -18,7 +18,10 @@
* 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;
require_once('../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php');
@@ -34,6 +37,7 @@ $oP = new iTopWebPage("iTop - Synchro Replicas");
// Main program
$sOperation = utils::ReadParam('operation', 'details');
try {
switch ($sOperation) {
case 'details':
@@ -46,21 +50,23 @@ 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()).'</a>');
//$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, ['menu' => false, 'table_id' => '1']);
$oBlock1 = new DisplayBlock($oFilter, 'search', false, ['menu' => true, 'table_id' => '1']);
$oBlock1->Display($oP, 0);
$oP->add('<p class="page-header">'.MetaModel::GetClassIcon('SynchroReplica').Dict::S('Core:SynchroReplica:ListOfReplicas').'</p>');
$iSourceId = utils::ReadParam('datasource', null);
if ($iSourceId != null) {
$oSource = MetaModel::GetObject('SynchroDataSource', $iSourceId);
$oP->p(Dict::Format('Core:SynchroReplica:BackToDataSource', $oSource->GetHyperlink()).'</a>');
}
$oBlock = new DisplayBlock($oFilter, 'list', false, ['menu' => false]);
$oBlock->Display($oP, 1);
break;
case 'delete':
@@ -69,6 +75,81 @@ try {
$sDelete = utils::GetAbsoluteUrlAppRoot().'pages/UI.php?'.$_SERVER['QUERY_STRING'];
header("Location: $sDelete");
break;
case 'unlinksynchro':
$iId = utils::ReadParam('id', null);
if ($iId == null) {
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id'));
}
$oReplica = MetaModel::GetObject('SynchroReplica', $iId);
$oReplica->UnLink();
$oStatLog = $oReplica->ReSynchro();
$oP->add(implode('<br>', $oStatLog->GetTraces()));
$oReplica->DisplayDetails($oP);
break;
case 'unlink':
$iId = utils::ReadParam('id', null);
if ($iId == null) {
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id'));
}
$oReplica = MetaModel::GetObject('SynchroReplica', $iId);
$oReplica->UnLink();
$oReplica->DisplayDetails($oP);
break;
case 'synchro':
$iId = utils::ReadParam('id', null);
if ($iId == null) {
throw new ApplicationException(Dict::Format('UI:Error:1ParametersMissing', 'id'));
}
$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)
UI::OperationSelectForModifyAll($oP,'UI:UnlinkAllTabTitle', 'UI:UnlinkAllPageTitle', 'form_for_unlink_all');
break;
case 'select_for_unlinksynchro_all': // Select the list of objects to be modified (bulk modify)
UI::OperationSelectForModifyAll($oP,'UI:UnlinkSynchroAllTabTitle', 'UI:UnlinkSynchroAllPageTitle', 'form_for_unlinksynchro_all');
break;
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) {
$oP->p('<b>An error occured while running the query:</b>');

View File

@@ -6,6 +6,12 @@
*/
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Application\UI\Base\Component\Button\ButtonUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\PopoverMenu\PopoverMenu;
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Toolbar\ToolbarUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\UIContentBlockUIBlockFactory;
use Combodo\iTop\Core\CMDBChange\CMDBChangeOrigin;
class SynchroDataSource extends cmdbAbstractObject
{
@@ -2108,6 +2114,12 @@ class SynchroReplica extends DBObject implements iDisplay
// MetaModel::Init_SetZListItems('advanced_search', array('name')); // Criteria of the advanced search form
}
public function InitExtendedData($oSource)
{
$sSQLTable = $oSource->GetDataTable();
$this->m_aExtendedData = $this->LoadExtendedDataFromTable($sSQLTable);
}
public function __construct($aRow = null, $sClassAlias = '', $aAttToLoad = null, $aExtendedDataSpec = null)
{
parent::__construct($aRow, $sClassAlias, $aAttToLoad, $aExtendedDataSpec);
@@ -2189,6 +2201,16 @@ class SynchroReplica extends DBObject implements iDisplay
$this->Set('status_last_error', $sText);
}
/*
* Disassociate the replica from the destination object and set the status to "new" to be synchronized with the next operation
*/
public function UnLink(){
$this->Set('dest_id', '');
$this->Set('dest_class', '');
$this->Set('status', 'new');
$this->DBWrite();
}
public function Synchro($oDataSource, $aReconciliationKeys, $aAttributes, $oChange, &$oStatLog)
{
$oStatLog->AddTrace(">>> Beginning of SynchroReplica::Synchro, replica status is '".$this->Get('status')."'.", $this);
@@ -2365,6 +2387,89 @@ class SynchroReplica extends DBObject implements iDisplay
$oStatLog->AddTrace('<<< End of SynchroReplica::Synchro.', $this);
}
/**
*
* @return \SynchroLog
* @throws \ArchivedObjectException
* @throws \CoreCannotSaveObjectException
* @throws \CoreException
* @throws \CoreUnexpectedValue
* @throws \CoreWarning
* @throws \MySQLException
* @throws \OQLException
* @throws \SynchroExceptionNotStarted
*/
public function ReSynchro(): SynchroLog
{
$oDataSource = MetaModel::GetObject('SynchroDataSource', $this->Get('sync_source_id'));
$oStatLog = new SynchroLog();
$oStatLog->Set('sync_source_id', $oDataSource->GetKey());
$oStatLog->Set('start_date', time());
$oStatLog->Set('status', 'running');
$oStatLog->AddTrace('Manual synchro');
// Get the list of SQL columns
$aAttCodesExpected = array();
$aAttCodesToReconcile = array();
$aAttCodesToUpdate = array();
$sSelectAtt = 'SELECT SynchroAttribute WHERE sync_source_id = :source_id AND (update = 1 OR reconcile = 1)';
$oSetAtt = new DBObjectSet(DBObjectSearch::FromOQL($sSelectAtt), array() /* order by*/, array('source_id' => $oDataSource->GetKey()) /* aArgs */);
while ($oSyncAtt = $oSetAtt->Fetch()) {
if ($oSyncAtt->Get('update')) {
$aAttCodesToUpdate[$oSyncAtt->Get('attcode')] = $oSyncAtt;
}
if ($oSyncAtt->Get('reconcile')) {
$aAttCodesToReconcile[$oSyncAtt->Get('attcode')] = $oSyncAtt;
}
$aAttCodesExpected[$oSyncAtt->Get('attcode')] = $oSyncAtt;
}
// Get the list of attributes, determine reconciliation keys and update targets
//
if ($oDataSource->Get('reconciliation_policy') == 'use_attributes') {
$aReconciliationKeys = $aAttCodesToReconcile;
} elseif ($oDataSource->Get('reconciliation_policy') == 'use_primary_key') {
// Override the settings made at the attribute level !
$aReconciliationKeys = array('primary_key' => null);
}
if (count($aAttCodesToUpdate) == 0) {
$oStatLog->AddTrace('No attribute to update');
throw new SynchroExceptionNotStarted('There is no attribute to update');
}
if (count($aReconciliationKeys) == 0) {
$oStatLog->AddTrace('No attribute for reconciliation');
throw new SynchroExceptionNotStarted('No attribute for reconciliation');
}
$aAttributesToUpdate = array();
foreach ($aAttCodesToUpdate as $sAttCode => $oSyncAtt) {
$oAttDef = MetaModel::GetAttributeDef($oDataSource->GetTargetClass(), $sAttCode);
if ($oAttDef->IsWritable()) {
$aAttributesToUpdate[$sAttCode] = $oSyncAtt;
}
}
// Create a change used for logging all the modifications/creations happening during the synchro
$oChange = MetaModel::NewObject('CMDBChange');
$oChange->Set('date', time());
$sUserString = CMDBChange::GetCurrentUserName();
$oChange->Set('userinfo', $sUserString.' '.Dict::S('Core:SyncDataExchangeComment'));
$oChange->Set('origin', CMDBChangeOrigin::SYNCHRO_DATA_SOURCE);
$oChange->DBInsert();
CMDBObject::SetCurrentChange($oChange);
$this->InitExtendedData($oDataSource);
$this->Synchro($oDataSource, $aReconciliationKeys, $aAttributesToUpdate, $oChange, $oStatLog);
$this->DBUpdate();
return $oStatLog;
}
/**
* Updates the destination object with the Extended data found in the synchro_data_XXXX table
*
@@ -2681,14 +2786,119 @@ class SynchroReplica extends DBObject implements iDisplay
public function DisplayDetails(WebPage $oPage, $bEditMode = false)
{
// Object's details
//$this->DisplayBareHeader($oPage, $bEditMode);
$this->DisplayBareHeader($oPage, $bEditMode);
$oPage->AddTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
$oPage->SetCurrentTab('UI:PropertiesTab');
$this->DisplayBareProperties($oPage, $bEditMode);
}
public function DisplayBareHeader(WebPage $oPage, $bEditMode = false)
{
$oBlock = UIContentBlockUIBlockFactory::MakeStandard('title-for-replica', ['ibo-page-header--replica-title']);
$oPage->AddSubBlock($oBlock);
$oPage->add_style('.ibo-page-header--replica-title{ display: table; width: 100%;}');
$oPage->add_style('.ibo-page-header--replica-title>.ibo-toolbar--button{ display: table-cell; vertical-align:middle;}');
public function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = [])
$sId = $this->GetKey();
$oTitle = TitleUIBlockFactory::MakeNeutral(Dict::S('Class:SynchroReplica'));
$oBlock->AddSubBlock($oTitle);
$oActionsToolbar = ToolbarUIBlockFactory::MakeForButton(MenuBlock::ACTIONS_TOOLBAR_ID_PREFIX.$sId);
$oActionsToolbar->AddCSSClass('ibo-panel--toolbar');
$oBlock->AddSubBlock($oActionsToolbar);
$sClass = get_class($this);
$sRootUrl = utils::GetAbsoluteUrlAppRoot();
$sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass);
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink();
if (utils::IsNotNullOrEmptyString($sContext)) {
$sContext = '&'.$sContext;
}
$aActions = [];
//Delete
if (UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE)) {
$aActions['UI:Menu:Delete'] = array(
'label' => Dict::S('UI:Menu:Delete'),
'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$sId{$sContext}",
'tooltip' => Dict::S('Class:SynchroReplica/Action:delete+'),
);
}
if (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY)) {
if (count($aActions) > 0) {
$sSeparator = '<hr class="menu-separator"/>';
$aActions['sep_0'] = array('label' => $sSeparator, 'url' => '');
}
$sUrl = "{$sRootUrl}synchro/replica.php?operation=unlink&class=$sClass&id=$sId{$sContext}";
$aActions['Class:SynchroReplica/Action:unlink'] = [
'label' => Dict::S('Class:SynchroReplica/Action:unlink'),
'url' => $sUrl,
'tooltip' => Dict::S('Class:SynchroReplica/Action:unlink+'),
];
$sUrl = "{$sRootUrl}synchro/replica.php?operation=unlinksynchro&class=$sClass&id=$sId{$sContext}";
$aActions['Class:SynchroReplica/Action:unlinksynchro'] = [
'label' => Dict::S('Class:SynchroReplica/Action:unlinksynchro'),
'url' => $sUrl,
'tooltip' => Dict::S('Class:SynchroReplica/Action:unlinksynchro+'),
];
$sUrl = "{$sRootUrl}synchro/replica.php?operation=synchro&class=$sClass&id=$sId{$sContext}";
$aActions['Class:SynchroReplica/Action:synchro'] = [
'label' => Dict::S('Class:SynchroReplica/Action:synchro'),
'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}";
$sRegularActionsPopoverMenuId = "ibo-regular-actions-popover-{$sId}";
$oActionButton = ButtonUIBlockFactory::MakeIconAction('fas fa-ellipsis-v', Dict::S('UI:Menu:Actions'), 'UI:Menu:Actions', '', false, $sRegularActionsMenuTogglerId)
->AddCSSClasses(['ibo-action-button', 'ibo-regular-action-button']);
$oRegularActionsMenu = $oPage->GetPopoverMenu($sRegularActionsPopoverMenuId, $aActions)
->SetTogglerJSSelector("#$sRegularActionsMenuTogglerId")
->SetContainer(PopoverMenu::ENUM_CONTAINER_BODY);
$oActionsToolbar->AddSubBlock($oActionButton)
->AddSubBlock($oRegularActionsMenu);
$oActionButton = ButtonUIBlockFactory::MakeIconLink('fas fa-search', Dict::Format('UI:SearchFor_Class', MetaModel::GetName($sClass)), "{$sRootUrl}pages/UI.php?operation=search_form&do_search=0&class=$sClass{$sContext}", '', 'UI:SearchFor_Class');
$oActionButton->AddCSSClasses(['ibo-action-button', 'ibo-regular-action-button']);
$oActionsToolbar->AddSubBlock($oActionButton);
}
$sUrl = "{$sRootUrl}pages/$sUIPage?operation=display&class=$sClass&id=$sId{$sContext}";
$oActionButton = ButtonUIBlockFactory::MakeAlternativeNeutral('', 'UI:Button:Refresh');
$oActionButton->SetIconClass('fas fa-sync-alt')
->SetOnClickJsCode('window.location.href=\''.$sUrl.'\'')
->SetTooltip(Dict::S('UI:Button:Refresh'))
->AddCSSClasses(['ibo-action-button', 'ibo-regular-action-button']);
$oActionsToolbar->AddSubBlock($oActionButton);
return $oBlock;
}
public function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
{
if ($bEditMode) {
return;