public static function GetCurrentUserName() { if (UserRights::IsImpersonated()) { $sUserString = Dict::Format('UI:Archive_User_OnBehalfOf_User', UserRights::GetRealUserFriendlyName(), UserRights::GetUserFriendlyName()); } else { $sUserString = UserRights::GetUserFriendlyName(); } return $sUserString; }
public function GetUserFriendlyDescription() { $sWrongClass = $this->GetWrongWord(); $sSuggest = self::FindClosestString($sWrongClass, $this->GetSuggestions()); if ($sSuggest != '') { return Dict::Format('UI:OQL:UnknownClassAndFix', $sWrongClass, $sSuggest); } else { return Dict::Format('UI:OQL:UnknownClassNoFix', $sWrongClass); } }
function TestConfig($sContents, $oP) { try { ini_set('display_errors', 1); ob_start(); eval('?' . '>' . trim($sContents)); $sNoise = trim(ob_get_contents()); ob_end_clean(); } catch (Exception $e) { // well, never reach in case of parsing error :-( throw new Exception('Error in configuration: ' . $e->getMessage()); } if (strlen($sNoise) > 0) { if (preg_match("/(Error|Parse error|Notice|Warning): (.+) in \\S+ : eval\\(\\)'d code on line (\\d+)/i", strip_tags($sNoise), $aMatches)) { $sMessage = $aMatches[2]; $sLine = $aMatches[3]; $iLine = (int) $sLine; // Highlight the line $aLines = explode("\n", $sContents); $iStart = 0; for ($i = 0; $i < $iLine - 1; $i++) { $iStart += strlen($aLines[$i]); } $iEnd = $iStart + strlen($aLines[$iLine - 1]); $iTotalLines = count($aLines); $oP->add_ready_script(<<<EOF setCursorPos(\$('#new_config')[0], {$iStart}, {$iEnd}); \$('#new_config')[0].focus(); var iScroll = Math.floor(\$('#new_config')[0].scrollHeight * ({$iLine} - 20) / {$iTotalLines}); \$('#new_config').scrollTop(iScroll); EOF ); $sMessage = Dict::Format('config-parse-error', $sMessage, $sLine); throw new Exception($sMessage); } else { // Note: sNoise is an html output, but so far it was ok for me (e.g. showing the entire call stack) throw new Exception('Syntax error in configuration file: <tt>' . $sNoise . '</tt>'); } } }
function DisplayNavigatorListTab($oP, $aResults, $sRelation, $oObj) { $oP->SetCurrentTab(Dict::S('UI:RelationshipList')); $oP->add("<div id=\"impacted_objects\" style=\"width:100%;background-color:#fff;padding:10px;\">"); $iBlock = 1; // Zero is not a valid blockid foreach ($aResults as $sListClass => $aObjects) { $oSet = CMDBObjectSet::FromArray($sListClass, $aObjects); $oP->add("<h1>" . MetaModel::GetRelationDescription($sRelation) . ' ' . $oObj->GetName() . "</h1>\n"); $oP->add("<div class=\"page_header\">\n"); $oP->add("<h2>" . MetaModel::GetClassIcon($sListClass) . " <span class=\"hilite\">" . Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', count($aObjects), Metamodel::GetName($sListClass)) . "</h2>\n"); $oP->add("</div>\n"); $oBlock = DisplayBlock::FromObjectSet($oSet, 'list'); $oBlock->Display($oP, $iBlock++); $oP->P(' '); // Some space ? } $oP->add("</div>"); }
} else { $oPage->add("<table>"); $aFirstLine = $aData[0]; // Use the first row to determine the number of columns $iStartLine = 0; $iNbColumns = count($aFirstLine); if ($bFirstLineAsHeader) { $iStartLine = 1; foreach ($aFirstLine as $sField) { $aHeader[] = $sField; } } else { // Build some conventional name for the fields: field1...fieldn $index = 1; foreach ($aFirstLine as $sField) { $aHeader[] = Dict::Format('UI:CSVImport:FieldName', $index); $index++; } } $oPage->add("<table>\n"); $oPage->add('<tr>'); $oPage->add('<th>' . Dict::S('UI:CSVImport:HeaderFields') . '</th><th>' . Dict::S('UI:CSVImport:HeaderMappings') . '</th><th> </th><th>' . Dict::S('UI:CSVImport:HeaderSearch') . '</th><th>' . Dict::S('UI:CSVImport:DataLine1') . '</th><th>' . Dict::S('UI:CSVImport:DataLine2') . '</th>'); $oPage->add('</tr>'); $index = 1; foreach ($aHeader as $sField) { $sDefaultChoice = null; if (isset($aInitFieldMapping[$index])) { $sDefaultChoice = $aInitFieldMapping[$index]; } $oPage->add('<tr>'); $oPage->add("<th>{$sField}</th>");
/** * Attempt a login * * @param int iOnExit What action to take if the user is not logged on (one of the class constants EXIT_...) * @return int One of the class constants EXIT_CODE_... */ protected static function Login($iOnExit) { if (self::SecureConnectionRequired() && !utils::IsConnectionSecure()) { // Non secured URL... request for a secure connection throw new Exception('Secure connection required!'); } $aAllowedLoginTypes = MetaModel::GetConfig()->GetAllowedLoginTypes(); if (isset($_SESSION['auth_user'])) { //echo "User: "******"\n"; // Already authentified UserRights::Login($_SESSION['auth_user']); // Login & set the user's language return self::EXIT_CODE_OK; } else { $index = 0; $sLoginMode = ''; $sAuthentication = 'internal'; while ($sLoginMode == '' && $index < count($aAllowedLoginTypes)) { $sLoginType = $aAllowedLoginTypes[$index]; switch ($sLoginType) { case 'cas': utils::InitCASClient(); // check CAS authentication if (phpCAS::isAuthenticated()) { $sAuthUser = phpCAS::getUser(); $sAuthPwd = ''; $sLoginMode = 'cas'; $sAuthentication = 'external'; } break; case 'form': // iTop standard mode: form based authentication $sAuthUser = utils::ReadPostedParam('auth_user', '', false, 'raw_data'); $sAuthPwd = utils::ReadPostedParam('auth_pwd', null, false, 'raw_data'); if ($sAuthUser != '' && $sAuthPwd !== null) { $sLoginMode = 'form'; } break; case 'basic': // Standard PHP authentication method, works with Apache... // Case 1) Apache running in CGI mode + rewrite rules in .htaccess if (isset($_SERVER['HTTP_AUTHORIZATION']) && !empty($_SERVER['HTTP_AUTHORIZATION'])) { list($sAuthUser, $sAuthPwd) = explode(':', base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6))); $sLoginMode = 'basic'; } else { if (isset($_SERVER['PHP_AUTH_USER'])) { $sAuthUser = $_SERVER['PHP_AUTH_USER']; // Unfortunately, the RFC is not clear about the encoding... // IE and FF supply the user and password encoded in ISO-8859-1 whereas Chrome provides them encoded in UTF-8 // So let's try to guess if it's an UTF-8 string or not... fortunately all encodings share the same ASCII base if (!self::LooksLikeUTF8($sAuthUser)) { // Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8 // Supposed to be harmless in case of a plain ASCII string... $sAuthUser = iconv('iso-8859-1', 'utf-8', $sAuthUser); } $sAuthPwd = $_SERVER['PHP_AUTH_PW']; if (!self::LooksLikeUTF8($sAuthPwd)) { // Does not look like and UTF-8 string, try to convert it from iso-8859-1 to UTF-8 // Supposed to be harmless in case of a plain ASCII string... $sAuthPwd = iconv('iso-8859-1', 'utf-8', $sAuthPwd); } $sLoginMode = 'basic'; } } break; case 'external': // Web server supplied authentication $bExternalAuth = false; $sExtAuthVar = MetaModel::GetConfig()->GetExternalAuthenticationVariable(); // In which variable is the info passed ? eval('$sAuthUser = isset(' . $sExtAuthVar . ') ? ' . $sExtAuthVar . ' : false;'); // Retrieve the value if ($sAuthUser && strlen($sAuthUser) > 0) { $sAuthPwd = ''; // No password in this case the web server already authentified the user... $sLoginMode = 'external'; $sAuthentication = 'external'; } break; case 'url': // Credentials passed directly in the url $sAuthUser = utils::ReadParam('auth_user', '', false, 'raw_data'); $sAuthPwd = utils::ReadParam('auth_pwd', null, false, 'raw_data'); if ($sAuthUser != '' && $sAuthPwd !== null) { $sLoginMode = 'url'; } break; } $index++; } //echo "\nsLoginMode: $sLoginMode (user: $sAuthUser / pwd: $sAuthPwd\n)"; if ($sLoginMode == '') { // First connection $sDesiredLoginMode = utils::ReadParam('login_mode'); if (in_array($sDesiredLoginMode, $aAllowedLoginTypes)) { $sLoginMode = $sDesiredLoginMode; } else { $sLoginMode = $aAllowedLoginTypes[0]; // First in the list... } if (array_key_exists('HTTP_X_COMBODO_AJAX', $_SERVER)) { // X-Combodo-Ajax is a special header automatically added to all ajax requests // Let's reply that we're currently logged-out header('HTTP/1.0 401 Unauthorized'); exit; } if ($iOnExit == self::EXIT_HTTP_401 || $sLoginMode == 'basic') { header('WWW-Authenticate: Basic realm="' . Dict::Format('UI:iTopVersion:Short', ITOP_VERSION)); header('HTTP/1.0 401 Unauthorized'); header('Content-type: text/html; charset=iso-8859-1'); exit; } else { if ($iOnExit == self::EXIT_RETURN) { if ($sAuthUser !== '' && $sAuthPwd === null) { return self::EXIT_CODE_MISSINGPASSWORD; } else { return self::EXIT_CODE_MISSINGLOGIN; } } else { $oPage = self::NewLoginWebPage(); $oPage->DisplayLoginForm($sLoginMode, false); $oPage->output(); exit; } } } else { if (!UserRights::CheckCredentials($sAuthUser, $sAuthPwd, $sLoginMode, $sAuthentication)) { //echo "Check Credentials returned false for user $sAuthUser!"; self::ResetSession(); if ($iOnExit == self::EXIT_HTTP_401 || $sLoginMode == 'basic') { header('WWW-Authenticate: Basic realm="' . Dict::Format('UI:iTopVersion:Short', ITOP_VERSION)); header('HTTP/1.0 401 Unauthorized'); header('Content-type: text/html; charset=iso-8859-1'); exit; } else { if ($iOnExit == self::EXIT_RETURN) { return self::EXIT_CODE_WRONGCREDENTIALS; } else { $oPage = self::NewLoginWebPage(); $oPage->DisplayLoginForm($sLoginMode, true); $oPage->output(); exit; } } } else { // User is Ok, let's save it in the session and proceed with normal login UserRights::Login($sAuthUser, $sAuthentication); // Login & set the user's language if (MetaModel::GetConfig()->Get('log_usage')) { $oLog = new EventLoginUsage(); $oLog->Set('userinfo', UserRights::GetUser()); $oLog->Set('user_id', UserRights::GetUserObject()->GetKey()); $oLog->Set('message', 'Successful login'); $oLog->DBInsertNoReload(); } $_SESSION['auth_user'] = $sAuthUser; $_SESSION['login_mode'] = $sLoginMode; UserRights::_InitSessionCache(); } } } return self::EXIT_CODE_OK; }
/** * Updates the object form POSTED arguments, and writes it into the DB (applies a stimuli if requested) * @param DBObject $oObj The object to update * $param array $aAttList If set, this will limit the list of updated attributes * @return void */ public function DoUpdateObjectFromPostedForm(DBObject $oObj, $aAttList = null) { $sTransactionId = utils::ReadPostedParam('transaction_id', ''); if (!utils::IsTransactionValid($sTransactionId)) { throw new TransactionException(); } $sClass = get_class($oObj); $sStimulus = trim(utils::ReadPostedParam('apply_stimulus', '')); $sTargetState = ''; if (!empty($sStimulus)) { // Compute the target state $aTransitions = $oObj->EnumTransitions(); if (!isset($aTransitions[$sStimulus])) { throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $oObj->GetName(), $oObj->GetStateLabel())); } $sTargetState = $aTransitions[$sStimulus]['target_state']; } $oObj->UpdateObjectFromPostedForm('', $aAttList, $sTargetState); // Optional: apply a stimulus // if (!empty($sStimulus)) { if (!$oObj->ApplyStimulus($sStimulus)) { throw new Exception("Cannot apply stimulus '{$sStimulus}' to {$oObj->GetName()}"); } } if ($oObj->IsModified()) { // Record the change // $oObj->DBUpdate(); // Trigger ? // $aClasses = MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL); $sClassList = implode(", ", CMDBSource::Quote($aClasses)); $oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnPortalUpdate AS t WHERE t.target_class IN ({$sClassList})")); while ($oTrigger = $oSet->Fetch()) { $oTrigger->DoActivate($oObj->ToArgs('this')); } $this->p("<h1>" . Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName()) . "</h1>\n"); } $bLockEnabled = MetaModel::GetConfig()->Get('concurrent_lock_enabled'); if ($bLockEnabled) { // Release the concurrent lock, if any $sOwnershipToken = utils::ReadPostedParam('ownership_token', null, false, 'raw_data'); if ($sOwnershipToken !== null) { // We're done, let's release the lock iTopOwnershipLock::ReleaseLock(get_class($oObj), $oObj->GetKey(), $sOwnershipToken); } } }
/** * Describe (as a text string) the modifications corresponding to this change */ public function GetDescription() { $sResult = ''; $oTargetObjectClass = $this->Get('objclass'); $oTargetObjectKey = $this->Get('objkey'); $oTargetSearch = new DBObjectSearch($oTargetObjectClass); $oTargetSearch->AddCondition('id', $oTargetObjectKey, '='); $oMonoObjectSet = new DBObjectSet($oTargetSearch); if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES) { if (!MetaModel::IsValidAttCode($this->Get('objclass'), $this->Get('attcode'))) { return ''; } // Protects against renamed attributes... $oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode')); $sAttName = $oAttDef->GetLabel(); $sLinkClass = $oAttDef->GetLinkedClass(); $aLinkClasses = MetaModel::EnumChildClasses($sLinkClass, ENUM_CHILD_CLASSES_ALL); // Search for changes on the corresponding link // $oSearch = new DBObjectSearch('CMDBChangeOpSetAttribute'); $oSearch->AddCondition('change', $this->Get('change'), '='); $oSearch->AddCondition('objkey', $this->Get('link_id'), '='); if (count($aLinkClasses) == 1) { // Faster than the whole building of the expression below for just one value ?? $oSearch->AddCondition('objclass', $sLinkClass, '='); } else { $oField = new FieldExpression('objclass', $oSearch->GetClassAlias()); $sListExpr = '(' . implode(', ', CMDBSource::Quote($aLinkClasses)) . ')'; $sOQLCondition = $oField->Render() . " IN {$sListExpr}"; $oNewCondition = Expression::FromOQL($sOQLCondition); $oSearch->AddConditionExpression($oNewCondition); } $oSet = new DBObjectSet($oSearch); $aChanges = array(); while ($oChangeOp = $oSet->Fetch()) { $aChanges[] = $oChangeOp->GetDescription(); } if (count($aChanges) == 0) { return ''; } $sItemDesc = MetaModel::GetHyperLink($this->Get('item_class'), $this->Get('item_id')); $sResult = $sAttName . ' - '; $sResult .= Dict::Format('Change:LinkSet:Modified', $sItemDesc); $sResult .= ' : ' . implode(', ', $aChanges); } return $sResult; }
/** * Describe (as a text string) the modifications corresponding to this change */ public function GetDescription() { // Temporary, until we change the options of GetDescription() -needs a more global revision $bIsHtml = true; $sResult = Dict::Format('Attachments:History_File_Removed', '<span class="attachment-history-deleted">' . htmlentities($this->Get('filename'), ENT_QUOTES, 'UTF-8') . '</span>'); return $sResult; }
$oLog->Set('userinfo', ''); $oLog->Set('issue', $e->GetIssue()); $oLog->Set('impact', 'Page could not be displayed'); $oLog->Set('callstack', $e->getTrace()); $oLog->Set('data', $e->getContextData()); $oLog->DBInsertNoReload(); } IssueLog::Error($e->getMessage()); } // For debugging only //throw $e; } catch (Exception $e) { require_once APPROOT . '/setup/setuppage.class.inc.php'; $oP = new SetupPage(Dict::S('UI:PageTitle:FatalError')); $oP->add("<h1>" . Dict::S('UI:FatalErrorMessage') . "</h1>\n"); $oP->error(Dict::Format('UI:Error_Details', $e->getMessage())); $oP->output(); if (MetaModel::IsLogEnabledIssue()) { if (MetaModel::IsValidClass('EventIssue')) { $oLog = new EventIssue(); $oLog->Set('message', $e->getMessage()); $oLog->Set('userinfo', ''); $oLog->Set('issue', 'PHP Exception'); $oLog->Set('impact', 'Page could not be displayed'); $oLog->Set('callstack', $e->getTrace()); $oLog->Set('data', array()); $oLog->DBInsertNoReload(); } IssueLog::Error($e->getMessage()); } }
/** * Outputs (via some echo) the complete HTML page by assembling all its elements */ public function output() { $sAbsURLAppRoot = addslashes($this->m_sRootUrl); //$this->set_base($this->m_sRootUrl.'pages/'); $sForm = $this->GetSiloSelectionForm(); $this->DisplayMenu(); // Compute the menu // Call the extensions to add content to the page, so that they can also add styles or scripts $sBannerExtraHtml = ''; foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) { $sBannerExtraHtml .= $oExtensionInstance->GetBannerHtml($this); } $sNorthPane = ''; foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) { $sNorthPane .= $oExtensionInstance->GetNorthPaneHtml($this); } if (UserRights::IsAdministrator() && ExecutionKPI::IsEnabled()) { $sNorthPane .= '<div id="admin-banner"><span style="padding:5px;">' . ExecutionKPI::GetDescription() . '<span></div>'; } //$sSouthPane = '<p>Peak memory Usage: '.sprintf('%.3f MB', memory_get_peak_usage(true) / (1024*1024)).'</p>'; $sSouthPane = ''; foreach (MetaModel::EnumPlugins('iPageUIExtension') as $oExtensionInstance) { $sSouthPane .= $oExtensionInstance->GetSouthPaneHtml($this); } // Put here the 'ready scripts' that must be executed after all others $aMultiselectOptions = array('header' => true, 'checkAllText' => Dict::S('UI:SearchValue:CheckAll'), 'uncheckAllText' => Dict::S('UI:SearchValue:UncheckAll'), 'noneSelectedText' => Dict::S('UI:SearchValue:Any'), 'selectedText' => Dict::S('UI:SearchValue:NbSelected'), 'selectedList' => 1); $sJSMultiselectOptions = json_encode($aMultiselectOptions); $this->add_ready_script(<<<EOF \t\t// Since the event is only triggered when the hash changes, we need to trigger \t\t// the event now, to handle the hash the page may have loaded with. \t\t\$(window).trigger( 'hashchange' ); \t\t \t\t// Some table are sort-able, some are not, let's fix this \t\t\$('table.listResults').each( function() { FixTableSorter(\$(this)); } ); \t\t \t\t\$('.multiselect').multiselect({$sJSMultiselectOptions}); \t\tFixSearchFormsDisposition(); EOF ); if ($this->GetOutputFormat() == 'html') { foreach ($this->a_headers as $s_header) { header($s_header); } } $s_captured_output = $this->ob_get_clean_safe(); $sHtml = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"; $sHtml .= "<html>\n"; $sHtml .= "<head>\n"; // Make sure that Internet Explorer renders the page using its latest/highest/greatest standards ! $sHtml .= "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n"; $sHtml .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"; $sHtml .= "<title>" . htmlentities($this->s_title, ENT_QUOTES, 'UTF-8') . "</title>\n"; $sHtml .= $this->get_base_tag(); // Stylesheets MUST be loaded before any scripts otherwise // jQuery scripts may face some spurious problems (like failing on a 'reload') foreach ($this->a_linked_stylesheets as $a_stylesheet) { if ($a_stylesheet['condition'] != "") { $sHtml .= "<!--[if {$a_stylesheet['condition']}]>\n"; } $sHtml .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"{$a_stylesheet['link']}\" />\n"; if ($a_stylesheet['condition'] != "") { $sHtml .= "<![endif]-->\n"; } } // special stylesheet for printing, hides the navigation gadgets $sHtml .= "<link rel=\"stylesheet\" media=\"print\" type=\"text/css\" href=\"../css/print.css\" />\n"; if ($this->GetOutputFormat() == 'html') { $sHtml .= $this->output_dict_entries(true); // before any script so that they can benefit from the translations foreach ($this->a_linked_scripts as $s_script) { // Make sure that the URL to the script contains the application's version number // so that the new script do NOT get reloaded from the cache when the application is upgraded if (strpos($s_script, '?') === false) { $s_script .= "?itopversion=" . ITOP_VERSION; } else { $s_script .= "&itopversion=" . ITOP_VERSION; } $sHtml .= "<script type=\"text/javascript\" src=\"{$s_script}\"></script>\n"; } $this->add_script("var iPaneVisWatchDog = window.setTimeout('FixPaneVis()',5000);\n\$(document).ready(function() {\n{$this->m_sInitScript};\nwindow.setTimeout('onDelayedReady()',10)\n});"); if (count($this->m_aReadyScripts) > 0) { $this->add_script("\nonDelayedReady = function() {\n" . implode("\n", $this->m_aReadyScripts) . "\n}\n"); } if (count($this->a_scripts) > 0) { $sHtml .= "<script type=\"text/javascript\">\n"; foreach ($this->a_scripts as $s_script) { $sHtml .= "{$s_script}\n"; } $sHtml .= "</script>\n"; } } if (count($this->a_styles) > 0) { $sHtml .= "<style>\n"; foreach ($this->a_styles as $s_style) { $sHtml .= "{$s_style}\n"; } $sHtml .= "</style>\n"; } $sHtml .= "<link rel=\"search\" type=\"application/opensearchdescription+xml\" title=\"iTop\" href=\"" . utils::GetAbsoluteUrlAppRoot() . "pages/opensearch.xml.php\" />\n"; $sHtml .= "<link rel=\"shortcut icon\" href=\"" . utils::GetAbsoluteUrlAppRoot() . "images/favicon.ico\" />\n"; $sHtml .= "</head>\n"; $sHtml .= "<body>\n"; // Render the revision number if (ITOP_REVISION == '$WCREV$') { // This is NOT a version built using the buil system, just display the main version $sVersionString = Dict::Format('UI:iTopVersion:Short', ITOP_VERSION); } else { // This is a build made from SVN, let display the full information $sVersionString = Dict::Format('UI:iTopVersion:Long', ITOP_VERSION, ITOP_REVISION, ITOP_BUILD_DATE); } // Render the text of the global search form $sText = htmlentities(utils::ReadParam('text', '', false, 'raw_data'), ENT_QUOTES, 'UTF-8'); $sOnClick = ""; if (empty($sText)) { // if no search text is supplied then // 1) the search text is filled with "your search" // 2) clicking on it will erase it $sText = Dict::S("UI:YourSearch"); $sOnClick = " onclick=\"this.value='';this.onclick=null;\""; } // Render the tabs in the page (if any) $this->s_content = $this->m_oTabs->RenderIntoContent($this->s_content); if ($this->GetOutputFormat() == 'html') { $oAppContext = new ApplicationContext(); $sUserName = UserRights::GetUser(); $sIsAdmin = UserRights::IsAdministrator() ? '(Administrator)' : ''; if (UserRights::IsAdministrator()) { $sLogonMessage = Dict::Format('UI:LoggedAsMessage+Admin', $sUserName); } else { $sLogonMessage = Dict::Format('UI:LoggedAsMessage', $sUserName); } $sLogOffMenu = "<span id=\"logOffBtn\"><ul><li><img src=\"../images/onOffBtn.png\"><ul>"; $sLogOffMenu .= "<li><span>{$sLogonMessage}</span></li>\n"; $aActions = array(); $oPrefs = new URLPopupMenuItem('UI:Preferences', Dict::S('UI:Preferences'), utils::GetAbsoluteUrlAppRoot() . "pages/preferences.php?" . $oAppContext->GetForLink()); $aActions[$oPrefs->GetUID()] = $oPrefs->GetMenuItem(); if (utils::CanLogOff()) { $oLogOff = new URLPopupMenuItem('UI:LogOffMenu', Dict::S('UI:LogOffMenu'), utils::GetAbsoluteUrlAppRoot() . 'pages/logoff.php?operation=do_logoff'); $aActions[$oLogOff->GetUID()] = $oLogOff->GetMenuItem(); } if (UserRights::CanChangePassword()) { $oChangePwd = new URLPopupMenuItem('UI:ChangePwdMenu', Dict::S('UI:ChangePwdMenu'), utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?loginop=change_pwd'); $aActions[$oChangePwd->GetUID()] = $oChangePwd->GetMenuItem(); } utils::GetPopupMenuItems($this, iPopupMenuExtension::MENU_USER_ACTIONS, null, $aActions); $oAbout = new JSPopupMenuItem('UI:AboutBox', Dict::S('UI:AboutBox'), 'return ShowAboutBox();'); $aActions[$oAbout->GetUID()] = $oAbout->GetMenuItem(); $sLogOffMenu .= $this->RenderPopupMenuItems($aActions); $sRestrictions = ''; if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE)) { if (!MetaModel::DBHasAccess(ACCESS_ADMIN_WRITE)) { $sRestrictions = Dict::S('UI:AccessRO-All'); } } elseif (!MetaModel::DBHasAccess(ACCESS_USER_WRITE)) { $sRestrictions = Dict::S('UI:AccessRO-Users'); } $sApplicationBanner = ''; if (strlen($sRestrictions) > 0) { $sAdminMessage = trim(MetaModel::GetConfig()->Get('access_message')); $sApplicationBanner .= '<div id="admin-banner">'; $sApplicationBanner .= '<img src="../images/locked.png" style="vertical-align:middle;">'; $sApplicationBanner .= ' <b>' . $sRestrictions . '</b>'; if (strlen($sAdminMessage) > 0) { $sApplicationBanner .= ' <b>' . $sAdminMessage . '</b>'; } $sApplicationBanner .= '</div>'; } if (strlen($this->m_sMessage)) { $sApplicationBanner .= '<div id="admin-banner"><span style="padding:5px;">' . $this->m_sMessage . '<span></div>'; } $sApplicationBanner .= $sBannerExtraHtml; if (!empty($sNorthPane)) { $sNorthPane = '<div id="bottom-pane" class="ui-layout-north">' . $sNorthPane . '</div>'; } if (!empty($sSouthPane)) { $sSouthPane = '<div id="bottom-pane" class="ui-layout-south">' . $sSouthPane . '</div>'; } $sIconUrl = Utils::GetConfig()->Get('app_icon_url'); $sOnlineHelpUrl = MetaModel::GetConfig()->Get('online_help'); //$sLogOffMenu = "<span id=\"logOffBtn\" style=\"height:55px;padding:0;margin:0;\"><img src=\"../images/onOffBtn.png\"></span>"; $sDisplayIcon = utils::GetAbsoluteUrlAppRoot() . 'images/itop-logo.png'; if (file_exists(MODULESROOT . 'branding/main-logo.png')) { $sDisplayIcon = utils::GetAbsoluteUrlModulesRoot() . 'branding/main-logo.png'; } $sHtml .= $sNorthPane; $sHtml .= '<div id="left-pane" class="ui-layout-west">'; $sHtml .= '<!-- Beginning of the left pane -->'; $sHtml .= ' <div class="ui-layout-north">'; $sHtml .= ' <div id="header-logo">'; $sHtml .= ' <div id="top-left"></div><div id="logo"><a href="' . htmlentities($sIconUrl, ENT_QUOTES, 'UTF-8') . '"><img src="' . $sDisplayIcon . '" title="' . htmlentities($sVersionString, ENT_QUOTES, 'UTF-8') . '" style="border:0; margin-top:16px; margin-right:40px;"/></a></div>'; $sHtml .= ' </div>'; $sHtml .= ' <div class="header-menu">'; if (!MetaModel::GetConfig()->Get('demo_mode')) { $sHtml .= ' <div class="icon ui-state-default ui-corner-all"><span id="tPinMenu" class="ui-icon ui-icon-pin-w">pin</span></div>'; } $sHtml .= ' <div style="text-align:center;">' . self::FilterXSS($sForm) . '</div>'; $sHtml .= ' </div>'; $sHtml .= ' </div>'; $sHtml .= ' <div id="menu" class="ui-layout-center">'; $sHtml .= ' <div id="inner_menu">'; $sHtml .= ' <div id="accordion">'; $sHtml .= self::FilterXSS($this->m_sMenu); $sHtml .= ' <!-- Beginning of the accordion menu -->'; $sHtml .= ' <!-- End of the accordion menu-->'; $sHtml .= ' </div>'; $sHtml .= ' </div> <!-- /inner menu -->'; $sHtml .= ' </div> <!-- /menu -->'; $sHtml .= ' <div class="footer ui-layout-south"><div id="combodo_logo"><a href="http://www.combodo.com" title="www.combodo.com" target="_blank"><img src="../images/logo-combodo.png"/></a></div></div>'; $sHtml .= '<!-- End of the left pane -->'; $sHtml .= '</div>'; $sHtml .= '<div class="ui-layout-center">'; $sHtml .= ' <div id="top-bar" style="width:100%">'; $sHtml .= self::FilterXSS($sApplicationBanner); $sHtml .= ' <div id="global-search"><form action="' . utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php"><table><tr><td></td><td id="g-search-input"><input type="text" name="text" value="' . $sText . '"' . $sOnClick . '/></td>'; $sHtml .= '<td><input type="image" src="../images/searchBtn.png"/></a></td>'; $sHtml .= '<td><a style="background:transparent;" href="' . $sOnlineHelpUrl . '" target="_blank"><img style="border:0;padding-left:20px;padding-right:10px;" title="' . Dict::S('UI:Help') . '" src="../images/help.png"/></td>'; $sHtml .= '<td style="padding-right:20px;padding-left:10px;">' . self::FilterXSS($sLogOffMenu) . '</td><td><input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>'; //echo '<td> <input type="hidden" name="operation" value="full_text"/></td></tr></table></form></div>'; $sHtml .= ' </div>'; $sHtml .= ' <div class="ui-layout-content" style="overflow:auto;">'; $sHtml .= ' <!-- Beginning of page content -->'; $sHtml .= self::FilterXSS($this->s_content); $sHtml .= ' <!-- End of page content -->'; $sHtml .= ' </div>'; $sHtml .= '</div>'; $sHtml .= $sSouthPane; // Add the captured output if (trim($s_captured_output) != "") { $sHtml .= "<div id=\"rawOutput\" title=\"Debug Output\"><div style=\"height:500px; overflow-y:auto;\">" . self::FilterXSS($s_captured_output) . "</div></div>\n"; } $sHtml .= "<div id=\"at_the_end\">" . self::FilterXSS($this->s_deferred_content) . "</div>"; $sHtml .= "<div style=\"display:none\" title=\"ex2\" id=\"ex2\">Please wait...</div>\n"; // jqModal Window $sHtml .= "<div style=\"display:none\" title=\"dialog\" id=\"ModalDlg\"></div>"; $sHtml .= "<div style=\"display:none\" id=\"ajax_content\"></div>"; } else { $sHtml .= self::FilterXSS($this->s_content); } $sHtml .= "</body>\n"; $sHtml .= "</html>\n"; if ($this->GetOutputFormat() == 'html') { $oKPI = new ExecutionKPI(); echo $sHtml; $oKPI->ComputeAndReport('Echoing (' . round(strlen($sHtml) / 1024) . ' Kb)'); } else { if ($this->GetOutputFormat() == 'pdf' && $this->IsOutputFormatAvailable('pdf')) { if (@is_readable(APPROOT . 'lib/MPDF/mpdf.php')) { require_once APPROOT . 'lib/MPDF/mpdf.php'; $oMPDF = new mPDF('c'); $oMPDF->mirroMargins = false; if ($this->a_base['href'] != '') { $oMPDF->setBasePath($this->a_base['href']); // Seems that the <BASE> tag is not recognized by mPDF... } $oMPDF->showWatermarkText = true; if ($this->GetOutputOption('pdf', 'template_path')) { $oMPDF->setImportUse(); // Allow templates $oMPDF->SetDocTemplate($this->GetOutputOption('pdf', 'template_path'), 1); } $oMPDF->WriteHTML($sHtml); $sOutputName = $this->s_title . '.pdf'; if ($this->GetOutputOption('pdf', 'output_name')) { $sOutputName = $this->GetOutputOption('pdf', 'output_name'); } $oMPDF->Output($sOutputName, 'I'); } } } DBSearch::RecordQueryTrace(); ExecutionKPI::ReportStats(); }
public function ToArgs($sArgName = 'this') { if (is_null($this->m_aAsArgs)) { $oKPI = new ExecutionKPI(); $aScalarArgs = $this->ToArgsForQuery($sArgName); $aScalarArgs[$sArgName] = $this->GetKey(); $aScalarArgs[$sArgName . '->id'] = $this->GetKey(); $aScalarArgs[$sArgName . '->hyperlink()'] = $this->GetHyperlink('iTopStandardURLMaker', false); $aScalarArgs[$sArgName . '->hyperlink(portal)'] = $this->GetHyperlink('PortalURLMaker', false); $aScalarArgs[$sArgName . '->name()'] = $this->GetName(); $sClass = get_class($this); foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) { if ($oAttDef instanceof AttributeCaseLog) { $oCaseLog = $this->Get($sAttCode); $aScalarArgs[$sArgName . '->' . $sAttCode] = $oCaseLog->GetText(); $sHead = $oCaseLog->GetLatestEntry(); $aScalarArgs[$sArgName . '->head(' . $sAttCode . ')'] = $sHead; $aScalarArgs[$sArgName . '->head_html(' . $sAttCode . ')'] = '<div class="caselog_entry">' . str_replace(array("\r\n", "\n", "\r"), "<br/>", htmlentities($sHead, ENT_QUOTES, 'UTF-8')) . '</div>'; $aScalarArgs[$sArgName . '->html(' . $sAttCode . ')'] = $oCaseLog->GetAsEmailHtml(); } elseif ($oAttDef->IsScalar()) { $aScalarArgs[$sArgName . '->' . $sAttCode] = $this->Get($sAttCode); // #@# Note: This has been proven to be quite slow, this can slow down bulk load $sAsHtml = $this->GetAsHtml($sAttCode); $aScalarArgs[$sArgName . '->html(' . $sAttCode . ')'] = $sAsHtml; $aScalarArgs[$sArgName . '->label(' . $sAttCode . ')'] = $this->GetEditValue($sAttCode); // "Nice" display value, but without HTML tags and entities } elseif ($oAttDef->IsLinkSet()) { $sRemoteName = $oAttDef->IsIndirect() ? $oAttDef->GetExtKeyToRemote() . '_friendlyname' : 'friendlyname'; $oLinkSet = clone $this->Get($sAttCode); // Workaround/Safety net for Trac #887 $iLimit = MetaModel::GetConfig()->Get('max_linkset_output'); if ($iLimit > 0) { $oLinkSet->SetLimit($iLimit); } $aNames = $oLinkSet->GetColumnAsArray($sRemoteName); if ($iLimit > 0) { $iTotal = $oLinkSet->Count(); if ($iTotal > count($aNames)) { $aNames[] = '... ' . Dict::Format('UI:TruncatedResults', count($aNames), $iTotal); } } $sNames = implode("\n", $aNames); $aScalarArgs[$sArgName . '->' . $sAttCode] = $sNames; $aScalarArgs[$sArgName . '->html(' . $sAttCode . ')'] = '<ul><li>' . implode("</li><li>", $aNames) . '</li></ul>'; } } $this->m_aAsArgs = $aScalarArgs; $oKPI->ComputeStats('ToArgs', get_class($this)); } return $this->m_aAsArgs; }
public function GetName() { return Dict::Format('UI:UserManagement:LinkBetween_User_And_Org', $this->Get('userlogin'), $this->Get('allowed_org_name')); }
/** * 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}\"> " . MetaModel::GetClassIcon($sSubClass) . " {$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 ); }
public function ReadParameters() { parent::ReadParameters(); $sQueryId = utils::ReadParam('query', null, true); $sFields = utils::ReadParam('fields', null, true, 'raw_data'); if (($sFields === null || $sFields === '') && $sQueryId === null) { throw new BulkExportMissingParameterException('fields'); } else { if ($sQueryId !== null && $sQueryId !== null) { $oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId)); $oQueries = new DBObjectSet($oSearch); if ($oQueries->Count() > 0) { $oQuery = $oQueries->Fetch(); if ($sFields === null || $sFields === '') { // No 'fields' parameter supplied, take the fields from the query phrasebook definition $sFields = trim($oQuery->Get('fields')); if ($sFields === '') { throw new BulkExportMissingParameterException('fields'); } } } else { throw BulkExportException('Invalid value for the parameter: query. There is no Query Phrasebook with id = ' . $sQueryId, Dict::Format('Core:BulkExport:InvalidParameter_Query', $sQueryId)); } } } $aFields = explode(',', $sFields); $this->aStatusInfo['fields'] = array(); foreach ($aFields as $sField) { // Trim the values since it's too temping to write: fields=name, first_name, org_name instead of fields=name,first_name,org_name $this->aStatusInfo['fields'][] = trim($sField); } }
public function ReadParameters() { parent::ReadParameters(); $sQueryId = utils::ReadParam('query', null, true); $sFields = utils::ReadParam('fields', null, true, 'raw_data'); if (($sFields === null || $sFields === '') && $sQueryId === null) { throw new BulkExportMissingParameterException('fields'); } else { if ($sQueryId !== null && $sQueryId !== null) { $oSearch = DBObjectSearch::FromOQL('SELECT QueryOQL WHERE id = :query_id', array('query_id' => $sQueryId)); $oQueries = new DBObjectSet($oSearch); if ($oQueries->Count() > 0) { $oQuery = $oQueries->Fetch(); if ($sFields === null || $sFields === '') { // No 'fields' parameter supplied, take the fields from the query phrasebook definition $sFields = trim($oQuery->Get('fields')); if ($sFields === '') { throw new BulkExportMissingParameterException('fields'); } } } else { throw BulkExportException('Invalid value for the parameter: query. There is no Query Phrasebook with id = ' . $sQueryId, Dict::Format('Core:BulkExport:InvalidParameter_Query', $sQueryId)); } } } // Interpret (and check) the list of fields // $aSelectedClasses = $this->oSearch->GetSelectedClasses(); $aAliases = array_keys($aSelectedClasses); $aAuthorizedClasses = array(); foreach ($aSelectedClasses as $sAlias => $sClassName) { if (UserRights::IsActionAllowed($sClassName, UR_ACTION_BULK_READ) == UR_ALLOWED_YES) { $aAuthorizedClasses[$sAlias] = $sClassName; } } $aFields = explode(',', $sFields); $this->aStatusInfo['fields'] = array(); foreach ($aFields as $sFieldSpec) { // Trim the values since it's natural to write: fields=name, first_name, org_name instead of fields=name,first_name,org_name $sExtendedAttCode = trim($sFieldSpec); if (preg_match('/^([^\\.]+)\\.(.+)$/', $sExtendedAttCode, $aMatches)) { $sAlias = $aMatches[1]; $sAttCode = $aMatches[2]; } else { $sAlias = reset($aAliases); $sAttCode = $sExtendedAttCode; } if (!array_key_exists($sAlias, $aSelectedClasses)) { throw new Exception("Invalid alias '{$sAlias}' for the column '{$sExtendedAttCode}'. Availables aliases: '" . implode("', '", $aAliases) . "'"); } $sClass = $aSelectedClasses[$sAlias]; if (!array_key_exists($sAlias, $aAuthorizedClasses)) { throw new Exception("You do not have enough permissions to bulk read data of class '{$sClass}' (alias: {$sAlias})"); } if ($this->bLocalizeOutput) { try { $sLabel = MetaModel::GetLabel($sClass, $sAttCode); } catch (Exception $e) { throw new Exception("Wrong field specification '{$sFieldSpec}': " . $e->getMessage()); } } else { $sLabel = $sAttCode; } if (count($aAuthorizedClasses) > 1) { $sColLabel = $sAlias . '.' . $sLabel; } else { $sColLabel = $sLabel; } $this->aStatusInfo['fields'][] = array('sFieldSpec' => $sExtendedAttCode, 'sAlias' => $sAlias, 'sClass' => $sClass, 'sAttCode' => $sAttCode, 'sLabel' => $sLabel, 'sColLabel' => $sColLabel); } }
/** * Display the hierarchy of the 'target' class */ public function DisplayHierarchy(WebPage $oPage, $sFilter, $currValue, $oObj) { $sDialogTitle = addslashes(Dict::Format('UI:HierarchyOf_Class', MetaModel::GetName($this->sTargetClass))); $oPage->add('<div id="dlg_tree_' . $this->iId . '"><div class="wizContainer" style="vertical-align:top;"><div style="overflow:auto;background:#fff;margin-bottom:5px;" id="tree_' . $this->iId . '">'); $oPage->add('<table style="width:100%"><tr><td>'); if (is_null($sFilter)) { throw new Exception('Implementation: null value for allowed values definition'); } try { $oFilter = DBObjectSearch::FromOQL($sFilter); $oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode); $oSet = new DBObjectSet($oFilter, array(), array('this' => $oObj)); } catch (MissingQueryArgument $e) { // When used in a search form the $this parameter may be missing, in this case return all possible values... // TODO check if we can improve this behavior... $sOQL = 'SELECT ' . $this->m_sTargetClass; $oFilter = DBObjectSearch::FromOQL($sOQL); $oFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', $this->bSearchMode); $oSet = new DBObjectSet($oFilter); } $sHKAttCode = MetaModel::IsHierarchicalClass($this->sTargetClass); $this->DumpTree($oPage, $oSet, $sHKAttCode, $currValue); $oPage->add('</td></tr></table>'); $oPage->add('</div>'); $oPage->add("<input type=\"button\" id=\"btn_cancel_{$this->iId}\" value=\"" . Dict::S('UI:Button:Cancel') . "\" onClick=\"\$('#dlg_tree_{$this->iId}').dialog('close');\"> "); $oPage->add("<input type=\"button\" id=\"btn_ok_{$this->iId}\" value=\"" . Dict::S('UI:Button:Ok') . "\" onClick=\"oACWidget_{$this->iId}.DoHKOk();\">"); $oPage->add('</div></div>'); $oPage->add_ready_script("\$('#tree_{$this->iId} ul').treeview();\n"); $oPage->add_ready_script("\$('#dlg_tree_{$this->iId}').dialog({ width: 'auto', height: 'auto', autoOpen: true, modal: true, title: '{$sDialogTitle}', resizeStop: oACWidget_{$this->iId}.OnHKResize, close: oACWidget_{$this->iId}.OnHKClose });\n"); }
/** * Displays the details of a request * @param WebPage $oP The current web page * @param Object $oObj The target object * @return void */ function ShowDetailsRequest(WebPage $oP, $oObj) { $sClass = get_class($oObj); $sLogAttCode = GetConstant($sClass, 'PUBLIC_LOG'); $sUserCommentAttCode = GetConstant($sClass, 'USER_COMMENT'); $bIsReopenButton = false; $bIsCloseButton = false; $bIsEscalateButton = false; $bEditAttachments = false; $aEditAtt = array(); // List of attributes editable in the main form if (!MetaModel::DBIsReadOnly()) { switch ($oObj->GetState()) { case 'resolved': $aEditAtt = array(); $aTransitions = $oObj->EnumTransitions(); $oSet = DBObjectSet::FromObject($oObj); // Add the "Reopen" button if this is valid action if (array_key_exists('ev_reopen', $aTransitions) && UserRights::IsStimulusAllowed($sClass, 'ev_reopen', $oSet)) { $bIsReopenButton = true; MakeStimulusForm($oP, $oObj, 'ev_reopen', array($sLogAttCode)); } // Add the "Close" button if this is valid action if (array_key_exists('ev_close', $aTransitions) && UserRights::IsStimulusAllowed($sClass, 'ev_close', $oSet)) { $bIsCloseButton = true; MakeStimulusForm($oP, $oObj, 'ev_close', array('user_satisfaction', $sUserCommentAttCode)); } break; case 'closed': // By convention 'closed' is the final state of a ticket and nothing can be done in such a state break; default: // In all other states, the only possible action is to update the ticket (both the case log and the attachments) // This update is possible only if the case log field is not read-only or hidden in the current state $iFlags = $oObj->GetAttributeFlags($sLogAttCode); $bReadOnly = ($iFlags & (OPT_ATT_READONLY | OPT_ATT_HIDDEN)) != 0; if ($bReadOnly) { $aEditAtt = array(); $bEditAttachments = false; } else { $aEditAtt = array($sLogAttCode => '????'); $bEditAttachments = true; } break; } } // REFACTORISER LA MISE EN FORME $oP->add("<h1 id=\"title_request_details\">" . $oObj->GetIcon() . " " . Dict::Format('Portal:TitleRequestDetailsFor_Request', $oObj->GetName()) . "</h1>\n"); $aAttList = json_decode(GetConstant($sClass, 'DETAILS_ZLIST'), true); switch ($oObj->GetState()) { case 'closed': $aAttList['centered'][] = 'user_satisfaction'; $aAttList['centered'][] = $sUserCommentAttCode; } // Remove the edited attribute from the shown attributes // foreach ($aEditAtt as $sAttCode => $foo) { foreach ($aAttList as $col => $aColumn) { if (in_array($sAttCode, $aColumn)) { if (($index = array_search($sAttCode, $aColumn)) !== false) { unset($aAttList[$col][$index]); } } } } $oP->add("<div class=\"wizContainer\" id=\"form_commment_request\">\n"); $oP->WizardFormStart('request_form', null); $oP->add('<div id="request_details">'); $oP->add('<table id="request_details_table">'); $oP->add('<tr>'); $oP->add('<td style="vertical-align:top;">'); $oP->DisplayObjectDetails($oObj, $aAttList['col:left']); $oP->add('</td>'); $oP->add('<td style="vertical-align:top;">'); $oP->DisplayObjectDetails($oObj, $aAttList['col:right']); $oP->add('</td>'); $oP->add('</tr>'); if (array_key_exists('centered', $aAttList)) { $oP->add('<tr>'); $oP->add('<td style="vertical-align:top;" colspan="2">'); $oP->DisplayObjectDetails($oObj, $aAttList['centered']); $oP->add('</td>'); $oP->add('</tr>'); } // REFACTORISER $oP->add('<tr>'); $oP->add('<td colspan="2" style="vertical-align:top;">'); $oAttPlugin = new AttachmentPlugIn(); if ($bEditAttachments) { $oAttPlugin->EnableDelete(false); $oAttPlugin->OnDisplayRelations($oObj, $oP, true); } else { $oAttPlugin->OnDisplayRelations($oObj, $oP, false); } $oP->add('</td>'); $oP->add('</tr>'); $oP->add('<tr>'); $oP->add('<td colspan="2" style="vertical-align:top;">'); //$oP->add("<form action=\"../portal/index.php\" id=\"request_form\" method=\"post\">\n"); //$oP->add('<table id=""><tr><td style="vertical-align:top;">'); //$oP->add("<h1 id=\"title_request_details\">".Dict::Format('Portal:CommentsFor_Request', $oObj->GetName())."</h1>\n"); $oP->add("<input type=\"hidden\" name=\"class\" value=\"{$sClass}\">"); $oP->add("<input type=\"hidden\" name=\"id\" value=\"" . $oObj->GetKey() . "\">"); $oP->add("<input type=\"hidden\" name=\"operation\" value=\"update_request\">"); $oP->add("<input type=\"hidden\" id=\"stimulus_to_apply\" name=\"apply_stimulus\" value=\"\">\n"); $oP->add_script(<<<EOF \tfunction SetStimulusToApply(sStimulusCode) \t{ \t\t\$('#stimulus_to_apply').val(sStimulusCode); \t} EOF ); $aEditFields = array(); // Intermediate array to avoid code duplication while splitting btw ticket_log and the rest foreach ($aEditAtt as $sAttCode => $foo) { $sValue = $oObj->Get($sAttCode); $sDisplayValue = $oObj->GetEditValue($sAttCode); $aArgs = array('this' => $oObj, 'formPrefix' => ''); $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); $sInputId = 'input_' . $sAttCode; $sHTMLValue = "<span id=\"field_{$sInputId}\">" . cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $sValue, $sDisplayValue, $sInputId, '', 0, $aArgs) . '</span>'; $aEditFields[$sAttCode] = array('label' => MetaModel::GetLabel($sClass, $sAttCode), 'value' => $sHTMLValue); } foreach ($aEditFields as $sAttCode => $aFieldSpec) { if ($sAttCode == $sLogAttCode) { // Skip, the public log will be displayed below the buttons continue; } $oP->add("<div class=\"edit_item\">"); $oP->add('<h1>' . $aFieldSpec['label'] . '</h1>'); $oP->add($aFieldSpec['value']); $oP->add('</div>'); } if ($bIsReopenButton) { $sStimulusCode = 'ev_reopen'; $sTitle = addslashes(Dict::S('Portal:Button:ReopenTicket')); $sOk = addslashes(Dict::S('UI:Button:Ok')); $oP->p('<input type="button" onClick="RunStimulusDialog(\'' . $sStimulusCode . '\', \'' . $sTitle . '\', \'' . $sOk . '\');" value="' . $sTitle . '...">'); } if ($bIsCloseButton) { $sStimulusCode = 'ev_close'; $sTitle = addslashes(Dict::S('Portal:Button:CloseTicket')); $sOk = addslashes(Dict::S('UI:Button:Ok')); $oP->p('<input type="button" onClick="RunStimulusDialog(\'' . $sStimulusCode . '\', \'' . $sTitle . '\', \'' . $sOk . '\');" value="' . $sTitle . '...">'); } elseif (count($aEditAtt) > 0) { $oP->p('<input type="submit" value="' . Dict::S('Portal:Button:UpdateRequest') . '">'); } if ($bIsEscalateButton) { $sStimulusCode = 'ev_timeout'; $oP->p('<input type="submit" onClick="SetStimulusToApply(\'' . $sStimulusCode . '\');" value="' . Dict::S('Portal:ButtonEscalate') . '">'); } $oP->add('</td>'); $oP->add('</tr>'); $oP->add('<tr>'); $oP->add('<td colspan="2" style="vertical-align:top;">'); if (isset($aEditFields[$sLogAttCode])) { $oP->add("<div class=\"edit_item\">"); $oP->add('<h1>' . $aEditFields[$sLogAttCode]['label'] . '</h1>'); $oP->add($aEditFields[$sLogAttCode]['value']); $oP->add('</div>'); } else { $oP->add('<h1>' . MetaModel::GetLabel($sClass, $sLogAttCode) . '</h1>'); $oP->add($oObj->GetAsHTML($sLogAttCode)); } $oP->add('</td>'); $oP->add('</tr>'); $oP->add('</table>'); $oP->add('</div>'); $oP->WizardFormEnd(); $oP->add('</div>'); }
protected function GetFieldData($sAlias, $sAttCode, $oAttDef, $bChecked, $sSort) { $ret = false; if ($sAttCode == '_key_') { $sLabel = Dict::Format('UI:ExtKey_AsLink', MetaModel::GetName($this->aClassAliases[$sAlias])); $ret = array('label' => $sLabel, 'checked' => true, 'disabled' => true, 'alias' => $sAlias, 'code' => $sAttCode, 'sort' => $sSort); } else { if (!$oAttDef->IsLinkSet()) { $sLabel = $oAttDef->GetLabel(); if ($oAttDef->IsExternalKey()) { $sLabel = Dict::Format('UI:ExtKey_AsLink', $oAttDef->GetLabel()); } else { if ($oAttDef->IsExternalField()) { $oExtAttDef = $oAttDef->GetExtAttDef(); $sLabel = Dict::Format('UI:ExtField_AsRemoteField', $oAttDef->GetLabel(), $oExtAttDef->GetLabel()); } elseif ($oAttDef instanceof AttributeFriendlyName) { $sLabel = Dict::Format('UI:ExtKey_AsFriendlyName', $oAttDef->GetLabel()); } } $ret = array('label' => $sLabel, 'checked' => $bChecked, 'disabled' => false, 'alias' => $sAlias, 'code' => $sAttCode, 'sort' => $sSort); } } return $ret; }
public function GetName() { return Dict::Format('UI:UserManagement:LinkBetween_User_And_Profile', $this->Get('userlogin'), $this->Get('profile')); }
public function GetRenderContent(WebPage $oPage, $aExtraParams = array(), $sId) { $sHtml = ''; $bTruncated = false; $oSet = new CMDBObjectSet($this->m_oFilter, array('date' => false)); if ($this->iLimitStart > 0 || $this->iLimitCount > 0) { $oSet->SetLimit($this->iLimitCount, $this->iLimitStart); if ($this->iLimitCount - $this->iLimitStart < $oSet->Count()) { $bTruncated = true; } } $sHtml .= "<!-- filter: " . $this->m_oFilter->ToOQL() . "-->\n"; switch ($this->m_sStyle) { case 'toggle': // First the latest change that the user is allowed to see do { $oLatestChangeOp = $oSet->Fetch(); } while (is_object($oLatestChangeOp) && $oLatestChangeOp->GetDescription() == ''); if (is_object($oLatestChangeOp)) { // There is one change in the list... only when the object has been created ! $sDate = $oLatestChangeOp->GetAsHTML('date'); $oChange = MetaModel::GetObject('CMDBChange', $oLatestChangeOp->Get('change')); $sUserInfo = $oChange->GetAsHTML('userinfo'); $sHtml .= $oPage->GetStartCollapsibleSection(Dict::Format('UI:History:LastModified_On_By', $sDate, $sUserInfo)); $sHtml .= $this->GetHistoryTable($oPage, $oSet); $sHtml .= $oPage->GetEndCollapsibleSection(); } break; case 'table': default: if ($bTruncated) { $sFilter = $this->m_oFilter->serialize(); $sHtml .= '<div id="history_container"><p>'; $sHtml .= Dict::Format('UI:TruncatedResults', $this->iLimitCount, $oSet->Count()); $sHtml .= ' '; $sHtml .= '<a href="#" onclick="DisplayHistory(\'#history_container\', \'' . $sFilter . '\', 0, 0); return false;">' . Dict::S('UI:DisplayAll') . '</a>'; $sHtml .= $this->GetHistoryTable($oPage, $oSet); $sHtml .= '</p></div>'; $oPage->add_ready_script("\$('#{$sId} table.listResults tr:last td').addClass('truncated');"); } else { $sHtml .= $this->GetHistoryTable($oPage, $oSet); } } return $sHtml; }
public function DoCheckToWrite() { parent::DoCheckToWrite(); $sFilter = trim($this->Get('filter')); if (strlen($sFilter) > 0) { try { $oSearch = DBObjectSearch::FromOQL($sFilter); if (!MetaModel::IsParentClass($this->Get('target_class'), $oSearch->GetClass())) { $this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterClass', $this->Get('target_class')); } } catch (OqlException $e) { $this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterQuery', $e->getMessage()); } } }
$sClass = trim(utils::ReadParam('class', '')); $iTune = utils::ReadParam('tune', 0); if (preg_match('/^"(.*)"$/', $sFullText, $aMatches)) { // The text is surrounded by double-quotes, remove the quotes and treat it as one single expression $aFullTextNeedles = array($aMatches[1]); } else { // Split the text on the blanks and treat this as a search for <word1> AND <word2> AND <word3> $aFullTextNeedles = explode(' ', $sFullText); } $oFilter = new DBObjectSearch($sClass); foreach ($aFullTextNeedles as $sSearchText) { $oFilter->AddCondition_FullText($sSearchText); } $oSet = new DBObjectSet($oFilter); $oPage->add("<div class=\"page_header\">\n"); $oPage->add("<h2>" . MetaModel::GetClassIcon($sClass) . " <span class=\"hilite\">" . Dict::Format('UI:Search:Count_ObjectsOf_Class_Found', $oSet->Count(), Metamodel::GetName($sClass)) . "</h2>\n"); $oPage->add("</div>\n"); if ($oSet->Count() > 0) { $aLeafs = array(); while ($oObj = $oSet->Fetch()) { if (get_class($oObj) == $sClass) { $aLeafs[] = $oObj->GetKey(); } } $oLeafsFilter = new DBObjectSearch($sClass); if (count($aLeafs) > 0) { $oLeafsFilter->AddCondition('id', $aLeafs, 'IN'); $oBlock = new DisplayBlock($oLeafsFilter, 'list', false); $sBlockId = 'global_search_' . $sClass; $oPage->add('<div id="' . $sBlockId . '">'); $oBlock->RenderContent($oPage, array('table_id' => $sBlockId, 'currentId' => $sBlockId));
static function FormatDuration($duration) { $days = floor($duration / 86400); $hours = floor(($duration - 86400 * $days) / 3600); $minutes = floor(($duration - (86400 * $days + 3600 * $hours)) / 60); $sResult = ''; if ($duration < 60) { // Less than 1 min $sResult = Dict::S('UI:Deadline_LessThan1Min'); } else { if ($duration < 3600) { // less than 1 hour, display it in minutes $sResult = Dict::Format('UI:Deadline_Minutes', $minutes); } else { if ($duration < 86400) { // Less that 1 day, display it in hours/minutes $sResult = Dict::Format('UI:Deadline_Hours_Minutes', $hours, $minutes); } else { // Less that 1 day, display it in hours/minutes $sResult = Dict::Format('UI:Deadline_Days_Hours_Minutes', $days, $hours, $minutes); } } } return $sResult; }
private static function GetActionDescription($oAttachment, $bCreate = true) { $oBlob = $oAttachment->Get('contents'); $sFileName = $oBlob->GetFileName(); if ($bCreate) { $sDescription = Dict::Format('Attachments:History_File_Added', $sFileName); } else { $sDescription = Dict::Format('Attachments:History_File_Removed', $sFileName); } return $sDescription; }
public static function GetHyperLink($sTargetClass, $iKey) { if ($iKey < 0) { return "{$sTargetClass}: {$iKey} (invalid value)"; } $oObj = self::GetObject($sTargetClass, $iKey, false); if (is_null($oObj)) { // Whatever we are looking for, the root class is the key to search for $sRootClass = self::GetRootClass($sTargetClass); $oSearch = DBObjectSearch::FromOQL('SELECT CMDBChangeOpDelete WHERE objclass = :objclass AND objkey = :objkey', array('objclass' => $sRootClass, 'objkey' => $iKey)); $oSet = new DBObjectSet($oSearch); $oRecord = $oSet->Fetch(); // An empty fname is obtained with iTop < 2.0 if (is_null($oRecord) || strlen(trim($oRecord->Get('fname'))) == 0) { $sName = Dict::Format('Core:UnknownObjectLabel', $sTargetClass, $iKey); $sTitle = Dict::S('Core:UnknownObjectTip'); } else { $sName = $oRecord->Get('fname'); $sTitle = Dict::Format('Core:DeletedObjectTip', $oRecord->Get('date'), $oRecord->Get('userinfo')); } return '<span class="itop-deleted-object" title="' . htmlentities($sTitle, ENT_QUOTES, 'UTF-8') . '">' . htmlentities($sName, ENT_QUOTES, 'UTF-8') . '</span>'; } return $oObj->GetHyperLink(); }
/** * Perform all the needed checks to delete one (or more) objects */ public static function DeleteObjects(WebPage $oP, $sClass, $aObjects, $bPreview, $sCustomOperation, $aContextData = array()) { $oDeletionPlan = new DeletionPlan(); foreach ($aObjects as $oObj) { if ($bPreview) { $oObj->CheckToDelete($oDeletionPlan); } else { $oObj->DBDeleteTracked(CMDBObject::GetCurrentChange(), null, $oDeletionPlan); } } if ($bPreview) { if (count($aObjects) == 1) { $oObj = $aObjects[0]; $oP->add("<h1>" . Dict::Format('UI:Delete:ConfirmDeletionOf_Name', $oObj->GetName()) . "</h1>\n"); } else { $oP->add("<h1>" . Dict::Format('UI:Delete:ConfirmDeletionOf_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . "</h1>\n"); } // Explain what should be done // $aDisplayData = array(); foreach ($oDeletionPlan->ListDeletes() as $sTargetClass => $aDeletes) { foreach ($aDeletes as $iId => $aData) { $oToDelete = $aData['to_delete']; $bAutoDel = $aData['mode'] == DEL_SILENT || $aData['mode'] == DEL_AUTO; if (array_key_exists('issue', $aData)) { if ($bAutoDel) { if (isset($aData['requested_explicitely'])) { $sConsequence = Dict::Format('UI:Delete:CannotDeleteBecause', $aData['issue']); } else { $sConsequence = Dict::Format('UI:Delete:ShouldBeDeletedAtomaticallyButNotPossible', $aData['issue']); } } else { $sConsequence = Dict::Format('UI:Delete:MustBeDeletedManuallyButNotPossible', $aData['issue']); } } else { if ($bAutoDel) { if (isset($aData['requested_explicitely'])) { $sConsequence = ''; // not applicable } else { $sConsequence = Dict::S('UI:Delete:WillBeDeletedAutomatically'); } } else { $sConsequence = Dict::S('UI:Delete:MustBeDeletedManually'); } } $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToDelete)), 'object' => $oToDelete->GetHyperLink(), 'consequence' => $sConsequence); } } foreach ($oDeletionPlan->ListUpdates() as $sRemoteClass => $aToUpdate) { foreach ($aToUpdate as $iId => $aData) { $oToUpdate = $aData['to_reset']; if (array_key_exists('issue', $aData)) { $sConsequence = Dict::Format('UI:Delete:CannotUpdateBecause_Issue', $aData['issue']); } else { $sConsequence = Dict::Format('UI:Delete:WillAutomaticallyUpdate_Fields', $aData['attributes_list']); } $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToUpdate)), 'object' => $oToUpdate->GetHyperLink(), 'consequence' => $sConsequence); } } $iImpactedIndirectly = $oDeletionPlan->GetTargetCount() - count($aObjects); if ($iImpactedIndirectly > 0) { if (count($aObjects) == 1) { $oObj = $aObjects[0]; $oP->p(Dict::Format('UI:Delete:Count_Objects/LinksReferencing_Object', $iImpactedIndirectly, $oObj->GetName())); } else { $oP->p(Dict::Format('UI:Delete:Count_Objects/LinksReferencingTheObjects', $iImpactedIndirectly)); } $oP->p(Dict::S('UI:Delete:ReferencesMustBeDeletedToEnsureIntegrity')); } if ($iImpactedIndirectly > 0 || $oDeletionPlan->FoundStopper()) { $aDisplayConfig = array(); $aDisplayConfig['class'] = array('label' => 'Class', 'description' => ''); $aDisplayConfig['object'] = array('label' => 'Object', 'description' => ''); $aDisplayConfig['consequence'] = array('label' => 'Consequence', 'description' => Dict::S('UI:Delete:Consequence+')); $oP->table($aDisplayConfig, $aDisplayData); } if ($oDeletionPlan->FoundStopper()) { if ($oDeletionPlan->FoundSecurityIssue()) { $oP->p(Dict::S('UI:Delete:SorryDeletionNotAllowed')); } elseif ($oDeletionPlan->FoundManualOperation()) { $oP->p(Dict::S('UI:Delete:PleaseDoTheManualOperations')); } else { $oP->p(Dict::S('UI:Delete:PleaseDoTheManualOperations')); } $oAppContext = new ApplicationContext(); $oP->add("<form method=\"post\">\n"); $oP->add("<input type=\"hidden\" name=\"transaction_id\" value=\"" . utils::ReadParam('transaction_id') . "\">\n"); $oP->add("<input type=\"button\" onclick=\"window.history.back();\" value=\"" . Dict::S('UI:Button:Back') . "\">\n"); $oP->add("<input DISABLED type=\"submit\" name=\"\" value=\"" . Dict::S('UI:Button:Delete') . "\">\n"); $oP->add($oAppContext->GetForForm()); $oP->add("</form>\n"); } else { if (count($aObjects) == 1) { $oObj = $aObjects[0]; $id = $oObj->GetKey(); $oP->p('<h1>' . Dict::Format('UI:Delect:Confirm_Object', $oObj->GetHyperLink()) . '</h1>'); } else { $oP->p('<h1>' . Dict::Format('UI:Delect:Confirm_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . '</h1>'); } foreach ($aObjects as $oObj) { $aKeys[] = $oObj->GetKey(); } $oFilter = new DBObjectSearch($sClass); $oFilter->AddCondition('id', $aKeys, 'IN'); $oSet = new CMDBobjectSet($oFilter); $oP->add('<div id="0">'); CMDBAbstractObject::DisplaySet($oP, $oSet, array('display_limit' => false, 'menu' => false)); $oP->add("</div>\n"); $oP->add("<form method=\"post\">\n"); foreach ($aContextData as $sKey => $value) { $oP->add("<input type=\"hidden\" name=\"{$sKey}\" value=\"{$value}\">\n"); } $oP->add("<input type=\"hidden\" name=\"transaction_id\" value=\"" . utils::GetNewTransactionId() . "\">\n"); $oP->add("<input type=\"hidden\" name=\"operation\" value=\"{$sCustomOperation}\">\n"); $oP->add("<input type=\"hidden\" name=\"filter\" value=\"" . $oFilter->Serialize() . "\">\n"); $oP->add("<input type=\"hidden\" name=\"class\" value=\"{$sClass}\">\n"); foreach ($aObjects as $oObj) { $oP->add("<input type=\"hidden\" name=\"selectObject[]\" value=\"" . $oObj->GetKey() . "\">\n"); } $oP->add("<input type=\"button\" onclick=\"window.history.back();\" value=\"" . Dict::S('UI:Button:Back') . "\">\n"); $oP->add("<input type=\"submit\" name=\"\" value=\"" . Dict::S('UI:Button:Delete') . "\">\n"); $oAppContext = new ApplicationContext(); $oP->add($oAppContext->GetForForm()); $oP->add("</form>\n"); } } else { // Execute the deletion // if (count($aObjects) == 1) { $oObj = $aObjects[0]; $oP->add("<h1>" . Dict::Format('UI:Title:DeletionOf_Object', $oObj->GetName()) . "</h1>\n"); } else { $oP->add("<h1>" . Dict::Format('UI:Title:BulkDeletionOf_Count_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass)) . "</h1>\n"); } // Security - do not allow the user to force a forbidden delete by the mean of page arguments... if ($oDeletionPlan->FoundSecurityIssue()) { throw new CoreException(Dict::S('UI:Error:NotEnoughRightsToDelete')); } if ($oDeletionPlan->FoundManualOperation()) { throw new CoreException(Dict::S('UI:Error:CannotDeleteBecauseManualOpNeeded')); } if ($oDeletionPlan->FoundManualDelete()) { throw new CoreException(Dict::S('UI:Error:CannotDeleteBecauseOfDepencies')); } // Report deletions // $aDisplayData = array(); foreach ($oDeletionPlan->ListDeletes() as $sTargetClass => $aDeletes) { foreach ($aDeletes as $iId => $aData) { $oToDelete = $aData['to_delete']; if (isset($aData['requested_explicitely'])) { $sMessage = Dict::S('UI:Delete:Deleted'); } else { $sMessage = Dict::S('UI:Delete:AutomaticallyDeleted'); } $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToDelete)), 'object' => $oToDelete->GetName(), 'consequence' => $sMessage); } } // Report updates // foreach ($oDeletionPlan->ListUpdates() as $sTargetClass => $aToUpdate) { foreach ($aToUpdate as $iId => $aData) { $oToUpdate = $aData['to_reset']; $aDisplayData[] = array('class' => MetaModel::GetName(get_class($oToUpdate)), 'object' => $oToUpdate->GetHyperLink(), 'consequence' => Dict::Format('UI:Delete:AutomaticResetOf_Fields', $aData['attributes_list'])); } } // Report automatic jobs // if ($oDeletionPlan->GetTargetCount() > 0) { if (count($aObjects) == 1) { $oObj = $aObjects[0]; $oP->p(Dict::Format('UI:Delete:CleaningUpRefencesTo_Object', $oObj->GetName())); } else { $oP->p(Dict::Format('UI:Delete:CleaningUpRefencesTo_Several_ObjectsOf_Class', count($aObjects), MetaModel::GetName($sClass))); } $aDisplayConfig = array(); $aDisplayConfig['class'] = array('label' => 'Class', 'description' => ''); $aDisplayConfig['object'] = array('label' => 'Object', 'description' => ''); $aDisplayConfig['consequence'] = array('label' => 'Done', 'description' => Dict::S('UI:Delete:Done+')); $oP->table($aDisplayConfig, $aDisplayData); } } }
function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array()) { if ($bEditMode) { return; } // Not editable $oPage->add('<table style="vertical-align:top"><tr style="vertical-align:top"><td>'); $aDetails = array(); $sClass = get_class($this); $oPage->add('<fieldset>'); $oPage->add('<legend>' . Dict::S('Core:SynchroReplica:PrivateDetails') . '</legend>'); $aZList = MetaModel::FlattenZlist(MetaModel::GetZListItems($sClass, 'details')); foreach ($aZList as $sAttCode) { $sDisplayValue = $this->GetAsHTML($sAttCode); $aDetails[] = array('label' => '<span title="' . MetaModel::GetDescription($sClass, $sAttCode) . '">' . MetaModel::GetLabel($sClass, $sAttCode) . '</span>', 'value' => $sDisplayValue); } $oPage->Details($aDetails); $oPage->add('</fieldset>'); if (strlen($this->Get('dest_class')) > 0) { $oDestObj = MetaModel::GetObject($this->Get('dest_class'), $this->Get('dest_id'), false); if (is_object($oDestObj)) { $oPage->add('<fieldset>'); $oPage->add('<legend>' . Dict::Format('Core:SynchroReplica:TargetObject', $oDestObj->GetHyperlink()) . '</legend>'); $oDestObj->DisplayBareProperties($oPage, false, $sPrefix, $aExtraParams); $oPage->add('<fieldset>'); } } $oPage->add('</td><td>'); $oPage->add('<fieldset>'); $oPage->add('<legend>' . Dict::S('Core:SynchroReplica:PublicData') . '</legend>'); $oSource = MetaModel::GetObject('SynchroDataSource', $this->Get('sync_source_id')); $sSQLTable = $oSource->GetDataTable(); $aData = $this->LoadExtendedDataFromTable($sSQLTable); $aHeaders = array('attcode' => array('label' => 'Attribute Code', 'description' => ''), 'data' => array('label' => 'Value', 'description' => '')); $aRows = array(); foreach ($aData as $sKey => $value) { $aRows[] = array('attcode' => $sKey, 'data' => $value); } $oPage->Table($aHeaders, $aRows); $oPage->add('</fieldset>'); $oPage->add('</td></tr></table>'); }
function DisplayBareRelations(WebPage $oPage, $bEditMode = false) { parent::DisplayBareRelations($oPage, $bEditMode); if (!$bEditMode) { $oPage->SetCurrentTab(Dict::S('Class:Subnet/Tab:IPUsage')); $bit_ip = ip2long($this->Get('ip')); $bit_mask = ip2long($this->Get('ip_mask')); $iIPMin = sprintf('%u', $bit_ip & $bit_mask | 1); // exclude the first one: identifies the subnet itself $iIPMax = sprintf('%u', ($bit_ip | ~$bit_mask) & 0xfffffffe); // exclude the last one : broadcast address $sIPMin = long2ip($iIPMin); $sIPMax = long2ip($iIPMax); $oPage->p(Dict::Format('Class:Subnet/Tab:IPUsage-explain', $sIPMin, $sIPMax)); $oIfFilter = DBObjectSearch::FromOQL("SELECT IPInterface AS if WHERE INET_ATON(if.ipaddress) >= INET_ATON('{$sIPMin}') AND INET_ATON(if.ipaddress) <= INET_ATON('{$sIPMax}')"); $oIfSet = new CMDBObjectSet($oIfFilter); $oBlock = new DisplayBlock($oIfFilter, 'list', false); $oBlock->Display($oPage, 'nwif', array('menu' => false)); $iCountUsed = $oIfSet->Count(); $iCountRange = $iIPMax - $iIPMin; // On 32-bit systems the substraction will be computed using floats for values greater than PHP_MAX_INT; $iFreeCount = $iCountRange - $iCountUsed; $oPage->SetCurrentTab(Dict::S('Class:Subnet/Tab:FreeIPs')); $oPage->p(Dict::Format('Class:Subnet/Tab:FreeIPs-count', $iFreeCount)); $oPage->p(Dict::S('Class:Subnet/Tab:FreeIPs-explain')); $aUsedIPs = $oIfSet->GetColumnAsArray('ipaddress', false); $iAnIP = $iIPMin; $iFound = 0; while ($iFound < min($iFreeCount, 10) && $iAnIP <= $iIPMax) { $sAnIP = long2ip($iAnIP); if (!in_array($sAnIP, $aUsedIPs)) { $iFound++; $oPage->p($sAnIP); } else { } $iAnIP++; } } }
/** * Select the options of the CSV load and check for CSV parsing errors * @param WebPage $oPage The current web page * @return void */ function SelectOptions(WebPage $oPage) { $sOperation = utils::ReadParam('operation', 'csv_data'); $sCSVData = ''; switch ($sOperation) { case 'file_upload': $oDocument = utils::ReadPostedDocument('csvdata'); if (!$oDocument->IsEmpty()) { $sCSVData = $oDocument->GetData(); } break; default: $sCSVData = utils::ReadPostedParam('csvdata', '', 'raw_data'); } $sEncoding = utils::ReadParam('encoding', 'UTF-8'); // Compute a subset of the data set, now that we know the charset if ($sEncoding == 'UTF-8') { // Remove the BOM if any if (substr($sCSVData, 0, 3) == UTF8_BOM) { $sCSVData = substr($sCSVData, 3); } // Clean the input // Todo: warn the user if some characters are lost/substituted $sUTF8Data = iconv('UTF-8', 'UTF-8//IGNORE//TRANSLIT', $sCSVData); } else { $sUTF8Data = iconv($sEncoding, 'UTF-8//IGNORE//TRANSLIT', $sCSVData); } $aGuesses = GuessParameters($sUTF8Data); // Try to predict the parameters, based on the input data $sSeparator = utils::ReadParam('separator', '', false, 'raw_data'); if ($sSeparator == '') { $sSeparator = $aGuesses['separator']; } $iSkippedLines = utils::ReadParam('nb_skipped_lines', ''); $bBoxSkipLines = utils::ReadParam('box_skiplines', 0); if ($sSeparator == 'tab') { $sSeparator = "\t"; } $sOtherSeparator = in_array($sSeparator, array(',', ';', "\t")) ? '' : $sSeparator; $sTextQualifier = utils::ReadParam('text_qualifier', '', false, 'raw_data'); if ($sTextQualifier == '') { $sTextQualifier = $aGuesses['qualifier']; } $sOtherTextQualifier = in_array($sTextQualifier, array('"', "'")) ? '' : $sTextQualifier; $bHeaderLine = utils::ReadParam('header_line', 0); $sClassName = utils::ReadParam('class_name', '', false, 'class'); $bAdvanced = utils::ReadParam('advanced', 0); $aFieldsMapping = utils::ReadParam('field', array(), false, 'raw_data'); $aSearchFields = utils::ReadParam('search_field', array(), false, 'field_name'); // Create a truncated version of the data used for the fast preview // Take about 20 lines of data... knowing that some lines may contain carriage returns $iMaxLen = strlen($sUTF8Data); if ($iMaxLen > 0) { $iMaxLines = 20; $iCurPos = true; while ($iCurPos > 0 && $iMaxLines > 0) { $pos = strpos($sUTF8Data, "\n", $iCurPos); if ($pos !== false) { $iCurPos = 1 + $pos; } else { $iCurPos = strlen($sUTF8Data); $iMaxLines = 1; } $iMaxLines--; } $sCSVDataTruncated = substr($sUTF8Data, 0, $iCurPos); } else { $sCSVDataTruncated = ''; } $sSynchroScope = utils::ReadParam('synchro_scope', '', false, 'raw_data'); if (!empty($sSynchroScope)) { $oSearch = DBObjectSearch::FromOQL($sSynchroScope); $sClassName = $oSearch->GetClass(); $oSet = new DBObjectSet($oSearch); $iCount = $oSet->Count(); DisplaySynchroBanner($oPage, $sClassName, $iCount); $aSynchroUpdate = utils::ReadParam('synchro_update', array()); } $oPage->add('<h2>' . Dict::S('UI:Title:CSVImportStep2') . '</h2>'); $oPage->add('<div class="wizContainer">'); $oPage->add('<table><tr><td style="vertical-align:top;padding-right:50px;">'); $oPage->add('<form enctype="multipart/form-data" id="wizForm" method="post" id="csv_options">'); $oPage->add('<h3>' . Dict::S('UI:CSVImport:SeparatorCharacter') . '</h3>'); $oPage->add('<p><input type="radio" name="separator" value="," onClick="DoPreview()"' . IsChecked($sSeparator, ',') . '/> ' . Dict::S('UI:CSVImport:SeparatorComma+') . '<br/>'); $oPage->add('<input type="radio" name="separator" value=";" onClick="DoPreview()"' . IsChecked($sSeparator, ';') . '/> ' . Dict::S('UI:CSVImport:SeparatorSemicolon+') . '<br/>'); $oPage->add('<input type="radio" name="separator" value="tab" onClick="DoPreview()"' . IsChecked($sSeparator, "\t") . '/> ' . Dict::S('UI:CSVImport:SeparatorTab+') . '<br/>'); $oPage->add('<input type="radio" name="separator" value="other" onClick="DoPreview()"' . IsChecked($sOtherSeparator, '', true) . '/> ' . Dict::S('UI:CSVImport:SeparatorOther') . ' <input type="text" size="3" maxlength="1" name="other_separator" id="other_separator" value="' . $sOtherSeparator . '" onClick="DoPreview()"/>'); $oPage->add('</p>'); $oPage->add('</td><td style="vertical-align:top;padding-right:50px;">'); $oPage->add('<h3>' . Dict::S('UI:CSVImport:TextQualifierCharacter') . '</h3>'); $oPage->add('<p><input type="radio" name="text_qualifier" value=""" onClick="DoPreview()"' . IsChecked($sTextQualifier, '"') . '/> ' . Dict::S('UI:CSVImport:QualifierDoubleQuote+') . '<br/>'); $oPage->add('<input type="radio" name="text_qualifier" value="'" onClick="DoPreview()"' . IsChecked($sTextQualifier, "'") . '/> ' . Dict::S('UI:CSVImport:QualifierSimpleQuote+') . '<br/>'); $oPage->add('<input type="radio" name="text_qualifier" value="other" onClick="DoPreview()"' . IsChecked($sOtherTextQualifier, '', true) . '/> ' . Dict::S('UI:CSVImport:QualifierOther') . ' <input type="text" size="3" maxlength="1" name="other_qualifier" value="' . htmlentities($sOtherTextQualifier, ENT_QUOTES, 'UTF-8') . '" onChange="DoPreview()"/>'); $oPage->add('</p>'); $oPage->add('</td><td style="vertical-align:top;">'); $oPage->add('<h3>' . Dict::S('UI:CSVImport:CommentsAndHeader') . '</h3>'); $oPage->add('<p><input type="checkbox" name="header_line" id="box_header" value="1" onClick="DoPreview()"' . IsChecked($bHeaderLine, 1) . '/> ' . Dict::S('UI:CSVImport:TreatFirstLineAsHeader') . '<p>'); $oPage->add('<p><input type="checkbox" name="box_skiplines" value="1" id="box_skiplines" onClick="DoPreview()"' . IsChecked($bBoxSkipLines, 1) . '/> ' . Dict::Format('UI:CSVImport:Skip_N_LinesAtTheBeginning', '<input type="text" size=2 name="nb_skipped_lines" id="nb_skipped_lines" onChange="DoPreview()" value="' . $iSkippedLines . '">') . '<p>'); $oPage->add('</td></tr></table>'); $oPage->add('<input type="hidden" name="csvdata_truncated" id="csvdata_truncated" value="' . htmlentities($sCSVDataTruncated, ENT_QUOTES, 'UTF-8') . '"/>'); $oPage->add('<input type="hidden" name="csvdata" id="csvdata" value="' . htmlentities($sUTF8Data, ENT_QUOTES, 'UTF-8') . '"/>'); // The encoding has changed, keep that information within the wizard $oPage->add('<input type="hidden" name="encoding" value="UTF-8">'); $oPage->add('<input type="hidden" name="class_name" value="' . $sClassName . '"/>'); $oPage->add('<input type="hidden" name="advanced" value="' . $bAdvanced . '"/>'); $oPage->add('<input type="hidden" name="synchro_scope" value="' . $sSynchroScope . '"/>'); foreach ($aFieldsMapping as $iNumber => $sAttCode) { $oPage->add('<input type="hidden" name="field[' . $iNumber . ']" value="' . $sAttCode . '"/>'); } foreach ($aSearchFields as $index => $sDummy) { $oPage->add('<input type="hidden" name="search_field[' . $index . ']" value="1"/>'); } $oPage->add('<input type="hidden" name="step" value="3"/>'); if (!empty($sSynchroScope)) { foreach ($aSynchroUpdate as $sKey => $value) { $oPage->add('<input type="hidden" name="synchro_update[' . $sKey . ']" value="' . $value . '"/>'); } } $oPage->add('<div id="preview">'); $oPage->add('<p style="text-align:center">' . Dict::S('UI:CSVImport:CSVDataPreview') . '</p>'); $oPage->add('</div>'); $oPage->add('<input type="button" value="' . Dict::S('UI:Button:Back') . '" onClick="GoBack()"/>'); $oPage->add('<input type="submit" value="' . Dict::S('UI:Button:Next') . '"/>'); $oPage->add('</form>'); $oPage->add('</div>'); $oPage->add_script(<<<EOF \tfunction GoBack() \t{ \t\t\$('input[name=step]').val(1); \t\t\$('#wizForm').submit(); \t\t \t} \t \tvar ajax_request = null; \t \tfunction DoPreview() \t{ \t\tvar separator = \$('input[name=separator]:checked').val(); \t\tif (separator == 'other') \t\t{ \t\t\tseparator = \$('#other_separator').val(); \t\t} \t\tvar text_qualifier = \$('input[name=text_qualifier]:checked').val(); \t\tif (text_qualifier == 'other') \t\t{ \t\t\ttext_qualifier = \$('#other_qualifier').val(); \t\t} \t\tvar do_skip_lines = 0; \t\tif (\$('#box_skiplines:checked').val() != null) \t\t{ \t\t\tdo_skip_lines = \$('#nb_skipped_lines').val(); \t\t} \t\tvar header_line = 0; \t\tif (\$('#box_header:checked').val() != null) \t\t{ \t\t\theader_line = 1; \t\t} \t\tvar encoding = \$('input[name=encoding]').val(); \t\t\$('#preview').block(); \t\t \t\t// Make sure that we cancel any pending request before issuing another \t\t// since responses may arrive in arbitrary order \t\tif (ajax_request != null) \t\t{ \t\t\tajax_request.abort(); \t\t\tajax_request = null; \t\t} \t\t \t\tajax_request = \$.post(GetAbsoluteUrlAppRoot()+'pages/ajax.csvimport.php', \t\t\t { operation: 'parser_preview', enctype: 'multipart/form-data', csvdata: \$("#csvdata_truncated").val(), separator: separator, qualifier: text_qualifier, do_skip_lines: do_skip_lines, header_line: header_line, encoding: encoding }, \t\t\t function(data) { \t\t\t\t \$('#preview').empty(); \t\t\t\t \$('#preview').append(data); \t\t\t\t \$('#preview').unblock(); \t\t\t\t} \t\t\t ); \t} EOF ); $oPage->add_ready_script('DoPreview();'); }