diff --git a/application/displayblock.class.inc.php b/application/displayblock.class.inc.php index f1e5a6f15..ff0d4af0a 100644 --- a/application/displayblock.class.inc.php +++ b/application/displayblock.class.inc.php @@ -1567,244 +1567,308 @@ class MenuBlock extends DisplayBlock { $this->m_sStyle = 'list'; } - $oAppContext = new ApplicationContext(); - $sContext = $oAppContext->GetForLink(); - if (!empty($sContext)) { - $sContext = '&'.$sContext; - } $sClass = $this->m_oFilter->GetClass(); - $oReflectionClass = new ReflectionClass($sClass); $oSet = new CMDBObjectSet($this->m_oFilter); - $sFilter = $this->m_oFilter->serialize(); - $aActions = []; - $sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass); - $sRootUrl = utils::GetAbsoluteUrlAppRoot(); - // Common params that will be applied to actions - $aActionParams = array(); - if (isset($aExtraParams['menu_actions_target'])) { - $aActionParams['target'] = $aExtraParams['menu_actions_target']; - } - // 1:n links, populate the target object as a default value when creating a new linked object - if (isset($aExtraParams['target_attr'])) { - $aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id']; - } - $sDefault = ''; - if (!empty($aExtraParams['default'])) { - foreach ($aExtraParams['default'] as $sKey => $sValue) { - $sDefault .= "&default[$sKey]=$sValue"; - } - } - $bIsCreationAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_CREATE) == UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); $sRefreshAction = ''; - switch ($oSet->Count()) { - case 0: - // No object in the set, the only possible action is "new" - if ($bIsCreationAllowed) { - $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}") + $aActionParams; + if (!isset($aExtraParams['selection_mode']) || $aExtraParams['selection_mode'] == "") { + $oAppContext = new ApplicationContext(); + $sContext = $oAppContext->GetForLink(); + if (!empty($sContext)) { + $sContext = '&'.$sContext; + } + $oReflectionClass = new ReflectionClass($sClass); + $sFilter = $this->m_oFilter->serialize(); + $aActions = []; + $sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass); + $sRootUrl = utils::GetAbsoluteUrlAppRoot(); + // Common params that will be applied to actions + $aActionParams = array(); + if (isset($aExtraParams['menu_actions_target'])) { + $aActionParams['target'] = $aExtraParams['menu_actions_target']; + } + // 1:n links, populate the target object as a default value when creating a new linked object + if (isset($aExtraParams['target_attr'])) { + $aExtraParams['default'][$aExtraParams['target_attr']] = $aExtraParams['object_id']; + } + $sDefault = ''; + if (!empty($aExtraParams['default'])) { + foreach ($aExtraParams['default'] as $sKey => $sValue) { + $sDefault .= "&default[$sKey]=$sValue"; } - break; + } + $bIsCreationAllowed = (UserRights::IsActionAllowed($sClass, + UR_ACTION_CREATE) == UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); + switch ($oSet->Count()) { + case 0: + // No object in the set, the only possible action is "new" + if ($bIsCreationAllowed) { + $aActions['UI:Menu:New'] = array( + 'label' => Dict::S('UI:Menu:New'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}" + ) + $aActionParams; + } + break; - case 1: - $oObj = $oSet->Fetch(); - if (is_null($oObj)) { - if (!isset($aExtraParams['link_attr'])) { - if ($bIsCreationAllowed) { - $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}") + $aActionParams; + case 1: + $oObj = $oSet->Fetch(); + if (is_null($oObj)) { + if (!isset($aExtraParams['link_attr'])) { + if ($bIsCreationAllowed) { + $aActions['UI:Menu:New'] = array( + 'label' => Dict::S('UI:Menu:New'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}" + ) + $aActionParams; + } } - } - } else { - $id = $oObj->GetKey(); - if (utils::ReadParam('operation') == 'details') { - if ($_SERVER['REQUEST_METHOD'] == 'GET') { - $sRefreshAction = "window.location.reload();"; - } else { - $sRefreshAction = "window.location.href='".ApplicationContext::MakeObjectUrl(get_class($oObj), $id)."';"; + } else { + $id = $oObj->GetKey(); + if (utils::ReadParam('operation') == 'details') { + if ($_SERVER['REQUEST_METHOD'] == 'GET') { + $sRefreshAction = "window.location.reload();"; + } else { + $sRefreshAction = "window.location.href='".ApplicationContext::MakeObjectUrl(get_class($oObj), $id)."';"; + } } - } - $bLocked = false; - if (MetaModel::GetConfig()->Get('concurrent_lock_enabled')) { - $aLockInfo = iTopOwnershipLock::IsLocked(get_class($oObj), $id); - if ($aLockInfo['locked']) { - $bLocked = true; - //$this->AddMenuSeparator($aActions); - //$aActions['concurrent_lock_unlock'] = array ('label' => Dict::S('UI:Menu:ReleaseConcurrentLock'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}"); + $bLocked = false; + if (MetaModel::GetConfig()->Get('concurrent_lock_enabled')) { + $aLockInfo = iTopOwnershipLock::IsLocked(get_class($oObj), $id); + if ($aLockInfo['locked']) { + $bLocked = true; + //$this->AddMenuSeparator($aActions); + //$aActions['concurrent_lock_unlock'] = array ('label' => Dict::S('UI:Menu:ReleaseConcurrentLock'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}"); + } } - } - $bRawModifiedAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) == UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); - $bIsModifyAllowed = !$bLocked && $bRawModifiedAllowed; - $bIsDeleteAllowed = !$bLocked && UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet); - // Just one object in the set, possible actions are "new / clone / modify and delete" - if (!isset($aExtraParams['link_attr'])) { - if ($bIsModifyAllowed) { - $aActions['UI:Menu:Modify'] = array('label' => Dict::S('UI:Menu:Modify'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=modify&class=$sClass&id=$id{$sContext}#") + $aActionParams; - } - if ($bIsCreationAllowed) { - $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}") + $aActionParams; - } - if ($bIsDeleteAllowed) { - $aActions['UI:Menu:Delete'] = array('label' => Dict::S('UI:Menu:Delete'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}") + $aActionParams; - } - // Transitions / Stimuli - if (!$bLocked) { - $aTransitions = $oObj->EnumTransitions(); - if (count($aTransitions)) { + $bRawModifiedAllowed = (UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, + $oSet) == UR_ALLOWED_YES) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); + $bIsModifyAllowed = !$bLocked && $bRawModifiedAllowed; + $bIsDeleteAllowed = !$bLocked && UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet); + // Just one object in the set, possible actions are "new / clone / modify and delete" + if (!isset($aExtraParams['link_attr'])) { + if ($bIsModifyAllowed) { + $aActions['UI:Menu:Modify'] = array( + 'label' => Dict::S('UI:Menu:Modify'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=modify&class=$sClass&id=$id{$sContext}#" + ) + $aActionParams; + } + if ($bIsCreationAllowed) { + $aActions['UI:Menu:New'] = array( + 'label' => Dict::S('UI:Menu:New'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}" + ) + $aActionParams; + } + if ($bIsDeleteAllowed) { + $aActions['UI:Menu:Delete'] = array( + 'label' => Dict::S('UI:Menu:Delete'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=delete&class=$sClass&id=$id{$sContext}" + ) + $aActionParams; + } + // Transitions / Stimuli + if (!$bLocked) { + $aTransitions = $oObj->EnumTransitions(); + if (count($aTransitions)) { + $this->AddMenuSeparator($aActions); + $aStimuli = Metamodel::EnumStimuli(get_class($oObj)); + foreach ($aTransitions as $sStimulusCode => $aTransitionDef) { + $iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sClass, + $sStimulusCode, $oSet) : UR_ALLOWED_NO; + switch ($iActionAllowed) { + case UR_ALLOWED_YES: + $aActions[$sStimulusCode] = array( + 'label' => $aStimuli[$sStimulusCode]->GetLabel(), + 'url' => "{$sRootUrl}pages/UI.php?operation=stimulus&stimulus=$sStimulusCode&class=$sClass&id=$id{$sContext}" + ) + $aActionParams; + break; + + default: + // Do nothing + } + } + } + } + // Relations... + $aRelations = MetaModel::EnumRelationsEx($sClass); + if (count($aRelations)) { $this->AddMenuSeparator($aActions); - $aStimuli = Metamodel::EnumStimuli(get_class($oObj)); - foreach ($aTransitions as $sStimulusCode => $aTransitionDef) { - $iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet) : UR_ALLOWED_NO; - switch ($iActionAllowed) { - case UR_ALLOWED_YES: - $aActions[$sStimulusCode] = array('label' => $aStimuli[$sStimulusCode]->GetLabel(), 'url' => "{$sRootUrl}pages/UI.php?operation=stimulus&stimulus=$sStimulusCode&class=$sClass&id=$id{$sContext}") + $aActionParams; - break; + foreach ($aRelations as $sRelationCode => $aRelationInfo) { + if (array_key_exists('down', $aRelationInfo)) { + $aActions[$sRelationCode.'_down'] = array( + 'label' => $aRelationInfo['down'], + 'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}" + ) + $aActionParams; + } + if (array_key_exists('up', $aRelationInfo)) { + $aActions[$sRelationCode.'_up'] = array( + 'label' => $aRelationInfo['up'], + 'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}" + ) + $aActionParams; + } + } + } + if ($bLocked && $bRawModifiedAllowed) { + // Add a special menu to kill the lock, but only to allowed users who can also modify this object + /** @var array $aAllowedProfiles */ + $aAllowedProfiles = MetaModel::GetConfig()->Get('concurrent_lock_override_profiles'); + $bCanKill = false; - default: - // Do nothing + $oUser = UserRights::GetUserObject(); + $aUserProfiles = array(); + if (!is_null($oUser)) { + $oProfileSet = $oUser->Get('profile_list'); + while ($oProfile = $oProfileSet->Fetch()) { + $aUserProfiles[$oProfile->Get('profile')] = true; + } + } + + foreach ($aAllowedProfiles as $sProfile) { + if (array_key_exists($sProfile, $aUserProfiles)) { + $bCanKill = true; + break; + } + } + + if ($bCanKill) { + $this->AddMenuSeparator($aActions); + $aActions['concurrent_lock_unlock'] = array( + 'label' => Dict::S('UI:Menu:KillConcurrentLock'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}" + ); + } + } + } + $this->AddMenuSeparator($aActions); + /** @var \iApplicationUIExtension $oExtensionInstance */ + foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) { + $oSet->Rewind(); + foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $sUrl) { + $aActions[$sLabel] = array('label' => $sLabel, 'url' => $sUrl) + $aActionParams; + } + } + } + break; + + default: + // Check rights + // New / Modify + $bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, + $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); + $bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sClass)) && UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, + $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); + $bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet); + if (isset($aExtraParams['link_attr'])) { + $id = $aExtraParams['object_id']; + $sTargetAttr = $aExtraParams['target_attr']; + $oAttDef = MetaModel::GetAttributeDef($sClass, $sTargetAttr); + $sTargetClass = $oAttDef->GetTargetClass(); + if ($bIsModifyAllowed) { + $aActions['UI:Menu:Add'] = array( + 'label' => Dict::S('UI:Menu:Add'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id&addObjects=true{$sContext}" + ) + $aActionParams; + } + if ($bIsBulkModifyAllowed) { + $aActions['UI:Menu:Manage'] = array( + 'label' => Dict::S('UI:Menu:Manage'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id{$sContext}" + ) + $aActionParams; + } + //if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All...', 'url' => "#") + $aActionParams; } + } else { + // many objects in the set, possible actions are: new / modify all / delete all + if ($bIsCreationAllowed) { + $aActions['UI:Menu:New'] = array( + 'label' => Dict::S('UI:Menu:New'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}" + ) + $aActionParams; + } + if ($bIsBulkModifyAllowed) { + $aActions['UI:Menu:ModifyAll'] = array( + 'label' => Dict::S('UI:Menu:ModifyAll'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=select_for_modify_all&class=$sClass&filter=".urlencode($sFilter)."{$sContext}" + ) + $aActionParams; + } + if ($bIsBulkDeleteAllowed) { + $aActions['UI:Menu:BulkDelete'] = array( + 'label' => Dict::S('UI:Menu:BulkDelete'), + 'url' => "{$sRootUrl}pages/$sUIPage?operation=select_for_deletion&filter=".urlencode($sFilter)."{$sContext}" + ) + $aActionParams; + } + + // Stimuli + $aStates = MetaModel::EnumStates($sClass); + // Do not perform time consuming computations if there are too may objects in the list + $iLimit = MetaModel::GetConfig()->Get('complex_actions_limit'); + + if ((count($aStates) > 0) && (($iLimit == 0) || ($oSet->CountWithLimit($iLimit + 1) < $iLimit))) { + // Life cycle actions may be available... if all objects are in the same state + // + // Group by + $oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias()); + $aGroupBy = array('__state__' => $oGroupByExp); + $aQueryParams = array(); + if (isset($aExtraParams['query_params'])) { + $aQueryParams = $aExtraParams['query_params']; + } + $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy); + $aRes = CMDBSource::QueryToArray($sSql); + if (count($aRes) == 1) { + // All objects are in the same state... + $sState = $aRes[0]['__state__']; + $aTransitions = Metamodel::EnumTransitions($sClass, $sState); + if (count($aTransitions)) { + $this->AddMenuSeparator($aActions); + $aStimuli = Metamodel::EnumStimuli($sClass); + foreach ($aTransitions as $sStimulusCode => $aTransitionDef) { + $oSet->Rewind(); + // As soon as the user rights implementation will browse the object set, + // then we might consider using OptimizeColumnLoad() here + $iActionAllowed = UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet); + $iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? $iActionAllowed : UR_ALLOWED_NO; + switch ($iActionAllowed) { + case UR_ALLOWED_YES: + case UR_ALLOWED_DEPENDS: + $aActions[$sStimulusCode] = array( + 'label' => $aStimuli[$sStimulusCode]->GetLabel(), + 'url' => "{$sRootUrl}pages/UI.php?operation=select_bulk_stimulus&stimulus=$sStimulusCode&state=$sState&class=$sClass&filter=".urlencode($sFilter)."{$sContext}" + ) + $aActionParams; + break; + + default: + // Do nothing + } } } } } - // Relations... - $aRelations = MetaModel::EnumRelationsEx($sClass); - if (count($aRelations)) { - $this->AddMenuSeparator($aActions); - foreach ($aRelations as $sRelationCode => $aRelationInfo) { - if (array_key_exists('down', $aRelationInfo)) { - $aActions[$sRelationCode.'_down'] = array('label' => $aRelationInfo['down'], 'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=down&class=$sClass&id=$id{$sContext}") + $aActionParams; - } - if (array_key_exists('up', $aRelationInfo)) { - $aActions[$sRelationCode.'_up'] = array('label' => $aRelationInfo['up'], 'url' => "{$sRootUrl}pages/$sUIPage?operation=view_relations&relation=$sRelationCode&direction=up&class=$sClass&id=$id{$sContext}") + $aActionParams; - } - } - } - if ($bLocked && $bRawModifiedAllowed) { - // Add a special menu to kill the lock, but only to allowed users who can also modify this object - /** @var array $aAllowedProfiles */ - $aAllowedProfiles = MetaModel::GetConfig()->Get('concurrent_lock_override_profiles'); - $bCanKill = false; - - $oUser = UserRights::GetUserObject(); - $aUserProfiles = array(); - if (!is_null($oUser)) { - $oProfileSet = $oUser->Get('profile_list'); - while ($oProfile = $oProfileSet->Fetch()) { - $aUserProfiles[$oProfile->Get('profile')] = true; - } - } - - foreach ($aAllowedProfiles as $sProfile) { - if (array_key_exists($sProfile, $aUserProfiles)) { - $bCanKill = true; - break; - } - } - - if ($bCanKill) { - $this->AddMenuSeparator($aActions); - $aActions['concurrent_lock_unlock'] = array('label' => Dict::S('UI:Menu:KillConcurrentLock'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=kill_lock&class=$sClass&id=$id{$sContext}"); - } - } } - $this->AddMenuSeparator($aActions); - /** @var \iApplicationUIExtension $oExtensionInstance */ - foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) { - $oSet->Rewind(); - foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $sUrl) { - $aActions[$sLabel] = array('label' => $sLabel, 'url' => $sUrl) + $aActionParams; - } - } - } - break; - - default: - // Check rights - // New / Modify - $bIsModifyAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); - $bIsBulkModifyAllowed = (!MetaModel::IsAbstract($sClass)) && UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_MODIFY, $oSet) && ($oReflectionClass->IsSubclassOf('cmdbAbstractObject')); - $bIsBulkDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_BULK_DELETE, $oSet); - if (isset($aExtraParams['link_attr'])) - { - $id = $aExtraParams['object_id']; - $sTargetAttr = $aExtraParams['target_attr']; - $oAttDef = MetaModel::GetAttributeDef($sClass, $sTargetAttr); - $sTargetClass = $oAttDef->GetTargetClass(); - if ($bIsModifyAllowed) { $aActions['UI:Menu:Add'] = array ('label' => Dict::S('UI:Menu:Add'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id&addObjects=true{$sContext}") + $aActionParams; } - if ($bIsBulkModifyAllowed) { $aActions['UI:Menu:Manage'] = array ('label' => Dict::S('UI:Menu:Manage'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=modify_links&class=$sClass&link_attr=".$aExtraParams['link_attr']."&target_class=$sTargetClass&id=$id{$sContext}") + $aActionParams; } - //if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All...', 'url' => "#") + $aActionParams; } } - else - { - // many objects in the set, possible actions are: new / modify all / delete all - if ($bIsCreationAllowed) { $aActions['UI:Menu:New'] = array ('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=new&class=$sClass{$sContext}{$sDefault}") + $aActionParams; } - if ($bIsBulkModifyAllowed) { $aActions['UI:Menu:ModifyAll'] = array ('label' => Dict::S('UI:Menu:ModifyAll'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=select_for_modify_all&class=$sClass&filter=".urlencode($sFilter)."{$sContext}") + $aActionParams; } - if ($bIsBulkDeleteAllowed) { $aActions['UI:Menu:BulkDelete'] = array ('label' => Dict::S('UI:Menu:BulkDelete'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=select_for_deletion&filter=".urlencode($sFilter)."{$sContext}") + $aActionParams; } - // Stimuli - $aStates = MetaModel::EnumStates($sClass); - // Do not perform time consuming computations if there are too may objects in the list - $iLimit = MetaModel::GetConfig()->Get('complex_actions_limit'); - - if ((count($aStates) > 0) && (($iLimit == 0) || ($oSet->CountWithLimit($iLimit + 1) < $iLimit))) - { - // Life cycle actions may be available... if all objects are in the same state - // - // Group by - $oGroupByExp = new FieldExpression(MetaModel::GetStateAttributeCode($sClass), $this->m_oFilter->GetClassAlias()); - $aGroupBy = array('__state__' => $oGroupByExp); - $aQueryParams = array(); - if (isset($aExtraParams['query_params'])) - { - $aQueryParams = $aExtraParams['query_params']; - } - $sSql = $this->m_oFilter->MakeGroupByQuery($aQueryParams, $aGroupBy); - $aRes = CMDBSource::QueryToArray($sSql); - if (count($aRes) == 1) - { - // All objects are in the same state... - $sState = $aRes[0]['__state__']; - $aTransitions = Metamodel::EnumTransitions($sClass, $sState); - if (count($aTransitions)) - { - $this->AddMenuSeparator($aActions); - $aStimuli = Metamodel::EnumStimuli($sClass); - foreach($aTransitions as $sStimulusCode => $aTransitionDef) - { - $oSet->Rewind(); - // As soon as the user rights implementation will browse the object set, - // then we might consider using OptimizeColumnLoad() here - $iActionAllowed = UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSet); - $iActionAllowed = (get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction') ? $iActionAllowed : UR_ALLOWED_NO; - switch($iActionAllowed) - { - case UR_ALLOWED_YES: - case UR_ALLOWED_DEPENDS: - $aActions[$sStimulusCode] = array('label' => $aStimuli[$sStimulusCode]->GetLabel(), 'url' => "{$sRootUrl}pages/UI.php?operation=select_bulk_stimulus&stimulus=$sStimulusCode&state=$sState&class=$sClass&filter=".urlencode($sFilter)."{$sContext}") + $aActionParams; - break; - - default: - // Do nothing - } - } - } + $this->AddMenuSeparator($aActions); + /** @var \iApplicationUIExtension $oExtensionInstance */ + foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) { + $oSet->Rewind(); + foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $data) { + if (is_array($data)) { + // New plugins can provide javascript handlers via the 'onclick' property + //TODO: enable extension of different menus by checking the 'target' property ?? + $aActions[$sLabel] = [ + 'label' => $sLabel, + 'url' => isset($data['url']) ? $data['url'] : '#', + 'onclick' => isset($data['onclick']) ? $data['onclick'] : '' + ]; + } else { + // Backward compatibility with old plugins + $aActions[$sLabel] = ['label' => $sLabel, 'url' => $data] + $aActionParams; } } } - } - - $this->AddMenuSeparator($aActions); - /** @var \iApplicationUIExtension $oExtensionInstance */ - foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) { - $oSet->Rewind(); - foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $data) { - if (is_array($data)) { - // New plugins can provide javascript handlers via the 'onclick' property - //TODO: enable extension of different menus by checking the 'target' property ?? - $aActions[$sLabel] = ['label' => $sLabel, 'url' => isset($data['url']) ? $data['url'] : '#', 'onclick' => isset($data['onclick']) ? $data['onclick'] : '']; - } else { - // Backward compatibility with old plugins - $aActions[$sLabel] = ['label' => $sLabel, 'url' => $data] + $aActionParams; - } + if (empty($sRefreshAction) && $this->m_sStyle == 'list') { + //for the detail page this var is defined way beyond this line + $sRefreshAction = "window.location.reload();"; } + } else + { + //it's easier just display configure this list and MENU_OBJLIST_TOOLKIT } $param = null; $iMenuId = null; @@ -1891,10 +1955,6 @@ JS $oActionsBlock->AddSubBlock($oActionButton); } - if (empty($sRefreshAction) && $this->m_sStyle == 'list') { - //for the detail page this var is defined way beyond this line - $sRefreshAction = "window.location.reload();"; - } if (!$oPage->IsPrintableVersion() && ($sRefreshAction != '')) { $oActionButton = ButtonFactory::MakeAlternativeNeutral('', 'UI:Button:Refresh'); $oActionButton->SetIconClass('fas fa-sync') diff --git a/application/ui.linkswidget.class.inc.php b/application/ui.linkswidget.class.inc.php index 5e2869369..d283a89b7 100644 --- a/application/ui.linkswidget.class.inc.php +++ b/application/ui.linkswidget.class.inc.php @@ -559,7 +559,27 @@ HTML $oBlock = new DisplayBlock($oFilter, 'list', false); $oBlock->Display($oP, "ResultsToAdd_{$this->m_sAttCode}", array('menu' => false, 'cssCount'=> '#count_'.$this->m_sAttCode.$this->m_sNameSuffix , 'selection_mode' => true, 'table_id' => 'add_'.$this->m_sAttCode)); // Don't display the 'Actions' menu on the results } + /** + * Display one row of the whole form + * @param WebPage $oP + * @param array $aConfig + * @param array $aRow + * @param int $iRowId + * @return string + * @deprecated in 3.0 + */ + protected function DisplayFormRow(WebPage $oP, $aConfig, $aRow, $iRowId) + { + $sHtml = ''; + $sHtml .= "m_sAttCode}{$this->m_sNameSuffix}_row_$iRowId\">\n"; + foreach($aConfig as $sName=>$void) + { + $sHtml .= "".$aRow[$sName]."\n"; + } + $sHtml .= "\n"; + return $sHtml; + } /** * @param WebPage $oP * @param int $iMaxAddedId diff --git a/js/search/search_form_handler.js b/js/search/search_form_handler.js index 368ea5fdf..dc0d4b581 100644 --- a/js/search/search_form_handler.js +++ b/js/search/search_form_handler.js @@ -348,14 +348,14 @@ $(function() me._submit(); }); // - Toggle icon - this.element.find('.sf_title').on('click', function(oEvent){ + this.element.find('.ibo-panel--header').on('click', function(oEvent){ // Prevent anchors oEvent.preventDefault(); // Prevent toggle on