/** * Renders the "Actions" popup menu for the given set of objects * * Note that the menu links containing (or ending) with a hash (#) will have their fragment * part (whatever is after the hash) dynamically replaced (by javascript) when the menu is * displayed, to correspond to the current hash/fragment in the page. This allows modifying * an object in with the same tab active by default as the tab that was active when selecting * the "Modify..." action. */ public function GetRenderContent(WebPage $oPage, $aExtraParams = array(), $sId) { if ($this->m_sStyle == 'popup') { $this->m_sStyle = 'list'; } $sHtml = ''; $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(); $sFilterDesc = $this->m_oFilter->ToOql(true); $aActions = array(); $sUIPage = cmdbAbstractObject::ComputeStandardUIPage($sClass); $sRootUrl = utils::GetAbsoluteUrlAppRoot(); // 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'); 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}"); } break; case 1: $oObj = $oSet->Fetch(); $id = $oObj->GetKey(); $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}#"); } if ($bIsCreationAllowed) { $aActions['UI:Menu:New'] = array('label' => Dict::S('UI:Menu:New'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=new&class={$sClass}{$sContext}{$sDefault}"); } if ($bIsDeleteAllowed) { $aActions['UI:Menu:Delete'] = array('label' => Dict::S('UI:Menu:Delete'), 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=delete&class={$sClass}&id={$id}{$sContext}"); } // 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}"); 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=swf_navigator&relation={$sRelationCode}&direction=down&class={$sClass}&id={$id}{$sContext}"); } if (array_key_exists('up', $aRelationInfo)) { $aActions[$sRelationCode . '_up'] = array('label' => $aRelationInfo['up'], 'url' => "{$sRootUrl}pages/{$sUIPage}?operation=swf_navigator&relation={$sRelationCode}&direction=up&class={$sClass}&id={$id}{$sContext}"); } } } if ($bLocked && $bRawModifiedAllowed) { // Add a special menu to kill the lock, but only to allowed users who can also modify this object $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); // Static menus: Email this page & CSV Export $sUrl = ApplicationContext::MakeObjectUrl($sClass, $id); $aActions['UI:Menu:EMail'] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=".urlencode($oObj->GetRawName())."&body=".urlencode($sUrl)); $aActions['UI:Menu:CSVExport'] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."&format=csv{$sContext}"); // The style tells us whether the menu is displayed on a list of one object, or on the details of the given object if ($this->m_sStyle == 'list') { // Actions specific to the list $sOQL = addslashes($sFilterDesc); $aActions['UI:Menu:AddToDashboard'] = array ('label' => Dict::S('UI:Menu:AddToDashboard'), 'url' => "#", 'onclick' => "return DashletCreationDlg('$sOQL')"); } */ } $this->AddMenuSeparator($aActions); foreach (MetaModel::EnumPlugins('iApplicationUIExtension') as $oExtensionInstance) { $oSet->Rewind(); foreach ($oExtensionInstance->EnumAllowedActions($oSet) as $sLabel => $sUrl) { $aActions[$sLabel] = array('label' => $sLabel, 'url' => $sUrl); } } 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(); $bIsDeleteAllowed = UserRights::IsActionAllowed($sClass, UR_ACTION_DELETE, $oSet); 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}"); } 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}"); } //if ($bIsBulkDeleteAllowed) { $aActions[] = array ('label' => 'Remove All...', 'url' => "#"); } } 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}"); } 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}"); } 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}"); } // 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->Count() < $iLimit)) { // Life cycle actions may be available... if all objects are in the same state // // Group by <state> $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}"); break; default: // Do nothing } } } } } /* $this->AddMenuSeparator($aActions); $sUrl = utils::GetAbsoluteUrlAppRoot(); $aActions['UI:Menu:EMail'] = array ('label' => Dict::S('UI:Menu:EMail'), 'url' => "mailto:?subject=$sFilterDesc&body=".urlencode("{$sUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."{$sContext}")); $aActions['UI:Menu:CSVExport'] = array ('label' => Dict::S('UI:Menu:CSVExport'), 'url' => "{$sRootUrl}pages/$sUIPage?operation=search&filter=".urlencode($sFilter)."&format=csv{$sContext}"); $sOQL = addslashes($sFilterDesc); $aActions['UI:Menu:AddToDashboard'] = array ('label' => Dict::S('UI:Menu:AddToDashboard'), 'url' => "#", 'onclick' => "return DashletCreationDlg('$sOQL')"); */ } } $this->AddMenuSeparator($aActions); 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] = array('label' => $sLabel, 'url' => isset($data['url']) ? $data['url'] : '#', 'onclick' => isset($data['onclick']) ? $data['onclick'] : ''); } else { // Backward compatibility with old plugins $aActions[$sLabel] = array('label' => $sLabel, 'url' => $data); } } } // New extensions based on iPopupMenuItem interface switch ($this->m_sStyle) { case 'list': $oSet->Rewind(); $param = $oSet; $iMenuId = iPopupMenuExtension::MENU_OBJLIST_ACTIONS; break; case 'details': $oSet->Rewind(); $param = $oSet->Fetch(); $iMenuId = iPopupMenuExtension::MENU_OBJDETAILS_ACTIONS; break; } utils::GetPopupMenuItems($oPage, $iMenuId, $param, $aActions); $aFavoriteActions = array(); $aCallSpec = array($sClass, 'GetShortcutActions'); if (is_callable($aCallSpec)) { $aShortcutActions = call_user_func($aCallSpec, $sClass); foreach ($aActions as $key => $aAction) { if (in_array($key, $aShortcutActions)) { $aFavoriteActions[] = $aAction; unset($aActions[$key]); } } } else { $aShortcutActions = array(); } if (count($aFavoriteActions) > 0) { $sHtml .= "<div class=\"itop_popup actions_menu\"><ul>\n<li>" . Dict::S('UI:Menu:OtherActions') . "\n<ul>\n"; } else { $sHtml .= "<div class=\"itop_popup actions_menu\"><ul>\n<li>" . Dict::S('UI:Menu:Actions') . "\n<ul>\n"; } $sHtml .= $oPage->RenderPopupMenuItems($aActions, $aFavoriteActions); static $bPopupScript = false; if (!$bPopupScript) { // Output this once per page... $oPage->add_ready_script("\$(\"div.itop_popup>ul\").popupmenu();\n"); $bPopupScript = true; } return $sHtml; }
protected function GetToolkitMenu(WebPage $oPage, $aExtraParams) { $sMenuTitle = Dict::S('UI:ConfigureThisList'); $sHtml = '<div class="itop_popup toolkit_menu" id="tk_' . $this->iListId . '"><ul><li><img src="../images/toolkit_menu.png"><ul>'; $oMenuItem1 = new JSPopupMenuItem('iTop::ConfigureList', $sMenuTitle, "\$('#datatable_dlg_" . $this->iListId . "').dialog('open');"); $aActions = array($oMenuItem1->GetUID() => $oMenuItem1->GetMenuItem()); $this->oSet->Rewind(); utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_OBJLIST_TOOLKIT, $this->oSet, $aActions, $this->sTableId, $this->iListId); $this->oSet->Rewind(); $sHtml .= $oPage->RenderPopupMenuItems($aActions); return $sHtml; }
/** * Outputs (via some echo) the complete HTML page by assembling all its elements */ public function output() { $sAbsURLAppRoot = addslashes($this->m_sRootUrl); //$this->set_base($this->m_sRootUrl.'pages/'); $sForm = $this->GetSiloSelectionForm(); $this->DisplayMenu(); // Compute the menu // Call the extensions to add content to the page, so that they can also add styles or scripts $sBannerExtraHtml = ''; foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) { $sBannerExtraHtml .= $oExtensionInstance->GetBannerHtml($this); } $sNorthPane = ''; foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) { $sNorthPane .= $oExtensionInstance->GetNorthPaneHtml($this); } if (UserRights::IsAdministrator() && ExecutionKPI::IsEnabled()) { $sNorthPane .= '<div id="admin-banner"><span style="padding:5px;">' . ExecutionKPI::GetDescription() . '<span></div>'; } //$sSouthPane = '<p>Peak memory Usage: '.sprintf('%.3f MB', memory_get_peak_usage(true) / (1024*1024)).'</p>'; $sSouthPane = ''; foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) { $sSouthPane .= $oExtensionInstance->GetSouthPaneHtml($this); } // Put here the 'ready scripts' that must be executed after all others $aMultiselectOptions = array('header' => true, 'checkAllText' => Dict::S('UI:SearchValue:CheckAll'), 'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'), 'noneSelectedText' => Dict::S('UI:SearchValue:Any'), 'selectedText' => Dict::S('UI:SearchValue:NbSelected'), 'selectedList' => 1); $sJSMultiselectOptions = json_encode($aMultiselectOptions); $this->add_ready_script(<<<EOF \t\t// Since the event is only triggered when the hash changes, we need to trigger \t\t// the event now, to handle the hash the page may have loaded with. \t\t\$(window).trigger( 'hashchange' ); \t\t \t\t// Some table are sort-able, some are not, let's fix this \t\t\$('table.listResults').each( function() { FixTableSorter(\$(this)); } ); \t\t \t\t\$('.multiselect').multiselect({$sJSMultiselectOptions}); \t\tFixSearchFormsDisposition(); EOF ); if ($this->GetOutputFormat() == 'html') { foreach ($this->a_headers as $s_header) { header($s_header); } } $s_captured_output = $this->ob_get_clean_safe(); $sHtml = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"; $sHtml .= "<html>\n"; $sHtml .= "<head>\n"; // Make sure that Internet Explorer renders the page using its latest/highest/greatest standards ! $sHtml .= "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n"; $sHtml .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"; $sHtml .= "<title>" . htmlentities($this->s_title, ENT_QUOTES, 'UTF-8') . "</title>\n"; $sHtml .= $this->get_base_tag(); // Stylesheets MUST be loaded before any scripts otherwise // jQuery scripts may face some spurious problems (like failing on a 'reload') foreach ($this->a_linked_stylesheets as $a_stylesheet) { if ($a_stylesheet['condition'] != "") { $sHtml .= "<!--[if {$a_stylesheet['condition']}]>\n"; } $sHtml .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$a_stylesheet['link']}\" />\n"; if ($a_stylesheet['condition'] != "") { $sHtml .= "<![endif]-->\n"; } } // special stylesheet for printing, hides the navigation gadgets $sHtml .= "<link rel=\"stylesheet\" media=\"print\" type=\"text/css\" href=\"../css/print.css\" />\n"; if ($this->GetOutputFormat() == 'html') { $sHtml .= $this->output_dict_entries(true); // before any script so that they can benefit from the translations foreach ($this->a_linked_scripts as $s_script) { // Make sure that the URL to the script contains the application's version number // so that the new script do NOT get reloaded from the cache when the application is upgraded if (strpos($s_script, '?') === false) { $s_script .= "?itopversion=" . ITOP_VERSION; } else { $s_script .= "&itopversion=" . ITOP_VERSION; } $sHtml .= "<script type=\"text/javascript\" src=\"{$s_script}\"></script>\n"; } $this->add_script("var iPaneVisWatchDog = window.setTimeout('FixPaneVis()',5000);\n\$(document).ready(function() {\n{$this->m_sInitScript};\nwindow.setTimeout('onDelayedReady()',10)\n});"); if (count($this->m_aReadyScripts) > 0) { $this->add_script("\nonDelayedReady = function() {\n" . implode("\n", $this->m_aReadyScripts) . "\n}\n"); } if (count($this->a_scripts) > 0) { $sHtml .= "<script type=\"text/javascript\">\n"; foreach ($this->a_scripts as $s_script) { $sHtml .= "{$s_script}\n"; } $sHtml .= "</script>\n"; } } if (count($this->a_styles) > 0) { $sHtml .= "<style>\n"; foreach ($this->a_styles as $s_style) { $sHtml .= "{$s_style}\n"; } $sHtml .= "</style>\n"; } $sHtml .= "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"" . utils::GetAbsoluteUrlAppRoot() . "pages/opensearch.xml.php\" />\n"; $sHtml .= "<link rel=\"shortcut icon\" href=\"" . utils::GetAbsoluteUrlAppRoot() . "images/favicon.ico\" />\n"; $sHtml .= "</head>\n"; $sHtml .= "<body>\n"; // Render the revision number if (ITOP_REVISION == '$WCREV$') { // This is NOT a version built using the buil system, just display the main version $sVersionString = Dict::Format('UI:iTopVersion:Short', ITOP_VERSION); } else { // This is a build made from SVN, let display the full information $sVersionString = Dict::Format('UI:iTopVersion:Long', ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE); } // Render the text of the global search form $sText = htmlentities(utils::ReadParam('text', '', false, 'raw_data'), ENT_QUOTES, 'UTF-8'); $sOnClick = ""; if (empty($sText)) { // if no search text is supplied then // 1) the search text is filled with "your search" // 2) clicking on it will erase it $sText = Dict::S("UI:YourSearch"); $sOnClick = " onclick=\"this.value='';this.onclick=null;\""; } // Render the tabs in the page (if any) $this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content); if ($this->GetOutputFormat() == 'html') { $oAppContext = new ApplicationContext(); $sUserName = UserRights::GetUser(); $sIsAdmin = UserRights::IsAdministrator() ? '(Administrator)' : ''; if (UserRights::IsAdministrator()) { $sLogonMessage = Dict::Format('UI:LoggedAsMessage+Admin', $sUserName); } else { $sLogonMessage = Dict::Format('UI:LoggedAsMessage', $sUserName); } $sLogOffMenu = "<span id=\"logOffBtn\"><ul><li><img src=\"../images/onOffBtn.png\"><ul>"; $sLogOffMenu .= "<li><span>{$sLogonMessage}</span></li>\n"; $aActions = array(); $oPrefs = new URLPopupMenuItem('UI:Preferences', Dict::S('UI:Preferences'), utils::GetAbsoluteUrlAppRoot() . "pages/preferences.php?" . $oAppContext->GetForLink()); $aActions[$oPrefs->GetUID()] = $oPrefs->GetMenuItem(); if (utils::CanLogOff()) { $oLogOff = new URLPopupMenuItem('UI:LogOffMenu', Dict::S('UI:LogOffMenu'), utils::GetAbsoluteUrlAppRoot() . 'pages/logoff.php?operation=do_logoff'); $aActions[$oLogOff->GetUID()] = $oLogOff->GetMenuItem(); } if (UserRights::CanChangePassword()) { $oChangePwd = new URLPopupMenuItem('UI:ChangePwdMenu', Dict::S('UI:ChangePwdMenu'), utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=change_pwd'); $aActions[$oChangePwd->GetUID()] = $oChangePwd->GetMenuItem(); } utils::GetPopupMenuItems($this, iPopupMenuExtension::MENU_USER_ACTIONS, null, $aActions); $oAbout = new JSPopupMenuItem('UI:AboutBox', Dict::S('UI:AboutBox'), 'return ShowAboutBox();'); $aActions[$oAbout->GetUID()] = $oAbout->GetMenuItem(); $sLogOffMenu .= $this->RenderPopupMenuItems($aActions); $sRestrictions = ''; if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE)) { if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE)) { $sRestrictions = Dict::S('UI:AccessRO-All'); } } elseif (!MetaModel::DBHasAccess(ACCESS_USER_WRITE)) { $sRestrictions = Dict::S('UI:AccessRO-Users'); } $sApplicationBanner = ''; if (strlen($sRestrictions) > 0) { $sAdminMessage = trim(MetaModel::GetConfig()->Get('access_message')); $sApplicationBanner .= '<div id="admin-banner">'; $sApplicationBanner .= '<img src="../images/locked.png" style="vertical-align:middle;">'; $sApplicationBanner .= ' <b>' . $sRestrictions . '</b>'; if (strlen($sAdminMessage) > 0) { $sApplicationBanner .= ' <b>' . $sAdminMessage . '</b>'; } $sApplicationBanner .= '</div>'; } if (strlen($this->m_sMessage)) { $sApplicationBanner .= '<div id="admin-banner"><span style="padding:5px;">' . $this->m_sMessage . '<span></div>'; } $sApplicationBanner .= $sBannerExtraHtml; if (!empty($sNorthPane)) { $sNorthPane = '<div id="bottom-pane" class="ui-layout-north">' . $sNorthPane . '</div>'; } if (!empty($sSouthPane)) { $sSouthPane = '<div id="bottom-pane" class="ui-layout-south">' . $sSouthPane . '</div>'; } $sIconUrl = Utils::GetConfig()->Get('app_icon_url'); $sOnlineHelpUrl = MetaModel::GetConfig()->Get('online_help'); //$sLogOffMenu = "<span id=\"logOffBtn\" style=\"height:55px;padding:0;margin:0;\"><img src=\"../images/onOffBtn.png\"></span>"; $sDisplayIcon = utils::GetAbsoluteUrlAppRoot() . 'images/itop-logo.png'; if (file_exists(MODULESROOT . 'branding/main-logo.png')) { $sDisplayIcon = utils::GetAbsoluteUrlModulesRoot() . 'branding/main-logo.png'; } $sHtml .= $sNorthPane; $sHtml .= '<div id="left-pane" class="ui-layout-west">'; $sHtml .= '<!-- Beginning of the left pane -->'; $sHtml .= ' <div class="ui-layout-north">'; $sHtml .= ' <div id="header-logo">'; $sHtml .= ' <div id="top-left"></div><div id="logo"><a href="' . htmlentities($sIconUrl, ENT_QUOTES, 'UTF-8') . '"><img src="' . $sDisplayIcon . '" title="' . htmlentities($sVersionString, ENT_QUOTES, 'UTF-8') . '" style="border:0; margin-top:16px; margin-right:40px;"/></a></div>'; $sHtml .= ' </div>'; $sHtml .= ' <div class="header-menu">'; if (!MetaModel::GetConfig()->Get('demo_mode')) { $sHtml .= ' <div class="icon ui-state-default ui-corner-all"><span id="tPinMenu" class="ui-icon ui-icon-pin-w">pin</span></div>'; } $sHtml .= ' <div style="text-align:center;">' . self::FilterXSS($sForm) . '</div>'; $sHtml .= ' </div>'; $sHtml .= ' </div>'; $sHtml .= ' <div id="menu" class="ui-layout-center">'; $sHtml .= ' <div id="inner_menu">'; $sHtml .= ' <div id="accordion">'; $sHtml .= self::FilterXSS($this->m_sMenu); $sHtml .= ' <!-- Beginning of the accordion menu -->'; $sHtml .= ' <!-- End of the accordion menu-->'; $sHtml .= ' </div>'; $sHtml .= ' </div> <!-- /inner menu -->'; $sHtml .= ' </div> <!-- /menu -->'; $sHtml .= ' <div class="footer ui-layout-south"><div id="combodo_logo"><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="../images/logo-combodo.png"/></a></div></div>'; $sHtml .= '<!-- End of the left pane -->'; $sHtml .= '</div>'; $sHtml .= '<div class="ui-layout-center">'; $sHtml .= ' <div id="top-bar" style="width:100%">'; $sHtml .= self::FilterXSS($sApplicationBanner); $sHtml .= ' <div id="global-search"><form action="' . utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php"><table><tr><td></td><td id="g-search-input"><input type="text" name="text" value="' . $sText . '"' . $sOnClick . '/></td>'; $sHtml .= '<td><input type="image" src="../images/searchBtn.png"/></a></td>'; $sHtml .= '<td><a style="background:transparent;" href="' . $sOnlineHelpUrl . '" target="_blank"><img style="border:0;padding-left:20px;padding-right:10px;" title="' . Dict::S('UI:Help') . '" src="../images/help.png"/></td>'; $sHtml .= '<td style="padding-right:20px;padding-left:10px;">' . self::FilterXSS($sLogOffMenu) . '</td><td><input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>'; //echo '<td> <input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>'; $sHtml .= ' </div>'; $sHtml .= ' <div class="ui-layout-content" style="overflow:auto;">'; $sHtml .= ' <!-- Beginning of page content -->'; $sHtml .= self::FilterXSS($this->s_content); $sHtml .= ' <!-- End of page content -->'; $sHtml .= ' </div>'; $sHtml .= '</div>'; $sHtml .= $sSouthPane; // Add the captured output if (trim($s_captured_output) != "") { $sHtml .= "<div id=\"rawOutput\" title=\"Debug Output\"><div style=\"height:500px; overflow-y:auto;\">" . self::FilterXSS($s_captured_output) . "</div></div>\n"; } $sHtml .= "<div id=\"at_the_end\">" . self::FilterXSS($this->s_deferred_content) . "</div>"; $sHtml .= "<div style=\"display:none\" title=\"ex2\" id=\"ex2\">Please wait...</div>\n"; // jqModal Window $sHtml .= "<div style=\"display:none\" title=\"dialog\" id=\"ModalDlg\"></div>"; $sHtml .= "<div style=\"display:none\" id=\"ajax_content\"></div>"; } else { $sHtml .= self::FilterXSS($this->s_content); } $sHtml .= "</body>\n"; $sHtml .= "</html>\n"; if ($this->GetOutputFormat() == 'html') { $oKPI = new ExecutionKPI(); echo $sHtml; $oKPI->ComputeAndReport('Echoing (' . round(strlen($sHtml) / 1024) . ' Kb)'); } else { if ($this->GetOutputFormat() == 'pdf' && $this->IsOutputFormatAvailable('pdf')) { if (@is_readable(APPROOT . 'lib/MPDF/mpdf.php')) { require_once APPROOT . 'lib/MPDF/mpdf.php'; $oMPDF = new mPDF('c'); $oMPDF->mirroMargins = false; if ($this->a_base['href'] != '') { $oMPDF->setBasePath($this->a_base['href']); // Seems that the <BASE> tag is not recognized by mPDF... } $oMPDF->showWatermarkText = true; if ($this->GetOutputOption('pdf', 'template_path')) { $oMPDF->setImportUse(); // Allow templates $oMPDF->SetDocTemplate($this->GetOutputOption('pdf', 'template_path'), 1); } $oMPDF->WriteHTML($sHtml); $sOutputName = $this->s_title . '.pdf'; if ($this->GetOutputOption('pdf', 'output_name')) { $sOutputName = $this->GetOutputOption('pdf', 'output_name'); } $oMPDF->Output($sOutputName, 'I'); } } } DBSearch::RecordQueryTrace(); ExecutionKPI::ReportStats(); }
public function RenderEditionTools($oPage) { $sEditMenu = "<td><span id=\"DashboardMenu\"><ul><li><img src=\"../images/edit.png\"><ul>"; $aActions = array(); $oEdit = new JSPopupMenuItem('UI:Dashboard:Edit', Dict::S('UI:Dashboard:Edit'), "return EditDashboard('{$this->sId}')"); $aActions[$oEdit->GetUID()] = $oEdit->GetMenuItem(); if ($this->bCustomized) { $oRevert = new JSPopupMenuItem('UI:Dashboard:RevertConfirm', Dict::S('UI:Dashboard:Revert'), "if (confirm('" . addslashes(Dict::S('UI:Dashboard:RevertConfirm')) . "')) return RevertDashboard('{$this->sId}'); else return false"); $aActions[$oRevert->GetUID()] = $oRevert->GetMenuItem(); } utils::GetPopupMenuItems($oPage, iPopupMenuExtension::MENU_DASHBOARD_ACTIONS, $this, $aActions); $sEditMenu .= $oPage->RenderPopupMenuItems($aActions); $sEditMenu = addslashes($sEditMenu); //$sEditBtn = addslashes('<div style="display: inline-block; height: 55px; width:200px;vertical-align:center;line-height:60px;text-align:left;"><button onclick="EditDashboard(\''.$this->sId.'\');">Edit This Page</button></div>'); $oPage->add_ready_script(<<<EOF \t\$('#logOffBtn').parent().before('{$sEditMenu}'); \t\$('#DashboardMenu>ul').popupmenu(); \t EOF ); $oPage->add_script(<<<EOF function EditDashboard(sId) { \t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {operation: 'dashboard_editor', id: sId}, \t\tfunction(data) \t\t{ \t\t\t\$('body').append(data); \t\t} \t); \treturn false; } function RevertDashboard(sId) { \t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {operation: 'revert_dashboard', dashboard_id: sId}, \t\tfunction(data) \t\t{ \t\t\t\$('body').append(data); \t\t} \t); \treturn false; } EOF ); }