Esempio n. 1
0
 /**
  * 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;
 }
    public function DisplayModifyForm(WebPage $oPage, $aExtraParams = array())
    {
        $sOwnershipToken = null;
        $iKey = $this->GetKey();
        $sClass = get_class($this);
        if ($iKey > 0) {
            // The concurrent access lock makes sense only for already existing objects
            $LockEnabled = MetaModel::GetConfig()->Get('concurrent_lock_enabled');
            if ($LockEnabled) {
                $sOwnershipToken = utils::ReadPostedParam('ownership_token', null, false, 'raw_data');
                if ($sOwnershipToken !== null) {
                    // We're probably inside something like "apply_modify" where the validation failed and we must prompt the user again to edit the object
                    // let's extend our lock
                    $aLockInfo = iTopOwnershipLock::ExtendLock($sClass, $iKey, $sOwnershipToken);
                    $sOwnershipDate = $aLockInfo['acquired'];
                } else {
                    $aLockInfo = iTopOwnershipLock::AcquireLock($sClass, $iKey);
                    if ($aLockInfo['success']) {
                        $sOwnershipToken = $aLockInfo['token'];
                        $sOwnershipDate = $aLockInfo['acquired'];
                    } else {
                        $oOwner = $aLockInfo['lock']->GetOwner();
                        // If the object is locked by the current user, it's worth trying again, since
                        // the lock may be released by 'onunload' which is called AFTER loading the current page.
                        //$bTryAgain = $oOwner->GetKey() == UserRights::GetUserId();
                        self::ReloadAndDisplay($oPage, $this, array('operation' => 'modify'));
                        return;
                    }
                }
            }
        }
        if (isset($aExtraParams['wizard_container']) && $aExtraParams['wizard_container']) {
            $sClassLabel = MetaModel::GetName($sClass);
            $oPage->set_title(Dict::Format('UI:ModificationPageTitle_Object_Class', $this->GetRawName(), $sClassLabel));
            // Set title will take care of the encoding
            $oPage->add("<div class=\"page_header\">\n");
            $oPage->add("<h1>" . $this->GetIcon() . "&nbsp;" . Dict::Format('UI:ModificationTitle_Class_Object', $sClassLabel, $this->GetName()) . "</h1>\n");
            $oPage->add("</div>\n");
            $oPage->add("<div class=\"wizContainer\">\n");
        }
        self::$iGlobalFormId++;
        $this->aFieldsMap = array();
        $sPrefix = '';
        if (isset($aExtraParams['formPrefix'])) {
            $sPrefix = $aExtraParams['formPrefix'];
        }
        $aFieldsComments = isset($aExtraParams['fieldsComments']) ? $aExtraParams['fieldsComments'] : array();
        $this->m_iFormId = $sPrefix . self::$iGlobalFormId;
        $oAppContext = new ApplicationContext();
        $sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
        $aDetails = array();
        $aFieldsMap = array();
        if (!isset($aExtraParams['action'])) {
            $sFormAction = utils::GetAbsoluteUrlAppRoot() . 'pages/' . $this->GetUIPage();
            // No parameter in the URL, the only parameter will be the ones passed through the form
        } else {
            $sFormAction = $aExtraParams['action'];
        }
        // Custom label for the apply button ?
        if (isset($aExtraParams['custom_button'])) {
            $sApplyButton = $aExtraParams['custom_button'];
        } else {
            if ($iKey > 0) {
                $sApplyButton = Dict::S('UI:Button:Apply');
            } else {
                $sApplyButton = Dict::S('UI:Button:Create');
            }
        }
        // Custom operation for the form ?
        if (isset($aExtraParams['custom_operation'])) {
            $sOperation = $aExtraParams['custom_operation'];
        } else {
            if ($iKey > 0) {
                $sOperation = 'apply_modify';
            } else {
                $sOperation = 'apply_new';
            }
        }
        if ($iKey > 0) {
            // The object already exists in the database, it's a modification
            $sButtons = "<input id=\"{$sPrefix}_id\" type=\"hidden\" name=\"id\" value=\"{$iKey}\">\n";
            $sButtons .= "<input type=\"hidden\" name=\"operation\" value=\"{$sOperation}\">\n";
            $sButtons .= "<button type=\"button\" class=\"action cancel\"><span>" . Dict::S('UI:Button:Cancel') . "</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n";
            $sButtons .= "<button type=\"submit\" class=\"action\"><span>{$sApplyButton}</span></button>\n";
        } else {
            // The object does not exist in the database it's a creation
            $sButtons = "<input type=\"hidden\" name=\"operation\" value=\"{$sOperation}\">\n";
            $sButtons .= "<button type=\"button\" class=\"action cancel\">" . Dict::S('UI:Button:Cancel') . "</button>&nbsp;&nbsp;&nbsp;&nbsp;\n";
            $sButtons .= "<button type=\"submit\" class=\"action\"><span>{$sApplyButton}</span></button>\n";
        }
        $aTransitions = $this->EnumTransitions();
        if (!isset($aExtraParams['custom_operation']) && count($aTransitions)) {
            // transitions are displayed only for the standard new/modify actions, not for modify_all or any other case...
            $oSetToCheckRights = DBObjectSet::FromObject($this);
            $aStimuli = Metamodel::EnumStimuli($sClass);
            foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
                $iActionAllowed = get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction' ? UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSetToCheckRights) : UR_ALLOWED_NO;
                switch ($iActionAllowed) {
                    case UR_ALLOWED_YES:
                        $sButtons .= "<button type=\"submit\" name=\"next_action\" value=\"{$sStimulusCode}\" class=\"action\"><span>" . $aStimuli[$sStimulusCode]->GetLabel() . "</span></button>\n";
                        break;
                    default:
                        // Do nothing
                }
            }
        }
        $sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position');
        $iTransactionId = isset($aExtraParams['transaction_id']) ? $aExtraParams['transaction_id'] : utils::GetNewTransactionId();
        $oPage->SetTransactionId($iTransactionId);
        $oPage->add("<form action=\"{$sFormAction}\" id=\"form_{$this->m_iFormId}\" enctype=\"multipart/form-data\" method=\"post\" onSubmit=\"return OnSubmit('form_{$this->m_iFormId}');\">\n");
        $sStatesSelection = '';
        if (!isset($aExtraParams['custom_operation']) && $this->IsNew()) {
            $aInitialStates = MetaModel::EnumInitialStates($sClass);
            //$aInitialStates = array('new' => 'foo', 'closed' => 'bar');
            if (count($aInitialStates) > 1) {
                $sStatesSelection = Dict::Format('UI:Create_Class_InState', MetaModel::GetName($sClass)) . '<select name="obj_state" class="state_select_' . $this->m_iFormId . '">';
                foreach ($aInitialStates as $sStateCode => $sStateData) {
                    $sSelected = '';
                    if ($sStateCode == $this->GetState()) {
                        $sSelected = ' selected';
                    }
                    $sStatesSelection .= '<option value="' . $sStateCode . '"' . $sSelected . '>' . MetaModel::GetStateLabel($sClass, $sStateCode) . '</option>';
                }
                $sStatesSelection .= '</select>';
                $oPage->add_ready_script("\$('.state_select_{$this->m_iFormId}').change( function() { oWizardHelper{$sPrefix}.ReloadObjectCreationForm('form_{$this->m_iFormId}', \$(this).val()); } );");
            }
        }
        $sConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
        $sJSToken = json_encode($sOwnershipToken);
        $oPage->add_ready_script(<<<EOF
\t\$(window).unload(function() { return OnUnload('{$iTransactionId}', '{$sClass}', {$iKey}, {$sJSToken}) } );
\twindow.onbeforeunload = function() {
\t\tif (!window.bInSubmit && !window.bInCancel)
\t\t{
\t\t\treturn '{$sConfirmationMessage}';\t
\t\t}
\t\t// return nothing ! safer for IE
\t};
EOF
);
        if ($sButtonsPosition != 'bottom') {
            // top or both, display the buttons here
            $oPage->p($sStatesSelection);
            $oPage->add($sButtons);
        }
        $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, $sPrefix);
        $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
        $oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
        $aFieldsMap = $this->DisplayBareProperties($oPage, true, $sPrefix, $aExtraParams);
        if ($iKey > 0) {
            $aFieldsMap['id'] = $sPrefix . '_id';
        }
        // Now display the relations, one tab per relation
        if (!isset($aExtraParams['noRelations'])) {
            $this->DisplayBareRelations($oPage, true);
            // Edit mode, will fill $this->aFieldsMap
            $aFieldsMap = array_merge($aFieldsMap, $this->aFieldsMap);
        }
        $oPage->SetCurrentTab('');
        $oPage->add("<input type=\"hidden\" name=\"class\" value=\"{$sClass}\">\n");
        $oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"{$iTransactionId}\">\n");
        foreach ($aExtraParams as $sName => $value) {
            if (is_scalar($value)) {
                $oPage->add("<input type=\"hidden\" name=\"{$sName}\" value=\"{$value}\">\n");
            }
        }
        if ($sOwnershipToken !== null) {
            $oPage->add("<input type=\"hidden\" name=\"ownership_token\" value=\"" . htmlentities($sOwnershipToken, ENT_QUOTES, 'UTF-8') . "\">\n");
        }
        $oPage->add($oAppContext->GetForForm());
        if ($sButtonsPosition != 'top') {
            // bottom or both: display the buttons here
            $oPage->p($sStatesSelection);
            $oPage->add($sButtons);
        }
        // Hook the cancel button via jQuery so that it can be unhooked easily as well if needed
        $sDefaultUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=cancel&' . $oAppContext->GetForLink();
        $oPage->add_ready_script("\$('#form_{$this->m_iFormId} button.cancel').click( function() { BackToDetails('{$sClass}', {$iKey}, '{$sDefaultUrl}', {$sJSToken})} );");
        $oPage->add("</form>\n");
        if (isset($aExtraParams['wizard_container']) && $aExtraParams['wizard_container']) {
            $oPage->add("</div>\n");
        }
        $iFieldsCount = count($aFieldsMap);
        $sJsonFieldsMap = json_encode($aFieldsMap);
        $sState = $this->GetState();
        $sSessionStorageKey = $sClass . '_' . $iKey;
        $oPage->add_script(<<<EOF
\t\tsessionStorage.removeItem('{$sSessionStorageKey}');
\t\t
\t\t// Create the object once at the beginning of the page...
\t\tvar oWizardHelper{$sPrefix} = new WizardHelper('{$sClass}', '{$sPrefix}', '{$sState}');
\t\toWizardHelper{$sPrefix}.SetFieldsMap({$sJsonFieldsMap});
\t\toWizardHelper{$sPrefix}.SetFieldsCount({$iFieldsCount});
EOF
);
        $oPage->add_ready_script(<<<EOF
\t\toWizardHelper{$sPrefix}.UpdateWizard();
\t\t// Starts the validation when the page is ready
\t\tCheckFields('form_{$this->m_iFormId}', false);

EOF
);
        if ($sOwnershipToken !== null) {
            $this->GetOwnershipJSHandler($oPage, $sOwnershipToken);
        } else {
            // Probably a new object (or no concurrent lock), let's add a watchdog so that the session is kept open while editing
            $iInterval = MetaModel::GetConfig()->Get('concurrent_lock_expiration_delay') * 1000 / 2;
            if ($iInterval > 0) {
                $iInterval = max(MIN_WATCHDOG_INTERVAL * 1000, $iInterval);
                // Minimum interval for the watchdog is MIN_WATCHDOG_INTERVAL
                $oPage->add_ready_script(<<<EOF
\t\t\t\twindow.setInterval(function() {
\t\t\t\t\t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', {operation: 'watchdog'});
\t\t\t\t}, {$iInterval});
EOF
);
            }
        }
    }
    protected function RenderChart($oPage, $sId, $aValues, $sDrillDown = '', $aRows = array())
    {
        // 1- Compute Open Flash Chart data
        //
        $aValueKeys = array();
        $index = 0;
        if (count($aValues) > 0 && $sDrillDown != '') {
            $oFilter = DBObjectSearch::FromOQL($sDrillDown);
            $sClass = $oFilter->GetClass();
            $sOQLClause = str_replace('SELECT ' . $sClass, '', $sDrillDown);
            $aSQLColNames = array_keys(current($aRows));
            // Read the list of columns from the current (i.e. first) element of the array
            $oAppContext = new ApplicationContext();
            $sURL = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=search_oql&search_form=0&oql_class=' . $sClass . '&format=html&' . $oAppContext->GetForLink() . '&oql_clause=';
        }
        $aURLs = array();
        foreach ($aValues as $key => $value) {
            // Make sure that values are integers (so that max() will work....)
            // and build an array of STRING with the keys (numeric keys are transformed into string by PHP :-(
            $aValues[$key] = (int) $value;
            $aValueKeys[] = (string) $key;
            // Build the custom query for the 'drill down' on each element
            if ($sDrillDown != '') {
                $sFilter = $sOQLClause;
                foreach ($aSQLColNames as $sColName) {
                    $sFilter = str_replace(':' . $sColName, "'" . addslashes($aRows[$key][$sColName]) . "'", $sFilter);
                    $aURLs[$index] = $sURL . urlencode($sFilter);
                }
            }
            $index++;
        }
        $oChart = new open_flash_chart();
        if ($this->m_sType == 'bars') {
            $oChartElement = new bar_glass();
            if (count($aValues) > 0) {
                $maxValue = max($aValues);
            } else {
                $maxValue = 1;
            }
            $oYAxis = new y_axis();
            $aMagicValues = array(1, 2, 5, 10);
            $iMultiplier = 1;
            $index = 0;
            $iTop = $aMagicValues[$index % count($aMagicValues)] * $iMultiplier;
            while ($maxValue > $iTop) {
                $index++;
                $iTop = $aMagicValues[$index % count($aMagicValues)] * $iMultiplier;
                if ($index % count($aMagicValues) == 0) {
                    $iMultiplier = $iMultiplier * 10;
                }
            }
            //echo "oYAxis->set_range(0, $iTop, $iMultiplier);\n";
            $oYAxis->set_range(0, $iTop, $iMultiplier);
            $oChart->set_y_axis($oYAxis);
            $aBarValues = array();
            foreach ($aValues as $iValue) {
                $oBarValue = new bar_value($iValue);
                $oBarValue->on_click("ofc_drilldown_{$sId}");
                $aBarValues[] = $oBarValue;
            }
            $oChartElement->set_values($aBarValues);
            //$oChartElement->set_values(array_values($aValues));
            $oXAxis = new x_axis();
            $oXLabels = new x_axis_labels();
            // set them vertical
            $oXLabels->set_vertical();
            // set the label text
            $oXLabels->set_labels($aValueKeys);
            // Add the X Axis Labels to the X Axis
            $oXAxis->set_labels($oXLabels);
            $oChart->set_x_axis($oXAxis);
        } else {
            $oChartElement = new pie();
            $oChartElement->set_start_angle(35);
            $oChartElement->set_animate(true);
            $oChartElement->set_tooltip('#label# - #val# (#percent#)');
            $oChartElement->set_colours(array('#FF8A00', '#909980', '#2C2B33', '#CCC08D', '#596664'));
            $aData = array();
            foreach ($aValues as $sValue => $iValue) {
                $oPieValue = new pie_value($iValue, $sValue);
                //@@ BUG: not passed via ajax !!!
                $oPieValue->on_click("ofc_drilldown_{$sId}");
                $aData[] = $oPieValue;
            }
            $oChartElement->set_values($aData);
            $oChart->x_axis = null;
        }
        // Title given in HTML
        //$oTitle = new title($this->m_sTitle);
        //$oChart->set_title($oTitle);
        $oChart->set_bg_colour('#FFFFFF');
        $oChart->add_element($oChartElement);
        $sData = $oChart->toPrettyString();
        $sData = json_encode($sData);
        // 2- Declare the Javascript function that will render the chart data\
        //
        $oPage->add_script(<<<EOF
function ofc_get_data_{$sId}()
{
\treturn {$sData};
}
EOF
);
        if (count($aURLs) > 0) {
            $sURLList = '';
            foreach ($aURLs as $index => $sURL) {
                $sURLList .= "\taURLs[{$index}] = '" . addslashes($sURL) . "';\n";
            }
            $oPage->add_script(<<<EOF
function ofc_drilldown_{$sId}(index)
{
\tvar aURLs = new Array();
{$sURLList}
\tvar sURL = aURLs[index];
\t
\twindow.location.href = sURL; // Navigate ! 
}
EOF
);
        }
        // 3- Insert the Open Flash chart
        //
        $oPage->add("<div id=\"{$sId}\"><div>\n");
        $oPage->add_ready_script(<<<EOF
swfobject.embedSWF(\t"../images/open-flash-chart.swf", 
\t"{$sId}", 
\t"100%", "300","9.0.0",
\t"expressInstall.swf",
\t{"get-data":"ofc_get_data_{$sId}", "id":"{$sId}"}, 
\t{'wmode': 'transparent'}
);
EOF
);
    }
Esempio n. 4
0
    /**
     * 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 .= '&nbsp;<b>' . $sRestrictions . '</b>';
                if (strlen($sAdminMessage) > 0) {
                    $sApplicationBanner .= '&nbsp;<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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<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 DisplayModifyForm(WebPage $oPage, $aExtraParams = array())
    {
        self::$iGlobalFormId++;
        $this->aFieldsMap = array();
        $sPrefix = '';
        if (isset($aExtraParams['formPrefix'])) {
            $sPrefix = $aExtraParams['formPrefix'];
        }
        $aFieldsComments = isset($aExtraParams['fieldsComments']) ? $aExtraParams['fieldsComments'] : array();
        $this->m_iFormId = $sPrefix . self::$iGlobalFormId;
        $sClass = get_class($this);
        $oAppContext = new ApplicationContext();
        $sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
        $iKey = $this->GetKey();
        $aDetails = array();
        $aFieldsMap = array();
        if (!isset($aExtraParams['action'])) {
            $sFormAction = $_SERVER['SCRIPT_NAME'];
            // No parameter in the URL, the only parameter will be the ones passed through the form
        } else {
            $sFormAction = $aExtraParams['action'];
        }
        // Custom label for the apply button ?
        if (isset($aExtraParams['custom_button'])) {
            $sApplyButton = $aExtraParams['custom_button'];
        } else {
            if ($iKey > 0) {
                $sApplyButton = Dict::S('UI:Button:Apply');
            } else {
                $sApplyButton = Dict::S('UI:Button:Create');
            }
        }
        // Custom operation for the form ?
        if (isset($aExtraParams['custom_operation'])) {
            $sOperation = $aExtraParams['custom_operation'];
        } else {
            if ($iKey > 0) {
                $sOperation = 'apply_modify';
            } else {
                $sOperation = 'apply_new';
            }
        }
        if ($iKey > 0) {
            // The object already exists in the database, it's a modification
            $sButtons = "<input id=\"{$sPrefix}_id\" type=\"hidden\" name=\"id\" value=\"{$iKey}\">\n";
            $sButtons .= "<input type=\"hidden\" name=\"operation\" value=\"{$sOperation}\">\n";
            $sButtons .= "<button type=\"button\" class=\"action cancel\"><span>" . Dict::S('UI:Button:Cancel') . "</span></button>&nbsp;&nbsp;&nbsp;&nbsp;\n";
            $sButtons .= "<button type=\"submit\" class=\"action\"><span>{$sApplyButton}</span></button>\n";
        } else {
            // The object does not exist in the database it's a creation
            $sButtons = "<input type=\"hidden\" name=\"operation\" value=\"{$sOperation}\">\n";
            $sButtons .= "<button type=\"button\" class=\"action cancel\">" . Dict::S('UI:Button:Cancel') . "</button>&nbsp;&nbsp;&nbsp;&nbsp;\n";
            $sButtons .= "<button type=\"submit\" class=\"action\"><span>{$sApplyButton}</span></button>\n";
        }
        $aTransitions = $this->EnumTransitions();
        if (!isset($aExtraParams['custom_operation']) && count($aTransitions)) {
            // transitions are displayed only for the standard new/modify actions, not for modify_all or any other case...
            $oSetToCheckRights = DBObjectSet::FromObject($this);
            $aStimuli = Metamodel::EnumStimuli($sClass);
            foreach ($aTransitions as $sStimulusCode => $aTransitionDef) {
                $iActionAllowed = get_class($aStimuli[$sStimulusCode]) == 'StimulusUserAction' ? UserRights::IsStimulusAllowed($sClass, $sStimulusCode, $oSetToCheckRights) : UR_ALLOWED_NO;
                switch ($iActionAllowed) {
                    case UR_ALLOWED_YES:
                        $sButtons .= "<button type=\"submit\" name=\"next_action\" value=\"{$sStimulusCode}\" class=\"action\"><span>" . $aStimuli[$sStimulusCode]->GetLabel() . "</span></button>\n";
                        break;
                    default:
                        // Do nothing
                }
            }
        }
        $sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position');
        $iTransactionId = isset($aExtraParams['transaction_id']) ? $aExtraParams['transaction_id'] : utils::GetNewTransactionId();
        $oPage->SetTransactionId($iTransactionId);
        $oPage->add("<form action=\"{$sFormAction}\" id=\"form_{$this->m_iFormId}\" enctype=\"multipart/form-data\" method=\"post\" onSubmit=\"return OnSubmit('form_{$this->m_iFormId}');\">\n");
        $sStatesSelection = '';
        if (!isset($aExtraParams['custom_operation']) && $this->IsNew()) {
            $aInitialStates = MetaModel::EnumInitialStates($sClass);
            //$aInitialStates = array('new' => 'foo', 'closed' => 'bar');
            if (count($aInitialStates) > 1) {
                $sStatesSelection = Dict::Format('UI:Create_Class_InState', MetaModel::GetName($sClass)) . '<select name="obj_state" class="state_select_' . $this->m_iFormId . '">';
                foreach ($aInitialStates as $sStateCode => $sStateData) {
                    $sSelected = '';
                    if ($sStateCode == $this->GetState()) {
                        $sSelected = ' selected';
                    }
                    $sStatesSelection .= '<option value="' . $sStateCode . '"' . $sSelected . '>' . MetaModel::GetStateLabel($sClass, $sStateCode) . '</option>';
                }
                $sStatesSelection .= '</select>';
                $oPage->add_ready_script("\$('.state_select_{$this->m_iFormId}').change( function() { oWizardHelper{$sPrefix}.ReloadObjectCreationForm('form_{$this->m_iFormId}', \$(this).val()); } );");
            }
        }
        $sConfirmationMessage = addslashes(Dict::S('UI:NavigateAwayConfirmationMessage'));
        $oPage->add_ready_script(<<<EOF
\t\$(window).unload(function() { return OnUnload('{$iTransactionId}') } );
\twindow.onbeforeunload = function() {
\t\tif (!window.bInSubmit && !window.bInCancel)
\t\t{
\t\t\treturn '{$sConfirmationMessage}';\t
\t\t}
\t\t// return nothing ! safer for IE
\t};
EOF
);
        if ($sButtonsPosition != 'bottom') {
            // top or both, display the buttons here
            $oPage->p($sStatesSelection);
            $oPage->add($sButtons);
        }
        $oPage->AddTabContainer(OBJECT_PROPERTIES_TAB, $sPrefix);
        $oPage->SetCurrentTabContainer(OBJECT_PROPERTIES_TAB);
        $oPage->SetCurrentTab(Dict::S('UI:PropertiesTab'));
        $aFieldsMap = $this->DisplayBareProperties($oPage, true, $sPrefix, $aExtraParams);
        if ($iKey > 0) {
            $aFieldsMap['id'] = $sPrefix . '_id';
        }
        // Now display the relations, one tab per relation
        if (!isset($aExtraParams['noRelations'])) {
            $this->DisplayBareRelations($oPage, true);
            // Edit mode, will fill $this->aFieldsMap
            $aFieldsMap = array_merge($aFieldsMap, $this->aFieldsMap);
        }
        $oPage->SetCurrentTab('');
        $oPage->add("<input type=\"hidden\" name=\"class\" value=\"{$sClass}\">\n");
        $oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"{$iTransactionId}\">\n");
        foreach ($aExtraParams as $sName => $value) {
            if (is_scalar($value)) {
                $oPage->add("<input type=\"hidden\" name=\"{$sName}\" value=\"{$value}\">\n");
            }
        }
        $oPage->add($oAppContext->GetForForm());
        if ($sButtonsPosition != 'top') {
            // bottom or both: display the buttons here
            $oPage->p($sStatesSelection);
            $oPage->add($sButtons);
        }
        // Hook the cancel button via jQuery so that it can be unhooked easily as well if needed
        $sDefaultUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=cancel&' . $oAppContext->GetForLink();
        $oPage->add_ready_script("\$('#form_{$this->m_iFormId} button.cancel').click( function() { BackToDetails('{$sClass}', {$iKey}, '{$sDefaultUrl}')} );");
        $oPage->add("</form>\n");
        $iFieldsCount = count($aFieldsMap);
        $sJsonFieldsMap = json_encode($aFieldsMap);
        $sState = $this->GetState();
        $oPage->add_script(<<<EOF
\t\t// Create the object once at the beginning of the page...
\t\tvar oWizardHelper{$sPrefix} = new WizardHelper('{$sClass}', '{$sPrefix}', '{$sState}');
\t\toWizardHelper{$sPrefix}.SetFieldsMap({$sJsonFieldsMap});
\t\toWizardHelper{$sPrefix}.SetFieldsCount({$iFieldsCount});
EOF
);
        $oPage->add_ready_script(<<<EOF
\t\toWizardHelper{$sPrefix}.UpdateWizard();
\t\t// Starts the validation when the page is ready
\t\tCheckFields('form_{$this->m_iFormId}', false);

EOF
);
    }
    /**
     * Display the graph inside the given page, with the "filter" drawer above it
     * @param WebPage $oP
     * @param hash $aResults
     * @param string $sRelation
     * @param ApplicationContext $oAppContext
     * @param array $aExcludedObjects
     */
    function Display(WebPage $oP, $aResults, $sRelation, ApplicationContext $oAppContext, $aExcludedObjects = array(), $sObjClass = null, $iObjKey = null, $sContextKey, $aContextParams = array())
    {
        $aContextDefs = static::GetContextDefinitions($sContextKey, true, $aContextParams);
        $aExcludedByClass = array();
        foreach ($aExcludedObjects as $oObj) {
            if (!array_key_exists(get_class($oObj), $aExcludedByClass)) {
                $aExcludedByClass[get_class($oObj)] = array();
            }
            $aExcludedByClass[get_class($oObj)][] = $oObj->GetKey();
        }
        $oP->add("<div class=\"not-printable\">\n");
        $oP->add("<div id=\"ds_flash\" class=\"SearchDrawer\" style=\"display:none;\">\n");
        if (!$oP->IsPrintableVersion()) {
            $oP->add_ready_script(<<<EOF
\t\$( "#tabbedContent_0" ).tabs({ heightStyle: "fill" });
EOF
);
        }
        $oP->add_ready_script(<<<EOF
\t\$("#dh_flash").click( function() {
\t\t\$("#ds_flash").slideToggle('normal', function() { \$("#ds_flash").parent().resize(); \$("#dh_flash").trigger('toggle_complete'); } );
\t\t\$("#dh_flash").toggleClass('open');
\t});
    \$('#ReloadMovieBtn').button().button('disable');
EOF
);
        $aSortedElements = array();
        foreach ($aResults as $sClassIdx => $aObjects) {
            foreach ($aObjects as $oCurrObj) {
                $sSubClass = get_class($oCurrObj);
                $aSortedElements[$sSubClass] = MetaModel::GetName($sSubClass);
            }
        }
        asort($aSortedElements);
        $idx = 0;
        foreach ($aSortedElements as $sSubClass => $sClassName) {
            $oP->add("<span style=\"padding-right:2em; white-space:nowrap;\"><input type=\"checkbox\" id=\"exclude_{$idx}\" name=\"excluded[]\" value=\"{$sSubClass}\" checked onChange=\"\$('#ReloadMovieBtn').button('enable')\"><label for=\"exclude_{$idx}\">&nbsp;" . MetaModel::GetClassIcon($sSubClass) . "&nbsp;{$sClassName}</label></span> ");
            $idx++;
        }
        $oP->add("<p style=\"text-align:right\"><button type=\"button\" id=\"ReloadMovieBtn\" onClick=\"DoReload()\">" . Dict::S('UI:Button:Refresh') . "</button></p>");
        $oP->add("</div>\n");
        $oP->add("<div class=\"HRDrawer\"></div>\n");
        $oP->add("<div id=\"dh_flash\" class=\"DrawerHandle\">" . Dict::S('UI:ElementsDisplayed') . "</div>\n");
        $oP->add("</div>\n");
        // class="not-printable"
        $aAdditionalContexts = array();
        foreach ($aContextDefs as $sKey => $aDefinition) {
            $aAdditionalContexts[] = array('key' => $sKey, 'label' => Dict::S($aDefinition['dict']), 'oql' => $aDefinition['oql'], 'default' => array_key_exists('default', $aDefinition) && $aDefinition['default'] == 'yes');
        }
        $sDirection = utils::ReadParam('d', 'horizontal');
        $iGroupingThreshold = utils::ReadParam('g', 5);
        $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/fraphael.js');
        $oP->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot() . 'css/jquery.contextMenu.css');
        $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.contextMenu.js');
        $oP->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/simple_graph.js');
        try {
            $this->InitFromGraphviz();
            $sExportAsPdfURL = '';
            $sExportAsPdfURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_pdf&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up');
            $oAppcontext = new ApplicationContext();
            $sContext = $oAppContext->GetForLink();
            $sDrillDownURL = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=details&class=%1$s&id=%2$s&' . $sContext;
            $sExportAsDocumentURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_attachment&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up');
            $sLoadFromURL = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=relation_json&relation=' . $sRelation . '&direction=' . ($this->bDirectionDown ? 'down' : 'up');
            $sAttachmentExportTitle = '';
            if ($sObjClass != null && $iObjKey != null) {
                $oTargetObj = MetaModel::GetObject($sObjClass, $iObjKey, false);
                if ($oTargetObj) {
                    $sAttachmentExportTitle = Dict::Format('UI:Relation:AttachmentExportOptions_Name', $oTargetObj->GetName());
                }
            }
            $sId = 'graph';
            $sStyle = '';
            if ($oP->IsPrintableVersion()) {
                // Optimize for printing on A4/Letter vertically
                $sStyle = 'margin-left:auto; margin-right:auto;';
                $oP->add_ready_script("\$('.simple-graph').width(18/2.54*96).resizable({ stop: function() { \$(window).trigger('resized'); }});");
                // Default width about 18 cm, since most browsers assume 96 dpi
            }
            $oP->add('<div id="' . $sId . '" class="simple-graph" style="' . $sStyle . '"></div>');
            $aParams = array('source_url' => $sLoadFromURL, 'sources' => $this->bDirectionDown ? $this->aSourceObjects : $this->aSinkObjects, 'excluded' => $aExcludedByClass, 'grouping_threshold' => $iGroupingThreshold, 'export_as_pdf' => array('url' => $sExportAsPdfURL, 'label' => Dict::S('UI:Relation:ExportAsPDF')), 'export_as_attachment' => array('url' => $sExportAsDocumentURL, 'label' => Dict::S('UI:Relation:ExportAsAttachment'), 'obj_class' => $sObjClass, 'obj_key' => $iObjKey), 'drill_down' => array('url' => $sDrillDownURL, 'label' => Dict::S('UI:Relation:DrillDown')), 'labels' => array('export_pdf_title' => Dict::S('UI:Relation:PDFExportOptions'), 'export_as_attachment_title' => $sAttachmentExportTitle, 'export' => Dict::S('UI:Button:Export'), 'cancel' => Dict::S('UI:Button:Cancel'), 'title' => Dict::S('UI:RelationOption:Title'), 'untitled' => Dict::S('UI:RelationOption:Untitled'), 'include_list' => Dict::S('UI:RelationOption:IncludeList'), 'comments' => Dict::S('UI:RelationOption:Comments'), 'grouping_threshold' => Dict::S('UI:RelationOption:GroupingThreshold'), 'refresh' => Dict::S('UI:Button:Refresh'), 'check_all' => Dict::S('UI:SearchValue:CheckAll'), 'uncheck_all' => Dict::S('UI:SearchValue:UncheckAll'), 'none_selected' => Dict::S('UI:Relation:NoneSelected'), 'nb_selected' => Dict::S('UI:SearchValue:NbSelected'), 'additional_context_info' => Dict::S('UI:Relation:AdditionalContextInfo'), 'zoom' => Dict::S('UI:Relation:Zoom'), 'loading' => Dict::S('UI:Loading')), 'page_format' => array('label' => Dict::S('UI:Relation:PDFExportPageFormat'), 'values' => array('A3' => Dict::S('UI:PageFormat_A3'), 'A4' => Dict::S('UI:PageFormat_A4'), 'Letter' => Dict::S('UI:PageFormat_Letter'))), 'page_orientation' => array('label' => Dict::S('UI:Relation:PDFExportPageOrientation'), 'values' => array('P' => Dict::S('UI:PageOrientation_Portrait'), 'L' => Dict::S('UI:PageOrientation_Landscape'))), 'additional_contexts' => $aAdditionalContexts, 'context_key' => $sContextKey);
            if (!extension_loaded('gd')) {
                // PDF export requires GD
                unset($aParams['export_as_pdf']);
            }
            if (!extension_loaded('gd') || is_null($sObjClass) || is_null($iObjKey)) {
                // Export as Attachment requires GD (for building the PDF) AND a valid objclass/objkey couple
                unset($aParams['export_as_attachment']);
            }
            $oP->add_ready_script("\$('#{$sId}').simple_graph(" . json_encode($aParams) . ");");
        } catch (Exception $e) {
            $oP->add('<div>' . $e->getMessage() . '</div>');
        }
        $oP->add_script(<<<EOF
\t\t
\tfunction DoReload()
\t{
\t\t\$('#ReloadMovieBtn').button('disable');
\t\ttry
\t\t{
\t\t\tvar aExcluded = [];
\t\t\t\$('input[name^=excluded]').each( function() {
\t\t\t\tif (!\$(this).prop('checked'))
\t\t\t\t{
\t\t\t\t\taExcluded.push(\$(this).val());
\t\t\t\t}
\t\t\t} );
\t\t\t\$('#graph').simple_graph('option', {excluded_classes: aExcluded});
\t\t\t\$('#graph').simple_graph('reload');
\t\t}
\t\tcatch(err)
\t\t{
\t\t\talert(err);
\t\t}
\t}
EOF
);
    }
