diff --git a/pages/UI.php b/pages/UI.php index 675ec5ba9..855fbdd68 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -127,6 +127,72 @@ function SetObjectBreadCrumbEntry(DBObject $oObj, WebPage $oPage) $oPage->SetBreadCrumbEntry("ui-details-$sClass-".$oObj->GetKey(), $oObj->Get('friendlyname'), MetaModel::GetName($sClass).': '.$oObj->Get('friendlyname'), '', $sIcon, $sIconType); } +/** + * Displays the result of a search request + * @param $oP WebPage Web page for the output + * @param $oFilter DBSearch The search of objects to display + * @param $bSearchForm boolean Whether or not to display the search form at the top the page + * @param $sBaseClass string The base class for the search (can be different from the actual class of the results) + * @param $sFormat string The format to use for the output: csv or html + * @param $bDoSearch bool True to display the search results below the search form + * @param $bSearchFormOpen bool True to display the search form fully expanded (only if $bSearchForm of course) + * @throws \CoreException + * @throws \DictExceptionMissingString + */ +function DisplaySearchSet($oP, $oFilter, $bSearchForm = true, $sBaseClass = '', $sFormat = '', $bDoSearch = true, $bSearchFormOpen = true, $aParams = []) +{ + //search block + $oBlockForm = null; + if ($bSearchForm) { + $aParams['open'] = $bSearchFormOpen; + if (false === isset($aParams['table_id'])) { + $aParams['table_id'] = 'result_1'; + } + if (!empty($sBaseClass)) { + $aParams['baseClass'] = $sBaseClass; + } + $oBlockForm = new DisplayBlock($oFilter, 'search', false /* Asynchronous */, $aParams); + + if (!$bDoSearch) { + $oBlockForm->Display($oP, 0); + } + } + if ($bDoSearch) { + if (strtolower($sFormat) == 'csv') { + $oBlock = new DisplayBlock($oFilter, 'csv', false); + // Adjust the size of the Textarea containing the CSV to fit almost all the remaining space + $oP->add_ready_script(" $('#1>textarea').height($('#1').parent().height() - $('#0').outerHeight() - 30).width( $('#1').parent().width() - 20);"); // adjust the size of the block + } else { + $oBlock = new DisplayBlock($oFilter, 'list', false); + + // Breadcrumb + //$iCount = $oBlock->GetDisplayedCount(); + $sPageId = "ui-search-".$oFilter->GetClass(); + $sLabel = MetaModel::GetName($oFilter->GetClass()); + $oP->SetBreadCrumbEntry($sPageId, $sLabel, '', '', 'fas fa-search', iTopWebPage::ENUM_BREADCRUMB_ENTRY_ICON_TYPE_CSS_CLASSES); + } + if ($bSearchForm) { + //add search block + $sTableId = utils::ReadParam('_table_id_', null, false, 'raw_data'); + if ($sTableId == '') { + $sTableId = 'result_1'; + } + $aExtraParams['table_id'] = $sTableId; + $aExtraParams['submit_on_load'] = false; + $oUIBlockForm = $oBlockForm->GetDisplay($oP, 'search_1', $aExtraParams); + //add result block + $oUIBlock = $oBlock->GetDisplay($oP, $sTableId); + $oUIBlock->AddCSSClasses(['display_block', 'sf_results_area']); + $oUIBlock->AddDataAttribute('target', 'search_results'); + //$oUIBlockForm->AddSubBlock($oUIBlock); + $oP->AddUiBlock($oUIBlockForm); + $oUIBlockForm->AddSubBlock($oUIBlock); + } else { + $oBlock->Display($oP, 1); + } + } +} + /** * 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 @@ -738,7 +804,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': @@ -1355,99 +1421,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); - } -} diff --git a/sources/Controller/UI.php b/sources/Controller/UI.php index 12edaea60..feda12231 100644 --- a/sources/Controller/UI.php +++ b/sources/Controller/UI.php @@ -9,64 +9,63 @@ use Combodo\iTop\Application\WebPage\WebPage; class UI { - - /** - * Operation select_for_modify_all - * - * @param iTopWebPage $oP - * - * @throws \ApplicationException - * @throws \ArchivedObjectException - * @throws \CoreException - * @throws \OQLException - */ + /** + * 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->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); + $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), + $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); + /** + * 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 @@ -104,64 +103,64 @@ class UI ); 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 + * 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 = array('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')); + { + $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 = 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']; + $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)); } - if (array_key_exists('title', $aDisplayParams)) { - $aExtraParams['panel_title'] = $aDisplayParams['title']; + $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)); + $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); -} + $oP->AddUiBlock($oForm); + } } \ No newline at end of file diff --git a/sources/Core/AttributeDefinition/AttributeObjectKey.php b/sources/Core/AttributeDefinition/AttributeObjectKey.php index 122c48909..1d62a6171 100644 --- a/sources/Core/AttributeDefinition/AttributeObjectKey.php +++ b/sources/Core/AttributeDefinition/AttributeObjectKey.php @@ -114,4 +114,8 @@ class AttributeObjectKey extends AttributeDBFieldVoid return (int)$proposedValue; } + public function GetTargetClass($iType = EXTKEY_RELATIVE) + { + return ''; + } } diff --git a/synchro/replica.php b/synchro/replica.php index 92a23d2f9..443123d2a 100644 --- a/synchro/replica.php +++ b/synchro/replica.php @@ -65,16 +65,8 @@ try { 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(''); - $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, ['menu' => false]); - $oBlock->Display($oP, 1); break; case 'delete':