Esempio n. 7
0
                $iDistance = $aQuery['iDistance'];
                if ($aQuery['bPropagate']) {
                    $oPage->add("<li>" . Dict::Format('UI:Schema:RelationPropagates', $sRelKey, $iDistance, $sQuery) . "</li>\n");
                } else {
                    $oPage->add("<li>" . Dict::Format('UI:Schema:RelationDoesNotPropagate', $sRelKey, $iDistance, $sQuery) . "</li>\n");
                }
            }
            $oPage->add("</ul>\n");
            $oPage->add("</li>\n");
        }
    }
    $oPage->add_ready_script('$("#RelationshipDetails").treeview();');
}
// Display the menu on the left
$oAppContext = new ApplicationContext();
$sContext = $oAppContext->GetForLink();
if (!empty($sContext)) {
    $sContext = '&' . $sContext;
}
$operation = utils::ReadParam('operation', '');
$oPage = new iTopWebPage(Dict::S('UI:Schema:Title'));
$oPage->no_cache();
$operation = utils::ReadParam('operation', '');
switch ($operation) {
    case 'details_class':
        $sClass = utils::ReadParam('class', 'logRealObject', false, 'class');
        DisplayClassDetails($oPage, $sClass, $sContext);
        break;
    case 'details_relation':
        $sRelCode = utils::ReadParam('relcode', '');
        DisplayRelationDetails($oPage, $sRelCode, $sContext);
    /**
     * Display the history of bulk imports
     */
    static function DisplayImportHistory(WebPage $oPage, $bFromAjax = false, $bShowAll = false)
    {
        $sAjaxDivId = "CSVImportHistory";
        if (!$bFromAjax) {
            $oPage->add('<div id="' . $sAjaxDivId . '">');
        }
        $oPage->p(Dict::S('UI:History:BulkImports+') . ' <span id="csv_history_reload"></span>');
        $oBulkChangeSearch = DBObjectSearch::FromOQL("SELECT CMDBChange WHERE origin IN ('csv-interactive', 'csv-import.php')");
        $iQueryLimit = $bShowAll ? 0 : appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
        $oBulkChanges = new DBObjectSet($oBulkChangeSearch, array('date' => false), array(), null, $iQueryLimit);
        $oAppContext = new ApplicationContext();
        $bLimitExceeded = false;
        if ($oBulkChanges->Count() > appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit())) {
            $bLimitExceeded = true;
            if (!$bShowAll) {
                $iMaxObjects = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
                $oBulkChanges->SetLimit($iMaxObjects);
            }
        }
        $oBulkChanges->Seek(0);
        $aDetails = array();
        while ($oChange = $oBulkChanges->Fetch()) {
            $sDate = '<a href="csvimport.php?step=10&changeid=' . $oChange->GetKey() . '&' . $oAppContext->GetForLink() . '">' . $oChange->Get('date') . '</a>';
            $sUser = $oChange->GetUserName();
            if (preg_match('/^(.*)\\(CSV\\)$/i', $oChange->Get('userinfo'), $aMatches)) {
                $sUser = $aMatches[1];
            } else {
                $sUser = $oChange->Get('userinfo');
            }
            $oOpSearch = DBObjectSearch::FromOQL("SELECT CMDBChangeOpCreate WHERE change = :change_id");
            $oOpSet = new DBObjectSet($oOpSearch, array(), array('change_id' => $oChange->GetKey()));
            $iCreated = $oOpSet->Count();
            // Get the class from the first item found (assumption: a CSV load is done for a single class)
            if ($oCreateOp = $oOpSet->Fetch()) {
                $sClass = $oCreateOp->Get('objclass');
            }
            $oOpSearch = DBObjectSearch::FromOQL("SELECT CMDBChangeOpSetAttribute WHERE change = :change_id");
            $oOpSet = new DBObjectSet($oOpSearch, array(), array('change_id' => $oChange->GetKey()));
            $aModified = array();
            $aAttList = array();
            while ($oModified = $oOpSet->Fetch()) {
                // Get the class (if not done earlier on object creation)
                $sClass = $oModified->Get('objclass');
                $iKey = $oModified->Get('objkey');
                $sAttCode = $oModified->Get('attcode');
                $aAttList[$sClass][$sAttCode] = true;
                $aModified["{$sClass}::{$iKey}"] = true;
            }
            $iModified = count($aModified);
            // Assumption: there is only one class of objects being loaded
            // Then the last class found gives us the class for every object
            if ($iModified > 0 || $iCreated > 0) {
                $aDetails[] = array('date' => $sDate, 'user' => $sUser, 'class' => $sClass, 'created' => $iCreated, 'modified' => $iModified);
            }
        }
        $aConfig = array('date' => array('label' => Dict::S('UI:History:Date'), 'description' => Dict::S('UI:History:Date+')), 'user' => array('label' => Dict::S('UI:History:User'), 'description' => Dict::S('UI:History:User+')), 'class' => array('label' => Dict::S('Core:AttributeClass'), 'description' => Dict::S('Core:AttributeClass+')), 'created' => array('label' => Dict::S('UI:History:StatsCreations'), 'description' => Dict::S('UI:History:StatsCreations+')), 'modified' => array('label' => Dict::S('UI:History:StatsModifs'), 'description' => Dict::S('UI:History:StatsModifs+')));
        if ($bLimitExceeded) {
            if ($bShowAll) {
                // Collapsible list
                $oPage->add('<p>' . Dict::Format('UI:CountOfResults', $oBulkChanges->Count()) . '&nbsp;&nbsp;<a class="truncated" onclick="OnTruncatedHistoryToggle(false);">' . Dict::S('UI:CollapseList') . '</a></p>');
            } else {
                // Truncated list
                $iMinDisplayLimit = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
                $sCollapsedLabel = Dict::Format('UI:TruncatedResults', $iMinDisplayLimit, $oBulkChanges->Count());
                $sLinkLabel = Dict::S('UI:DisplayAll');
                $oPage->add('<p>' . $sCollapsedLabel . '&nbsp;&nbsp;<a class="truncated" onclick="OnTruncatedHistoryToggle(true);">' . $sLinkLabel . '</p>');
                $oPage->add_ready_script(<<<EOF
\t\$('#{$sAjaxDivId} table.listResults').addClass('truncated');
\t\$('#{$sAjaxDivId} table.listResults tr:last td').addClass('truncated');
EOF
);
                $sAppContext = $oAppContext->GetForLink();
                $oPage->add_script(<<<EOF
\tfunction OnTruncatedHistoryToggle(bShowAll)
\t{
\t\t\$('#csv_history_reload').html('<img src="../images/indicator.gif"/>');
\t\t\$.get(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?{$sAppContext}', {operation: 'displayCSVHistory', showall: bShowAll}, function(data)
\t\t\t{
\t\t\t\t\$('#{$sAjaxDivId}').html(data);
\t\t\t\tvar table = \$('#{$sAjaxDivId} .listResults');
\t\t\t\ttable.tableHover(); // hover tables
\t\t\t\ttable.tablesorter( { widgets: ['myZebra', 'truncatedList']} ); // sortable and zebra tables
\t\t\t}
\t\t);
\t}
EOF
);
            }
        } else {
            // Normal display - full list without any decoration
        }
        $oPage->table($aConfig, $aDetails);
        if (!$bFromAjax) {
            $oPage->add('</div>');
        }
    }
 protected function DisplayEditInPlace(WebPage $oPage, DBObjectSet $oValue, $aArgs = array(), $sFormPrefix, $oCurrentObj, $aButtons = array('create', 'delete'))
 {
     $aAttribs = $this->GetTableConfig();
     $oValue->Rewind();
     $oPage->add('<table class="listContainer" id="' . $this->sInputid . '"><tr><td>');
     $aData = array();
     while ($oLinkObj = $oValue->Fetch()) {
         $aRow = array();
         $aRow['form::select'] = '<input type="checkbox" class="selectList' . $this->sInputid . '" value="' . $oLinkObj->GetKey() . '"/>';
         foreach ($this->aZlist as $sLinkedAttCode) {
             $aRow[$sLinkedAttCode] = $oLinkObj->GetAsHTML($sLinkedAttCode);
         }
         $aData[] = $aRow;
     }
     $oPage->table($aAttribs, $aData);
     $oPage->add('</td></tr></table>');
     //listcontainer
     $sInputName = $sFormPrefix . 'attr_' . $this->sAttCode;
     $aLabels = array('delete' => Dict::S('UI:Button:Delete'), 'creation_title' => Dict::Format('UI:CreationTitle_Class', MetaModel::GetName($this->sLinkedClass)), 'create' => Dict::Format('UI:ClickToCreateNew', MetaModel::GetName($this->sLinkedClass)), 'remove' => Dict::S('UI:Button:Remove'), 'add' => Dict::Format('UI:AddAnExisting_Class', MetaModel::GetName($this->sLinkedClass)), 'selection_title' => Dict::Format('UI:SelectionOf_Class', MetaModel::GetName($this->sLinkedClass)));
     $oContext = new ApplicationContext();
     $sSubmitUrl = utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?' . $oContext->GetForLink();
     $sJSONLabels = json_encode($aLabels);
     $sJSONButtons = json_encode($aButtons);
     $sWizHelper = 'oWizardHelper' . $sFormPrefix;
     $oPage->add_ready_script("\$('#{$this->sInputid}').directlinks({class_name: '{$this->sClass}', att_code: '{$this->sAttCode}', input_name:'{$sInputName}', labels: {$sJSONLabels}, submit_to: '{$sSubmitUrl}', buttons: {$sJSONButtons}, oWizardHelper: {$sWizHelper} });");
 }
 /**
  * Get the current application url provider
  * @return string the name of the class
  */
 public static function MakeObjectUrl($sObjClass, $sObjKey, $sUrlMakerClass = null, $bWithNavigationContext = true)
 {
     $oAppContext = new ApplicationContext();
     if (is_null($sUrlMakerClass)) {
         $sUrlMakerClass = self::GetUrlMakerClass();
     }
     $sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
     if (strlen($sUrl) > 0) {
         if ($bWithNavigationContext) {
             return $sUrl . "&" . $oAppContext->GetForLink();
         } else {
             return $sUrl;
         }
     } else {
         return '';
     }
 }
Esempio n. 11
0
 /**
  * Merge standard menu items with plugin provided menus items
  */
 public static function GetPopupMenuItems($oPage, $iMenuId, $param, &$aActions, $sTableId = null, $sDataTableId = null)
 {
     // 1st - add standard built-in menu items
     //
     switch ($iMenuId) {
         case iPopupMenuExtension::MENU_OBJLIST_TOOLKIT:
             // $param is a DBObjectSet
             $oAppContext = new ApplicationContext();
             $sContext = $oAppContext->GetForLink();
             $sDataTableId = is_null($sDataTableId) ? '' : $sDataTableId;
             $sUIPage = cmdbAbstractObject::ComputeStandardUIPage($param->GetFilter()->GetClass());
             $sOQL = addslashes($param->GetFilter()->ToOQL(true));
             $sFilter = urlencode($param->GetFilter()->serialize());
             $sUrl = utils::GetAbsoluteUrlAppRoot() . "pages/{$sUIPage}?operation=search&filter=" . $sFilter . "&{$sContext}";
             $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/tabularfieldsselector.js');
             $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.dragtable.js');
             $oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot() . 'css/dragtable.css');
             $aResult = array(new SeparatorPopupMenuItem(), new URLPopupMenuItem('UI:Menu:EMail', Dict::S('UI:Menu:EMail'), "mailto:?body=" . urlencode($sUrl) . ' '));
             if (UserRights::IsActionAllowed($param->GetFilter()->GetClass(), UR_ACTION_BULK_READ, $param) && (UR_ALLOWED_YES || UR_ALLOWED_DEPENDS)) {
                 // Bulk export actions
                 $aResult[] = new JSPopupMenuItem('UI:Menu:CSVExport', Dict::S('UI:Menu:CSVExport'), "ExportListDlg('{$sOQL}', '{$sDataTableId}', 'csv', " . json_encode(Dict::S('UI:Menu:CSVExport')) . ")");
                 $aResult[] = new JSPopupMenuItem('UI:Menu:ExportXLSX', Dict::S('ExcelExporter:ExportMenu'), "ExportListDlg('{$sOQL}', '{$sDataTableId}', 'xlsx', " . json_encode(Dict::S('ExcelExporter:ExportMenu')) . ")");
                 $aResult[] = new JSPopupMenuItem('UI:Menu:ExportPDF', Dict::S('UI:Menu:ExportPDF'), "ExportListDlg('{$sOQL}', '{$sDataTableId}', 'pdf', " . json_encode(Dict::S('UI:Menu:ExportPDF')) . ")");
             }
             $aResult[] = new JSPopupMenuItem('UI:Menu:AddToDashboard', Dict::S('UI:Menu:AddToDashboard'), "DashletCreationDlg('{$sOQL}')");
             $aResult[] = new JSPopupMenuItem('UI:Menu:ShortcutList', Dict::S('UI:Menu:ShortcutList'), "ShortcutListDlg('{$sOQL}', '{$sDataTableId}', '{$sContext}')");
             break;
         case iPopupMenuExtension::MENU_OBJDETAILS_ACTIONS:
             // $param is a DBObject
             $oObj = $param;
             $sOQL = "SELECT " . get_class($oObj) . " WHERE id=" . $oObj->GetKey();
             $oFilter = DBObjectSearch::FromOQL($sOQL);
             $sFilter = $oFilter->serialize();
             $sUrl = ApplicationContext::MakeObjectUrl(get_class($oObj), $oObj->GetKey());
             $sUIPage = cmdbAbstractObject::ComputeStandardUIPage(get_class($oObj));
             $oAppContext = new ApplicationContext();
             $sContext = $oAppContext->GetForLink();
             $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/tabularfieldsselector.js');
             $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.dragtable.js');
             $oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot() . 'css/dragtable.css');
             $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/tabularfieldsselector.js');
             $oPage->add_linked_script(utils::GetAbsoluteUrlAppRoot() . 'js/jquery.dragtable.js');
             $oPage->add_linked_stylesheet(utils::GetAbsoluteUrlAppRoot() . 'css/dragtable.css');
             $aResult = array(new SeparatorPopupMenuItem(), new URLPopupMenuItem('UI:Menu:EMail', Dict::S('UI:Menu:EMail'), "mailto:?subject=" . urlencode($oObj->GetRawName()) . "&body=" . urlencode($sUrl) . ' '), new JSPopupMenuItem('UI:Menu:CSVExport', Dict::S('UI:Menu:CSVExport'), "ExportListDlg('{$sOQL}', '', 'csv', " . json_encode(Dict::S('UI:Menu:CSVExport')) . ")"), new JSPopupMenuItem('UI:Menu:ExportXLSX', Dict::S('ExcelExporter:ExportMenu'), "ExportListDlg('{$sOQL}', '', 'xlsx', " . json_encode(Dict::S('ExcelExporter:ExportMenu')) . ")"));
             break;
         case iPopupMenuExtension::MENU_DASHBOARD_ACTIONS:
             // $param is a Dashboard
             $oAppContext = new ApplicationContext();
             $aParams = $oAppContext->GetAsHash();
             $sMenuId = ApplicationMenu::GetActiveNodeId();
             $sDlgTitle = addslashes(Dict::S('UI:ImportDashboardTitle'));
             $sDlgText = addslashes(Dict::S('UI:ImportDashboardText'));
             $sCloseBtn = addslashes(Dict::S('UI:Button:Cancel'));
             $aResult = array(new SeparatorPopupMenuItem(), new URLPopupMenuItem('UI:ExportDashboard', Dict::S('UI:ExportDashBoard'), utils::GetAbsoluteUrlAppRoot() . 'pages/ajax.render.php?operation=export_dashboard&id=' . $sMenuId), new JSPopupMenuItem('UI:ImportDashboard', Dict::S('UI:ImportDashBoard'), "UploadDashboard({dashboard_id: '{$sMenuId}', title: '{$sDlgTitle}', text: '{$sDlgText}', close_btn: '{$sCloseBtn}' })"));
             break;
         default:
             // Unknown type of menu, do nothing
             $aResult = array();
     }
     foreach ($aResult as $oMenuItem) {
         $aActions[$oMenuItem->GetUID()] = $oMenuItem->GetMenuItem();
     }
     // Invoke the plugins
     //
     foreach (MetaModel::EnumPlugins('iPopupMenuExtension') as $oExtensionInstance) {
         if (is_object($param) && !$param instanceof DBObject) {
             $tmpParam = clone $param;
             // In case the parameter is an DBObjectSet, clone it to prevent alterations
         } else {
             $tmpParam = $param;
         }
         foreach ($oExtensionInstance->EnumItems($iMenuId, $tmpParam) as $oMenuItem) {
             if (is_object($oMenuItem)) {
                 $aActions[$oMenuItem->GetUID()] = $oMenuItem->GetMenuItem();
                 foreach ($oMenuItem->GetLinkedScripts() as $sLinkedScript) {
                     $oPage->add_linked_script($sLinkedScript);
                 }
             }
         }
     }
 }
Esempio n. 12
0
    public static function GetCreationDlgFromOQL($oPage, $sOQL, $sTableSettings)
    {
        $oPage->add('<div id="shortcut_creation_dlg">');
        $oForm = self::GetCreationForm($sOQL, $sTableSettings);
        $oForm->Render($oPage);
        $oPage->add('</div>');
        $sDialogTitle = Dict::S('UI:ShortcutListDlg:Title');
        $sOkButtonLabel = Dict::S('UI:Button:Ok');
        $sCancelButtonLabel = Dict::S('UI:Button:Cancel');
        $oAppContext = new ApplicationContext();
        $sContext = $oAppContext->GetForLink();
        $sRateTitle = addslashes(Dict::S('Class:ShortcutOQL/Attribute:auto_reload_sec+'));
        $oPage->add_ready_script(<<<EOF

// Note: the title gets deleted by the validation mechanism
\$("#attr_auto_reload_sec").tooltip({items: 'input', content: '{$sRateTitle}'});
\$("#attr_auto_reload_sec").prop('disabled', !\$('#attr_auto_reload').is(':checked'));

\$('#attr_auto_reload').change( function(ev) {
\t\$("#attr_auto_reload_sec").prop('disabled', !\$(this).is(':checked'));
} );

function ShortcutCreationOK() 
{
\tvar oForm = \$('#shortcut_creation_dlg form');
\tvar sFormId = oForm.attr('id');
\tvar oParams = null;
\tvar aErrors = ValidateForm(sFormId, false);
\tif (aErrors.length == 0)
\t{
\t\toParams = ReadFormParams(sFormId);
\t}
\toParams.operation = 'shortcut_list_create';
\tvar me = \$('#shortcut_creation_dlg');
\t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php?{$sContext}', oParams, function(data) {
\t\tme.dialog( "close" );
\t\tme.remove();
\t\t\$('body').append(data);
\t});
}

\$('#shortcut_creation_dlg form').bind('submit', function() { ShortcutCreationOK(); return false; });

\$('#shortcut_creation_dlg').dialog({
\twidth: 400,
\tmodal: true,
\ttitle: '{$sDialogTitle}',
\tbuttons: [
\t{ text: "{$sOkButtonLabel}", click: ShortcutCreationOK },
\t{ text: "{$sCancelButtonLabel}", click: function() {
\t\t\$(this).dialog( "close" ); \$(this).remove();
\t} },
\t],
\tclose: function() { \$(this).remove(); }
});
EOF
);
    }
    public function __construct($sTitle, $sAlternateStyleSheet = '')
    {
        $this->m_sWelcomeMsg = '';
        $this->m_aMenuButtons = array();
        parent::__construct($sTitle);
        $this->add_header("Content-type: text/html; charset=utf-8");
        $this->add_header("Cache-control: no-cache");
        $this->add_linked_stylesheet("../css/jquery.treeview.css");
        $this->add_linked_stylesheet("../css/jquery.autocomplete.css");
        $this->add_linked_stylesheet("../css/jquery.multiselect.css");
        $sAbsURLAppRoot = addslashes(utils::GetAbsoluteUrlAppRoot());
        // Pass it to Javascript scripts
        $sAbsURLModulesRoot = addslashes(utils::GetAbsoluteUrlModulesRoot());
        // Pass it to Javascript scripts
        $oAppContext = new ApplicationContext();
        $sAppContext = addslashes($oAppContext->GetForLink());
        $this->add_dict_entry('UI:FillAllMandatoryFields');
        if ($sAlternateStyleSheet != '') {
            $this->add_linked_stylesheet("../portal/{$sAlternateStyleSheet}/portal.css");
        } else {
            $this->add_linked_stylesheet("../portal/portal.css");
        }
        $this->add_linked_script('../js/jquery.layout.min.js');
        $this->add_linked_script('../js/jquery.ba-bbq.min.js');
        $this->add_linked_script("../js/jquery.tablehover.js");
        $this->add_linked_script("../js/jquery.treeview.js");
        $this->add_linked_script("../js/jquery.autocomplete.js");
        $this->add_linked_script("../js/jquery.positionBy.js");
        $this->add_linked_script("../js/jquery.popupmenu.js");
        $this->add_linked_script("../js/date.js");
        $this->add_linked_script("../js/jquery.tablesorter.min.js");
        $this->add_linked_script("../js/jquery.tablesorter.pager.js");
        $this->add_linked_script("../js/jquery.blockUI.js");
        $this->add_linked_script("../js/utils.js");
        $this->add_linked_script("../js/forms-json-utils.js");
        $this->add_linked_script("../js/swfobject.js");
        $this->add_linked_script("../js/jquery.qtip-1.0.min.js");
        $this->add_linked_script('../js/jquery.multiselect.min.js');
        $this->add_linked_script("../js/ajaxfileupload.js");
        $this->add_ready_script(<<<EOF
try
{
\t//add new widget called TruncatedList to properly display truncated lists when they are sorted
\t\$.tablesorter.addWidget({ 
\t    // give the widget a id 
\t    id: "truncatedList", 
\t    // format is called when the on init and when a sorting has finished 
\t    format: function(table)
\t    { 
\t\t\t// Check if there is a "truncated" line
\t\t\tthis.truncatedList = false;  
\t\t\tif (\$("tr td.truncated",table).length > 0)
\t\t\t{
\t\t\t\tthis.truncatedList = true;
\t\t\t}
\t\t\tif (this.truncatedList)
\t\t\t{
\t\t\t\t\$("tr td",table).removeClass('truncated');
\t\t\t\t\$("tr:last td",table).addClass('truncated');
\t\t\t}
\t    } 
\t});
\t\t
\t
\t\$.tablesorter.addWidget({ 
\t    // give the widget a id 
\t    id: "myZebra", 
\t    // format is called when the on init and when a sorting has finished 
\t    format: function(table)
\t    {
\t    \t// Replace the 'red even' lines by 'red_even' since most browser do not support 2 classes selector in CSS, etc..
\t\t\t\$("tbody tr:even",table).addClass('even');
\t\t\t\$("tbody tr.red:even",table).removeClass('red').removeClass('even').addClass('red_even');
\t\t\t\$("tbody tr.orange:even",table).removeClass('orange').removeClass('even').addClass('orange_even');
\t\t\t\$("tbody tr.green:even",table).removeClass('green').removeClass('even').addClass('green_even');
\t    } 
\t});
\t\t
\t\$(".date-pick").datepicker({
\t\t\tshowOn: 'button',
\t\t\tbuttonImage: '../images/calendar.png',
\t\t\tbuttonImageOnly: true,
\t\t\tdateFormat: 'yy-mm-dd',
\t\t\tconstrainInput: false,
\t\t\tchangeMonth: true,
\t\t\tchangeYear: true
\t\t});

\t\$(".datetime-pick").datepicker({
\t\tshowOn: 'button',
\t\tbuttonImage: '../images/calendar.png',
\t\tbuttonImageOnly: true,
\t\tdateFormat: 'yy-mm-dd 00:00:00',
\t\tconstrainInput: false,
\t\tchangeMonth: true,
\t\tchangeYear: true
\t\t});

\t//\$('.resizable').resizable(); // Make resizable everything that claims to be resizable !
\t\$('.caselog_header').click( function () { \$(this).toggleClass('open').next('.caselog_entry').toggle(); });
}
catch(err)
{
\t// Do something with the error !
\talert(err);
}
EOF
);
        $this->add_script(<<<EOF
\tfunction CheckSelection(sMessage, sInputId)
\t{
\t\tvar bResult;
\t\tif (sInputId.length > 0)
\t\t{
\t\t\tbResult = (\$('input[name='+sInputId+']:checked').length > 0);
\t\t}
\t\telse
\t\t{
\t\t\t// First select found...
\t\t\tbResult = (\$('input:checked').length > 0);
\t\t}
\t\tif (!bResult)
\t\t{
\t\t\talert(sMessage);
\t\t}
\t\treturn bResult;
\t}

\t\t
\tfunction GetAbsoluteUrlAppRoot()
\t{
\t\treturn '{$sAbsURLAppRoot}';
\t}
\t
\tfunction GetAbsoluteUrlModulesRoot()
\t{
\t\treturn '{$sAbsURLModulesRoot}';
\t}

\tfunction AddAppContext(sURL)
\t{
\t\tvar sContext = '{$sAppContext}';
\t\tif (sContext.length > 0)
\t\t{
\t\t\tif (sURL.indexOf('?') == -1)
\t\t\t{
\t\t\t\treturn sURL+'?'+sContext;
\t\t\t}\t\t\t\t
\t\t\treturn sURL+'&'+sContext;
\t\t}
\t\treturn sURL;
\t}
\t
\tfunction GoBack(sFormId)
\t{
\t\tvar form = \$('#'+sFormId);
\t\tvar step_back = \$('input[name=step_back]');

\t\tform.unbind('submit'); // De-activate validation

\t\tstep_back.val(1);
\t\tform.submit(); // Go
\t}

\tfunction GoHome()
\t{
\t\tvar form = \$('FORM');
\t\tform.unbind('submit'); // De-activate validation
\t\twindow.location.href = '?operation=';
\t\treturn false;
\t}

\tfunction SetWizardNextStep(sStep)
\t{
\t\tvar next_step = \$('input[id=next_step]');
\t\tnext_step.val(sStep);
\t}
EOF
);
        // For Wizard helper to process the ajax replies
        $this->add('<div id="ajax_content"></div>');
        // Customize the logo (unless a customer CSS has been defined)
        if ($sAlternateStyleSheet == '') {
            if (file_exists(MODULESROOT . 'branding/portal-logo.png')) {
                $sDisplayIcon = utils::GetAbsoluteUrlModulesRoot() . 'branding/portal-logo.png';
                $this->add_style("div#portal #logo {background: url(\"{$sDisplayIcon}\") no-repeat scroll 0 0 transparent;}");
            }
        }
    }
    public function __construct($sTitle, $sAlternateStyleSheet = '')
    {
        $this->m_sWelcomeMsg = '';
        $this->m_aMenuButtons = array();
        parent::__construct($sTitle);
        $this->add_header("Content-type: text/html; charset=utf-8");
        $this->add_header("Cache-control: no-cache");
        $this->add_linked_stylesheet("../css/jquery.treeview.css");
        $this->add_linked_stylesheet("../css/jquery.autocomplete.css");
        $this->add_linked_stylesheet("../css/jquery.multiselect.css");
        $sAbsURLAppRoot = addslashes(utils::GetAbsoluteUrlAppRoot());
        // Pass it to Javascript scripts
        $sAbsURLModulesRoot = addslashes(utils::GetAbsoluteUrlModulesRoot());
        // Pass it to Javascript scripts
        $oAppContext = new ApplicationContext();
        $sAppContext = addslashes($oAppContext->GetForLink());
        $this->add_dict_entry('UI:FillAllMandatoryFields');
        if ($sAlternateStyleSheet != '') {
            $this->add_linked_stylesheet("../portal/{$sAlternateStyleSheet}/portal.css");
        } else {
            $this->add_linked_stylesheet("../portal/portal.css");
        }
        $this->add_linked_script('../js/jquery.layout.min.js');
        $this->add_linked_script('../js/jquery.ba-bbq.min.js');
        $this->add_linked_script("../js/jquery.tablehover.js");
        $this->add_linked_script("../js/jquery.treeview.js");
        $this->add_linked_script("../js/jquery.autocomplete.js");
        $this->add_linked_script("../js/jquery.positionBy.js");
        $this->add_linked_script("../js/jquery.popupmenu.js");
        $this->add_linked_script("../js/date.js");
        $this->add_linked_script("../js/jquery.tablesorter.min.js");
        $this->add_linked_script("../js/jquery.tablesorter.pager.js");
        $this->add_linked_script("../js/jquery.blockUI.js");
        $this->add_linked_script("../js/utils.js");
        $this->add_linked_script("../js/forms-json-utils.js");
        $this->add_linked_script("../js/swfobject.js");
        $this->add_linked_script("../js/jquery.qtip-1.0.min.js");
        $this->add_linked_script('../js/jquery.multiselect.js');
        $this->add_linked_script("../js/ajaxfileupload.js");
        $this->add_linked_script("../js/ckeditor/ckeditor.js");
        $this->add_linked_script("../js/ckeditor/adapters/jquery.js");
        $sJSDisconnectedMessage = json_encode(Dict::S('UI:DisconnectedDlgMessage'));
        $sJSTitle = json_encode(Dict::S('UI:DisconnectedDlgTitle'));
        $sJSLoginAgain = json_encode(Dict::S('UI:LoginAgain'));
        $sJSStayOnThePage = json_encode(Dict::S('UI:StayOnThePage'));
        $sJSDaysMin = json_encode(array(Dict::S('DayOfWeek-Sunday-Min'), Dict::S('DayOfWeek-Monday-Min'), Dict::S('DayOfWeek-Tuesday-Min'), Dict::S('DayOfWeek-Wednesday-Min'), Dict::S('DayOfWeek-Thursday-Min'), Dict::S('DayOfWeek-Friday-Min'), Dict::S('DayOfWeek-Saturday-Min')));
        $sJSMonthsShort = json_encode(array(Dict::S('Month-01-Short'), Dict::S('Month-02-Short'), Dict::S('Month-03-Short'), Dict::S('Month-04-Short'), Dict::S('Month-05-Short'), Dict::S('Month-06-Short'), Dict::S('Month-07-Short'), Dict::S('Month-08-Short'), Dict::S('Month-09-Short'), Dict::S('Month-10-Short'), Dict::S('Month-11-Short'), Dict::S('Month-12-Short')));
        $iFirstDayOfWeek = (int) Dict::S('Calendar-FirstDayOfWeek');
        $this->add_ready_script(<<<EOF
try
{
\t//add new widget called TruncatedList to properly display truncated lists when they are sorted
\t\$.tablesorter.addWidget({ 
\t    // give the widget a id 
\t    id: "truncatedList", 
\t    // format is called when the on init and when a sorting has finished 
\t    format: function(table)
\t    { 
\t\t\t// Check if there is a "truncated" line
\t\t\tthis.truncatedList = false;  
\t\t\tif (\$("tr td.truncated",table).length > 0)
\t\t\t{
\t\t\t\tthis.truncatedList = true;
\t\t\t}
\t\t\tif (this.truncatedList)
\t\t\t{
\t\t\t\t\$("tr td",table).removeClass('truncated');
\t\t\t\t\$("tr:last td",table).addClass('truncated');
\t\t\t}
\t    } 
\t});
\t\t
\t
\t\$.tablesorter.addWidget({ 
\t    // give the widget a id 
\t    id: "myZebra", 
\t    // format is called when the on init and when a sorting has finished 
\t    format: function(table)
\t    {
\t    \t// Replace the 'red even' lines by 'red_even' since most browser do not support 2 classes selector in CSS, etc..
\t\t\t\$("tbody tr:even",table).addClass('even');
\t\t\t\$("tbody tr.red:even",table).removeClass('red').removeClass('even').addClass('red_even');
\t\t\t\$("tbody tr.orange:even",table).removeClass('orange').removeClass('even').addClass('orange_even');
\t\t\t\$("tbody tr.green:even",table).removeClass('green').removeClass('even').addClass('green_even');
\t    } 
\t});
\t\t
\t\$(".date-pick").datepicker({
\t\tshowOn: 'button',
\t\tbuttonImage: '../images/calendar.png',
\t\tbuttonImageOnly: true,
\t\tdateFormat: 'yy-mm-dd',
\t\tconstrainInput: false,
\t\tchangeMonth: true,
\t\tchangeYear: true,
\t\tdayNamesMin: {$sJSDaysMin},
\t\tmonthNamesShort: {$sJSMonthsShort},
\t\tfirstDay: {$iFirstDayOfWeek}\t\t
\t});

\t\$(".datetime-pick").datepicker({
\t\tshowOn: 'button',
\t\tbuttonImage: '../images/calendar.png',
\t\tbuttonImageOnly: true,
\t\tdateFormat: 'yy-mm-dd 00:00:00',
\t\tconstrainInput: false,
\t\tchangeMonth: true,
\t\tchangeYear: true,
\t\tdayNamesMin: {$sJSDaysMin},
\t\tmonthNamesShort: {$sJSMonthsShort},
\t\tfirstDay: {$iFirstDayOfWeek}
\t});

\t//\$('.resizable').resizable(); // Make resizable everything that claims to be resizable !
\t\$('.caselog_header').click( function () { \$(this).toggleClass('open').next('.caselog_entry').toggle(); });
\t\t\t
\t\$(document).ajaxSend(function(event, jqxhr, options) {
\t\tjqxhr.setRequestHeader('X-Combodo-Ajax', 'true');
\t});
\t\$(document).ajaxError(function(event, jqxhr, options) {
\t\tif (jqxhr.status == 401)
\t\t{
\t\t\t\$('<div>'+{$sJSDisconnectedMessage}+'</div>').dialog({
\t\t\t\tmodal:true,
\t\t\t\ttitle: {$sJSTitle},
\t\t\t\tclose: function() { \$(this).remove(); },
\t\t\t\tminWidth: 400,
\t\t\t\tbuttons: [
\t\t\t\t{ text: {$sJSLoginAgain}, click: function() { window.location.href= GetAbsoluteUrlAppRoot()+'pages/UI.php' } },
\t\t\t\t{ text: {$sJSStayOnThePage}, click: function() { \$(this).dialog('close'); } }
\t\t\t\t]
\t\t\t});
\t\t}
\t});
}
catch(err)
{
\t// Do something with the error !
\talert(err);
}
EOF
);
        $this->add_script(<<<EOF
\tfunction CheckSelection(sMessage, sInputId)
\t{
\t\tvar bResult;
\t\tif (sInputId.length > 0)
\t\t{
\t\t\tbResult = (\$('input[name='+sInputId+']:checked').length > 0);
\t\t}
\t\telse
\t\t{
\t\t\t// First select found...
\t\t\tbResult = (\$('input:checked').length > 0);
\t\t}
\t\tif (!bResult)
\t\t{
\t\t\talert(sMessage);
\t\t}
\t\treturn bResult;
\t}

\t\t
\tfunction GetAbsoluteUrlAppRoot()
\t{
\t\treturn '{$sAbsURLAppRoot}';
\t}
\t
\tfunction GetAbsoluteUrlModulesRoot()
\t{
\t\treturn '{$sAbsURLModulesRoot}';
\t}

\tfunction AddAppContext(sURL)
\t{
\t\tvar sContext = '{$sAppContext}';
\t\tif (sContext.length > 0)
\t\t{
\t\t\tif (sURL.indexOf('?') == -1)
\t\t\t{
\t\t\t\treturn sURL+'?'+sContext;
\t\t\t}\t\t\t\t
\t\t\treturn sURL+'&'+sContext;
\t\t}
\t\treturn sURL;
\t}
\t
\tfunction GoBack(sFormId)
\t{
\t\tvar form = \$('#'+sFormId);
\t\tvar step_back = \$('input[name=step_back]');

\t\tform.unbind('submit'); // De-activate validation

\t\tstep_back.val(1);
\t\tform.submit(); // Go
\t}

\tfunction GoHome()
\t{
\t\tvar form = \$('FORM');
\t\tform.unbind('submit'); // De-activate validation
\t\twindow.location.href = window.location.href.replace(/[&?]operation=[^&]*/, '');
\t\treturn false;
\t}

\tfunction SetWizardNextStep(sStep)
\t{
\t\tvar next_step = \$('input[id=next_step]');
\t\tnext_step.val(sStep);
\t}
\t\t
\t// For disabling the CKEditor at init time when the corresponding textarea is disabled !
\tCKEDITOR.plugins.add( 'disabler',
\t{
\t\tinit : function( editor )
\t\t{
\t\t\teditor.on( 'instanceReady', function(e)
\t\t\t{
\t\t\t\te.removeListener();
\t\t\t\t\$('#'+ editor.name).trigger('update');
\t\t\t});
\t\t}
\t\t
\t});
EOF
);
        // For Wizard helper to process the ajax replies
        $this->add('<div id="ajax_content"></div>');
        // Customize the logo (unless a customer CSS has been defined)
        if ($sAlternateStyleSheet == '') {
            if (file_exists(MODULESROOT . 'branding/portal-logo.png')) {
                $sDisplayIcon = utils::GetAbsoluteUrlModulesRoot() . 'branding/portal-logo.png';
                $this->add_style("div#portal #logo {background: url(\"{$sDisplayIcon}\") no-repeat scroll 0 0 transparent;}");
            }
        }
    }
Esempio n. 15
0
function ReloadAndDisplay($oPage, $oObj, $sMessageId = '', $sMessage = '', $sSeverity = null)
{
    $oAppContext = new ApplicationContext();
    if ($sMessageId != '') {
        cmdbAbstractObject::SetSessionMessage(get_class($oObj), $oObj->GetKey(), $sMessageId, $sMessage, $sSeverity, 0, true);
    }
    $oPage->add_header('Location: ' . utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=details&class=' . get_class($oObj) . '&id=' . $oObj->getKey() . '&' . $oAppContext->GetForLink());
}
 function GetApplicationContext()
 {
     $oAppContext = new ApplicationContext();
     return $oAppContext->GetForLink();
 }
Esempio n. 17
0
/**
 * Displays the user's changeable preferences
 * @param $oP WebPage The web page used for the output
 */
function DisplayPreferences($oP)
{
    $oAppContext = new ApplicationContext();
    $sURL = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?' . $oAppContext->GetForLink();
    $oP->add('<div class="page_header"><h1><img style="vertical-align:middle" src="../images/preferences.png"/>&nbsp;' . Dict::S('UI:Preferences') . "</h1></div>\n");
    $oP->add('<div id="user_prefs" style="max-width:800px; min-width:400px;">');
    //////////////////////////////////////////////////////////////////////////
    //
    // User Language selection
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('UI:FavoriteLanguage') . '</legend>');
    $oP->add('<form method="post">');
    $aLanguages = Dict::GetLanguages();
    $aSortedlang = array();
    foreach ($aLanguages as $sCode => $aLang) {
        if (MetaModel::GetConfig()->Get('demo_mode')) {
            if ($sCode != Dict::GetUserLanguage()) {
                // Demo mode: only the current user language is listed in the available choices
                continue;
            }
        }
        $aSortedlang[$aLang['description']] = $sCode;
    }
    ksort($aSortedlang);
    $oP->add('<p>' . Dict::S('UI:Favorites:SelectYourLanguage') . ' <select name="language">');
    foreach ($aSortedlang as $sCode) {
        $sSelected = $sCode == Dict::GetUserLanguage() ? 'selected' : '';
        $oP->add('<option value="' . $sCode . '" ' . $sSelected . '/>' . $aLanguages[$sCode]['description'] . ' (' . $aLanguages[$sCode]['localized_description'] . ')</option>');
    }
    $oP->add('</select></p>');
    $oP->add('<input type="hidden" name="operation" value="apply_language"/>');
    $oP->add($oAppContext->GetForForm());
    $oP->add('<p><input type="button" onClick="window.location.href=\'' . $sURL . '\'" value="' . Dict::S('UI:Button:Cancel') . '"/>');
    $oP->add('&nbsp;&nbsp;');
    $oP->add('<input type="submit" value="' . Dict::S('UI:Button:Apply') . '"/></p>');
    $oP->add('</form>');
    $oP->add('</fieldset>');
    //////////////////////////////////////////////////////////////////////////
    //
    // Other (miscellaneous) settings
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('UI:FavoriteOtherSettings') . '</legend>');
    $oP->add('<form method="post" onsubmit="return ValidateOtherSettings()">');
    $iDefaultPageSize = appUserPreferences::GetPref('default_page_size', MetaModel::GetConfig()->GetMinDisplayLimit());
    $oP->add('<p>' . Dict::Format('UI:Favorites:Default_X_ItemsPerPage', '<input id="default_page_size" name="default_page_size" type="text" size="3" value="' . $iDefaultPageSize . '"/><span id="v_default_page_size"></span>') . '</p>');
    $oP->add('<input type="hidden" name="operation" value="apply_others"/>');
    $oP->add($oAppContext->GetForForm());
    $oP->add('<p><input type="button" onClick="window.location.href=\'' . $sURL . '\'" value="' . Dict::S('UI:Button:Cancel') . '"/>');
    $oP->add('&nbsp;&nbsp;');
    $oP->add('<input id="other_submit" type="submit" value="' . Dict::S('UI:Button:Apply') . '"/></p>');
    $oP->add('</form>');
    $oP->add('</fieldset>');
    $oP->add_script(<<<EOF
function ValidateOtherSettings()
{
\tvar sPageLength = \$('#default_page_size').val();
\tvar iPageLength = parseInt(sPageLength , 10);
\tif (/^[0-9]+\$/.test(sPageLength) && (iPageLength > 0))
\t{
\t\t\$('#v_default_page_size').html('');
\t\t\$('#other_submit').removeAttr('disabled');
\t\treturn true;
\t}
\telse
\t{
\t\t\$('#v_default_page_size').html('<img src="../images/validation_error.png"/>');
\t\t\$('#other_submit').attr('disabled', 'disabled');
\t\treturn false;
\t}
}
EOF
);
    //////////////////////////////////////////////////////////////////////////
    //
    // Favorite Organizations
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('UI:FavoriteOrganizations') . '</legend>');
    $oP->p(Dict::S('UI:FavoriteOrganizations+'));
    $oP->add('<form method="post">');
    // Favorite organizations: the organizations listed in the drop-down menu
    $sOQL = ApplicationMenu::GetFavoriteSiloQuery();
    $oFilter = DBObjectSearch::FromOQL($sOQL);
    $oBlock = new DisplayBlock($oFilter, 'list', false);
    $oBlock->Display($oP, 1, array('menu' => false, 'selection_mode' => true, 'selection_type' => 'multiple', 'cssCount' => '.selectedCount', 'table_id' => 'user_prefs'));
    $oP->add($oAppContext->GetForForm());
    $oP->add('<input type="hidden" name="operation" value="apply"/>');
    $oP->add('<p><input type="button" onClick="window.location.href=\'' . $sURL . '\'" value="' . Dict::S('UI:Button:Cancel') . '"/>');
    $oP->add('&nbsp;&nbsp;');
    $oP->add('<input type="submit" value="' . Dict::S('UI:Button:Apply') . '"/></p>');
    $oP->add('</form>');
    $oP->add('</fieldset>');
    $aFavoriteOrgs = appUserPreferences::GetPref('favorite_orgs', null);
    if ($aFavoriteOrgs == null) {
        // All checked
        $oP->add_ready_script(<<<EOF
\tif (\$('#user_prefs table.pagination').length > 0)
\t{
\t\t// paginated display, restore the selection
\t\tvar pager = \$('#user_prefs form .pager');
\t\t\$(':input[name=selectionMode]', pager).val('negative');
\t\t\$('#user_prefs table.listResults').trigger('load_selection');
\t}
\telse
\t{
\t\t\$('#user_prefs table.listResults').trigger('check_all');
\t}
EOF
);
    } else {
        $sChecked = implode('","', $aFavoriteOrgs);
        $oP->add_ready_script(<<<EOF
\tvar aChecked = ["{$sChecked}"];
\tif (\$('#user_prefs table.pagination').length > 0)
\t{
\t\t// paginated display, restore the selection
\t\tvar pager = \$('#user_prefs form .pager');
\t\t\$(':input[name=selectionMode]', pager).val('positive');
\t\tfor (i=0; i<aChecked.length; i++)
\t\t{
\t\t\tpager.append('<input type="hidden" name="storedSelection[]" id="'+aChecked[i]+'" value="'+aChecked[i]+'"/>');
\t\t}
\t\t\$('#user_prefs table.listResults').trigger('load_selection');
\t\t
\t}
\telse
\t{
\t\t\$('#user_prefs form :checkbox[name^=selectObject]').each( function()
\t\t\t{
\t\t\t\tif (\$.inArray(\$(this).val(), aChecked) > -1)
\t\t\t\t{
\t\t\t\t\t\$(this).attr('checked', true);
\t\t\t\t\t\$(this).trigger('change');
\t\t\t\t}
\t\t\t});
\t}
EOF
);
    }
    //////////////////////////////////////////////////////////////////////////
    //
    // Shortcuts
    //
    //////////////////////////////////////////////////////////////////////////
    $oP->add('<fieldset><legend>' . Dict::S('Menu:MyShortcuts') . '</legend>');
    //$oP->p(Dict::S('UI:Menu:MyShortcuts+'));
    $oBMSearch = new DBObjectSearch('Shortcut');
    $oBMSearch->AddCondition('user_id', UserRights::GetUserId(), '=');
    //$aExtraParams = array('menu' => false, 'toolkit_menu' => false, 'display_limit' => false, 'localize_values' => $bLocalize, 'zlist' => 'details');
    $aExtraParams = array();
    $oBlock = new DisplayBlock($oBMSearch, 'list', false, $aExtraParams);
    $oBlock->Display($oP, 'shortcut_list', array('view_link' => false, 'menu' => false, 'toolkit_menu' => false, 'selection_mode' => true, 'selection_type' => 'multiple', 'cssCount' => '#shortcut_selection_count', 'table_id' => 'user_prefs_shortcuts'));
    $oP->add('<p>');
    $oSet = new DBObjectSet($oBMSearch);
    if ($oSet->Count() > 0) {
        $sButtons = '<img src="../images/tv-item-last.gif">';
        $sButtons .= '&nbsp;';
        $sButtons .= '<button id="shortcut_btn_rename">' . Dict::S('UI:Button:Rename') . '</button>';
        $sButtons .= '&nbsp;';
        $sButtons .= '<button id="shortcut_btn_delete">' . Dict::S('UI:Button:Delete') . '</button>';
        // Selection count updated by the pager, and used to enable buttons
        $oP->add('<input type="hidden" id="shortcut_selection_count"/>');
        $oP->add('</fieldset>');
        $sConfirmDelete = addslashes(Dict::S('UI:ShortcutDelete:Confirm'));
        $oP->add_ready_script(<<<EOF
function OnShortcutBtnRename()
{
\tvar oParams = \$('#datatable_shortcut_list').datatable('GetMultipleSelectionParams');
\toParams.operation = 'shortcut_rename_dlg';

\t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data){
\t\t\$('body').append(data);
\t});
\treturn false;
}

function OnShortcutBtnDelete()
{
\tif (confirm('{$sConfirmDelete}'))
\t{
\t\tvar oParams = \$('#datatable_shortcut_list').datatable('GetMultipleSelectionParams');
\t\toParams.operation = 'shortcut_delete_go';

\t\t\$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.render.php', oParams, function(data){
\t\t\t\$('body').append(data);
\t\t});
\t}
\treturn false;
}

function OnSelectionCountChange()
{
\tvar iCountSelected = \$("#shortcut_selection_count").val();
\tif (iCountSelected == 0)
\t{
\t\t\$('#shortcut_btn_rename').attr('disabled', 'disabled');
\t\t\$('#shortcut_btn_delete').attr('disabled', 'disabled');
\t}
\telse if (iCountSelected == 1)
\t{
\t\t\$('#shortcut_btn_rename').removeAttr('disabled');
\t\t\$('#shortcut_btn_delete').removeAttr('disabled');
\t}
\telse
\t{
\t\t\$('#shortcut_btn_rename').attr('disabled', 'disabled');
\t\t\$('#shortcut_btn_delete').removeAttr('disabled');
\t}
}

var oUpperCheckBox = \$('#datatable_shortcut_list .checkAll').first();
oUpperCheckBox.parent().width(oUpperCheckBox.width() + 2);

\$('#datatable_shortcut_list').append('<tr><td colspan="2">&nbsp;&nbsp;&nbsp;{$sButtons}</td></tr>');
\$('#shortcut_selection_count').bind('change', OnSelectionCountChange);
\$('#shortcut_btn_rename').bind('click', OnShortcutBtnRename);
\$('#shortcut_btn_delete').bind('click', OnShortcutBtnDelete);
OnSelectionCountChange();
EOF
);
    }
    // if count > 0
    //////////////////////////////////////////////////////////////////////////
    //
    // Footer
    //
    $oP->add('</div>');
    $oP->add_ready_script("\$('#fav_page_length').bind('keyup change', function(){ ValidateOtherSettings(); })");
}