/** * Determines the shortest SLT, for this ticket, for the given metric. Returns null is no SLT was found * @param string $sMetric Type of metric 'TTO', 'TTR', etc as defined in the SLT class * @return hash Array with 'SLT' => name of the SLT selected, 'value' => duration in seconds of the SLT metric, null if no SLT applies to this ticket */ protected static function ComputeSLT($oTicket, $sMetric = 'TTO') { $iDeadline = null; if (MetaModel::IsValidClass('SLT')) { $sType = get_class($oTicket); if ($sType == 'Incident') { $sRequestType = 'incident'; } else { $sRequestType = $oTicket->Get('request_type'); } $aArgs = $oTicket->ToArgs(); $aArgs['metric'] = $sMetric; $aArgs['request_type'] = $sRequestType; //echo "<p>Managing:".$sMetric."-".$this->Get('request_type')."-".$this->Get('importance')."</p>\n"; $oSLTSet = new DBObjectSet(DBObjectSearch::FromOQL(RESPONSE_TICKET_SLT_QUERY), array(), $aArgs); $iMinDuration = PHP_INT_MAX; $sSLTName = ''; while ($oSLT = $oSLTSet->Fetch()) { $iDuration = (int) $oSLT->Get('value'); $sUnit = $oSLT->Get('unit'); switch ($sUnit) { case 'days': $iDuration = $iDuration * 24; // 24 hours in 1 days // Fall though // 24 hours in 1 days // Fall though case 'hours': $iDuration = $iDuration * 60; // 60 minutes in 1 hour // Fall though // 60 minutes in 1 hour // Fall though case 'minutes': $iDuration = $iDuration * 60; } if ($iDuration < $iMinDuration) { $iMinDuration = $iDuration; $sSLTName = $oSLT->GetName(); } } if ($iMinDuration == PHP_INT_MAX) { $iDeadline = null; } else { // Store $sSLTName to keep track of which SLT has been used $iDeadline = $iMinDuration; } } return $iDeadline; }
public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion) { // Delete all Triggers corresponding to a no more valid class $oSearch = new DBObjectSearch('TriggerOnObject'); $oSet = new DBObjectSet($oSearch); $oChange = null; while ($oTrigger = $oSet->Fetch()) { if (!MetaModel::IsValidClass($oTrigger->Get('target_class'))) { if ($oChange == null) { // Create the change for its first use $oChange = new CMDBChange(); $oChange->Set("date", time()); $oChange->Set("userinfo", "Uninstallation"); $oChange->DBInsert(); } $oTrigger->DBDeleteTracked($oChange); } } }
public function __construct($sClass, $sClassAlias = null) { parent::__construct(); if (is_null($sClassAlias)) { $sClassAlias = $sClass; } if (!is_string($sClass)) { throw new Exception('DBObjectSearch::__construct called with a non-string parameter: $sClass = ' . print_r($sClass, true)); } if (!MetaModel::IsValidClass($sClass)) { throw new Exception('DBObjectSearch::__construct called for an invalid class: "' . $sClass . '"'); } $this->m_aSelectedClasses = array($sClassAlias => $sClass); $this->m_aClasses = array($sClassAlias => $sClass); $this->m_oSearchCondition = new TrueExpression(); $this->m_aParams = array(); $this->m_aFullText = array(); $this->m_aPointingTo = array(); $this->m_aReferencedBy = array(); }
/** * Search objects from a polymorph search specification (Rest/Json) * * @param string $sClass Name of the class * @param mixed $key Either search criteria (substructure), or an object or an OQL string. * @return DBObjectSet The search result set * @throws Exception If the input structure is not valid */ public static function GetObjectSetFromKey($sClass, $key) { if (is_object($key)) { if (isset($key->finalclass)) { $sClass = $key->finalclass; if (!MetaModel::IsValidClass($sClass)) { throw new Exception("finalclass: Unknown class '{$sClass}'"); } } $oSearch = new DBObjectSearch($sClass); foreach ($key as $sAttCode => $value) { $realValue = static::MakeValue($sClass, $sAttCode, $value); $oSearch->AddCondition($sAttCode, $realValue, '='); } } elseif (is_numeric($key)) { $oSearch = new DBObjectSearch($sClass); $oSearch->AddCondition('id', $key); } elseif (is_string($key)) { // OQL $oSearch = DBObjectSearch::FromOQL($key); $oObjectSet = new DBObjectSet($oSearch); } else { throw new Exception("Wrong format for key"); } $oObjectSet = new DBObjectSet($oSearch); return $oObjectSet; }
/** * Applies the defined parameters into the SQL query * @return string the SQL query to execute */ public function BuildQuery() { $oAppContext = new ApplicationContext(); $sQuery = $this->m_sQuery; $sQuery = str_replace('$DB_PREFIX$', MetaModel::GetConfig()->GetDBSubname(), $sQuery); // put the tables DB prefix (if any) foreach ($this->m_aParams as $sName => $aParam) { if ($aParam['type'] == 'context') { $sSearchPattern = '/\\$CONDITION\\(' . $sName . ',([^\\)]+)\\)\\$/'; $value = $oAppContext->GetCurrentValue($aParam['mapping']); if (empty($value)) { $sSQLExpr = '(1)'; } else { // Special case for managing the hierarchy of organizations if ($aParam['mapping'] == 'org_id' && MetaModel::IsValidClass('Organization')) { $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization'); if ($sHierarchicalKeyCode != false) { // organizations are in hierarchy... gather all the orgs below the given one... $sOQL = "SELECT Organization AS node JOIN Organization AS root ON node.{$sHierarchicalKeyCode} BELOW root.id WHERE root.id = :value"; $oSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array('value' => $value)); $aOrgIds = array(); while ($oOrg = $oSet->Fetch()) { $aOrgIds[] = $oOrg->GetKey(); } $sSQLExpr = '($1 IN(' . implode(',', $aOrgIds) . '))'; } else { $sSQLExpr = '($1 = ' . CMDBSource::Quote($value) . ')'; } } else { $sSQLExpr = '($1 = ' . CMDBSource::Quote($value) . ')'; } } $sQuery = preg_replace($sSearchPattern, $sSQLExpr, $sQuery); } } return $sQuery; }
protected function RenderTag($oPage, $sTag, $aAttributes, $sContent) { static $iTabContainerCount = 0; switch ($sTag) { case 'itoptabs': $oPage->AddTabContainer('Tabs_' . $iTabContainerCount); $oPage->SetCurrentTabContainer('Tabs_' . $iTabContainerCount); $iTabContainerCount++; //$oPage->p('Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>'); $oTemplate = new DisplayTemplate($sContent); $oTemplate->Render($oPage, array()); // no params to apply, they have already been applied $oPage->SetCurrentTabContainer(''); break; case 'itopcheck': $sClassName = $aAttributes['class']; if (MetaModel::IsValidClass($sClassName) && UserRights::IsActionAllowed($sClassName, UR_ACTION_READ)) { $oTemplate = new DisplayTemplate($sContent); $oTemplate->Render($oPage, array()); // no params to apply, they have already been applied } else { // Leave a trace for those who'd like to understand why nothing is displayed $oPage->add("<!-- class {$sClassName} does not exist, skipping some part of the template -->\n"); } break; case 'itoptab': $oPage->SetCurrentTab(Dict::S(str_replace('_', ' ', $aAttributes['name']))); $oTemplate = new DisplayTemplate($sContent); $oTemplate->Render($oPage, array()); // no params to apply, they have already been applied //$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>'); $oPage->SetCurrentTab(''); break; case 'itoptoggle': $sName = isset($aAttributes['name']) ? $aAttributes['name'] : 'Tagada'; $bOpen = isset($aAttributes['open']) ? $aAttributes['open'] : true; $oPage->StartCollapsibleSection(Dict::S($sName), $bOpen); $oTemplate = new DisplayTemplate($sContent); $oTemplate->Render($oPage, array()); // no params to apply, they have already been applied //$oPage->p('iTop Tab Content:<pre>'.htmlentities($sContent, ENT_QUOTES, 'UTF-8').'</pre>'); $oPage->EndCollapsibleSection(); break; case 'itopstring': $oPage->add(Dict::S($sContent)); break; case 'sqlblock': $oBlock = SqlBlock::FromTemplate($sContent); $oBlock->RenderContent($oPage); break; case 'itopblock': // No longer used, handled by DisplayBlock::FromTemplate see above $oPage->add("<!-- Application Error: should be handled by DisplayBlock::FromTemplate -->"); break; default: // Unknown tag, just ignore it or now -- output an HTML comment $oPage->add("<!-- unsupported tag: {$sTag} -->"); } }
public function UpdateChildRequestLog() { if (!MetaModel::IsValidClass('UserRequest')) { return true; } // Do nothing $oLog = $this->Get('public_log'); $sLogPublic = $oLog->GetModifiedEntry(); if ($sLogPublic != '') { $sOQL = "SELECT UserRequest WHERE parent_incident_id=:ticket"; $oChildRequestSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array('ticket' => $this->GetKey())); while ($oRequest = $oChildRequestSet->Fetch()) { $oRequest->set('public_log', $sLogPublic); $oRequest->DBUpdate(); } } $oLog = $this->Get('private_log'); $sLogPrivate = $oLog->GetModifiedEntry(); if ($sLogPrivate != '') { $sOQL = "SELECT UserRequest WHERE parent_incident_id=:ticket"; $oChildRequestSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array('ticket' => $this->GetKey())); while ($oRequest = $oChildRequestSet->Fetch()) { $oRequest->set('private_log', $sLogPrivate); $oRequest->DBUpdate(); } } return true; }
protected static function Sanitize_Internal($value, $sSanitizationFilter) { switch ($sSanitizationFilter) { case 'integer': $retValue = filter_var($value, FILTER_SANITIZE_NUMBER_INT); break; case 'class': $retValue = $value; if (!MetaModel::IsValidClass($value)) { $retValue = false; } break; case 'string': $retValue = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS); break; case 'context_param': case 'parameter': case 'field_name': if (is_array($value)) { $retValue = array(); foreach ($value as $key => $val) { $retValue[$key] = self::Sanitize_Internal($val, $sSanitizationFilter); // recursively check arrays if ($retValue[$key] === false) { $retValue = false; break; } } } else { switch ($sSanitizationFilter) { case 'parameter': $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=-]*$/'))); // the '=' equal character is used in serialized filters break; case 'field_name': $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[A-Za-z0-9_]+(->[A-Za-z0-9_]+)*$/'))); // att_code or att_code->name or AttCode->Name or AttCode->Key2->Name break; case 'context_param': $retValue = filter_var($value, FILTER_VALIDATE_REGEXP, array("options" => array("regexp" => '/^[ A-Za-z0-9_=%:+-]*$/'))); break; } } break; default: case 'raw_data': $retValue = $value; // Do nothing } return $retValue; }
public function IsValidClass($sClass) { return MetaModel::IsValidClass($sClass); }
protected function LogMessage($sMessage, $aData = array()) { if (MetaModel::IsLogEnabledIssue()) { if (MetaModel::IsValidClass('EventIssue')) { $oLog = new EventIssue(); $oLog->Set('message', $sMessage); $oLog->Set('userinfo', ''); $oLog->Set('issue', 'LDAP Authentication'); $oLog->Set('impact', 'User login rejected'); $oLog->Set('data', $aData); $oLog->DBInsertNoReload(); } IssueLog::Error($sMessage); } }
public function MakeRealValue($proposedValue, $oHostObj) { $sValue = $proposedValue; if (preg_match_all(WIKI_OBJECT_REGEXP, $sValue, $aAllMatches, PREG_SET_ORDER)) { foreach ($aAllMatches as $iPos => $aMatches) { $sClassLabel = $aMatches[1]; $sName = $aMatches[2]; if (!MetaModel::IsValidClass($sClassLabel)) { $sClass = MetaModel::GetClassFromLabel($sClassLabel); if ($sClass) { $sValue = str_replace($aMatches[0], "[[{$sClass}:{$sName}]]", $sValue); } } } } return $sValue; }
/** * Read the context directly in the PHP parameters (either POST or GET) * return nothing */ protected function ReadContext() { if (!isset(self::$aDefaultValues)) { self::$aDefaultValues = array(); $aContext = utils::ReadParam('c', array(), false, 'context_param'); foreach ($this->aNames as $sName) { $sValue = isset($aContext[$sName]) ? $aContext[$sName] : ''; // TO DO: check if some of the context parameters are mandatory (or have default values) if (!empty($sValue)) { self::$aDefaultValues[$sName] = $sValue; } // Hmm, there must be a better (more generic) way to handle the case below: // When there is only one possible (allowed) organization, the context must be // fixed to this org if ($sName == 'org_id') { if (MetaModel::IsValidClass('Organization')) { $oSearchFilter = new DBObjectSearch('Organization'); $oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true); $oSet = new CMDBObjectSet($oSearchFilter); $iCount = $oSet->Count(); if ($iCount == 1) { // Only one possible value for org_id, set it in the context $oOrg = $oSet->Fetch(); self::$aDefaultValues[$sName] = $oOrg->GetKey(); } } } } } $this->aValues = self::$aDefaultValues; }
function DisplayBareRelations(WebPage $oPage, $bEditMode = false) { parent::DisplayBareRelations($oPage, $bEditMode); if (!$bEditMode) { if (MetaModel::IsValidClass('KnownError')) { //Search for known errors $oPage->SetCurrentTab(Dict::S('Class:UserRequest:KnownErrorList')); $iTicketID = $this->GetKey(); $oKnownErrorSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT KnownError AS ke JOIN lnkErrorToFunctionalCI AS l1 ON l1.error_id=ke.id JOIN FunctionalCI AS ci ON l1.functionalci_id=ci.id JOIN lnkFunctionalCIToTicket AS l2 ON l2.functionalci_id=ci.id WHERE l2.ticket_id={$iTicketID}")); $iNumberKE = $oKnownErrorSet->count(); if ($iNumberKE > 0) { $oPage->SetCurrentTab(Dict::S('Class:UserRequest:KnownErrorList') . " ({$iNumberKE})"); } else { $oPage->SetCurrentTab(Dict::S('Class:UserRequest:KnownErrorList')); } self::DisplaySet($oPage, $oKnownErrorSet, array('menu' => false)); } } }
/** * Helper function to load the objects from a standard XML file into the database * @param $sFilePath string The full path to the XML file to load * @param $bUpdateKeyCacheOnly bool Set to true to *just* update the keys cache but not reload the objects */ function LoadFile($sFilePath, $bUpdateKeyCacheOnly = false) { global $aKeys; $oXml = simplexml_load_file($sFilePath); $aReplicas = array(); foreach ($oXml as $sClass => $oXmlObj) { if (!MetaModel::IsValidClass($sClass)) { SetupPage::log_error("Unknown class - {$sClass}"); throw new Exception("Unknown class - {$sClass}"); } $iSrcId = (int) $oXmlObj['id']; // Mandatory to cast // Import algorithm // Here enumerate all the attributes of the object // for all attribute that is neither an external field // not an external key, assign it // Store all external keys for further reference // Create the object an store the correspondance between its newly created Id // and its original Id // Once all the objects have been created re-assign all the external keys to // their actual Ids $iExistingId = $this->GetObjectKey($sClass, $iSrcId); if ($iExistingId != 0) { $oTargetObj = MetaModel::GetObject($sClass, $iExistingId); } else { $oTargetObj = MetaModel::NewObject($sClass); } foreach ($oXmlObj as $sAttCode => $oSubNode) { if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) { $sMsg = "Unknown attribute code - {$sClass}/{$sAttCode}"; continue; // ignore silently... //SetupPage::log_error($sMsg); //throw(new Exception($sMsg)); } $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode); if ($oAttDef->IsWritable() && $oAttDef->IsScalar()) { if ($oAttDef->IsExternalKey()) { if (substr(trim($oSubNode), 0, 6) == 'SELECT') { $sQuery = trim($oSubNode); $oSet = new DBObjectSet(DBObjectSearch::FromOQL($sQuery)); $iMatches = $oSet->Count(); if ($iMatches == 1) { $oFoundObject = $oSet->Fetch(); $iExtKey = $oFoundObject->GetKey(); } else { $sMsg = "Ext key not reconcilied - {$sClass}/{$iSrcId} - {$sAttCode}: '" . $sQuery . "' - found {$iMatches} matche(s)"; SetupPage::log_error($sMsg); $this->m_aErrors[] = $sMsg; $iExtKey = 0; } } else { $iDstObj = (int) $oSubNode; // Attempt to find the object in the list of loaded objects $iExtKey = $this->GetObjectKey($oAttDef->GetTargetClass(), $iDstObj); if ($iExtKey == 0) { $iExtKey = -$iDstObj; // Convention: Unresolved keys are stored as negative ! $oTargetObj->RegisterAsDirty(); } // here we allow external keys to be invalid because we will resolve them later on... } //$oTargetObj->CheckValue($sAttCode, $iExtKey); $oTargetObj->Set($sAttCode, $iExtKey); } elseif ($oAttDef instanceof AttributeBlob) { $sMimeType = (string) $oSubNode->mimetype; $sFileName = (string) $oSubNode->filename; $data = base64_decode((string) $oSubNode->data); $oDoc = new ormDocument($data, $sMimeType, $sFileName); $oTargetObj->Set($sAttCode, $oDoc); } else { $value = (string) $oSubNode; if ($value == '') { $value = $oAttDef->GetNullValue(); } $res = $oTargetObj->CheckValue($sAttCode, $value); if ($res !== true) { // $res contains the error description $sMsg = "Value not allowed - {$sClass}/{$iSrcId} - {$sAttCode}: '" . $oSubNode . "' ; {$res}"; SetupPage::log_error($sMsg); $this->m_aErrors[] = $sMsg; } $oTargetObj->Set($sAttCode, $value); } } } $this->StoreObject($sClass, $oTargetObj, $iSrcId, $bUpdateKeyCacheOnly, $bUpdateKeyCacheOnly); } return true; }
protected function LoadValues($aArgs) { // Call the parent to parse the additional values... parent::LoadValues($aArgs); // Translate the labels of the additional values foreach ($this->m_aValues as $sClass => $void) { if (MetaModel::IsValidClass($sClass)) { $this->m_aValues[$sClass] = MetaModel::GetName($sClass); } else { unset($this->m_aValues[$sClass]); } } // Then, add the classes from the category definition foreach (MetaModel::GetClasses($this->m_sCategories) as $sClass) { if (MetaModel::IsValidClass($sClass)) { $this->m_aValues[$sClass] = MetaModel::GetName($sClass); } else { unset($this->m_aValues[$sClass]); } } return true; }
protected static function SetProfilesFromCAS($oUser, $aGroups) { if (!MetaModel::IsValidClass('URP_Profiles')) { phpCAS::log("URP_Profiles is not a valid class. Automatic creation of Users is not supported in this context, sorry."); return false; } // read all the existing profiles $oProfilesSearch = new DBObjectSearch('URP_Profiles'); $oProfilesSet = new DBObjectSet($oProfilesSearch); $aAllProfiles = array(); while ($oProfile = $oProfilesSet->Fetch()) { $aAllProfiles[strtolower($oProfile->GetName())] = $oProfile->GetKey(); } // Translate the CAS/LDAP group names into iTop profile names $aProfiles = array(); $sPattern = MetaModel::GetConfig()->Get('cas_profile_pattern'); foreach ($aGroups as $sGroupName) { if (preg_match($sPattern, $sGroupName, $aMatches)) { if (array_key_exists(strtolower($aMatches[1]), $aAllProfiles)) { $aProfiles[] = $aAllProfiles[strtolower($aMatches[1])]; phpCAS::log("Info: Adding the profile '{$aMatches[1]}' from CAS."); } else { phpCAS::log("Warning: {$aMatches[1]} is not a valid iTop profile (extracted from group name: '{$sGroupName}'). Ignored."); } } else { phpCAS::log("Info: The CAS group '{$sGroupName}' does not seem to match an iTop pattern. Ignored."); } } if (count($aProfiles) == 0) { phpCAS::log("Info: The user '" . $oUser->GetName() . "' has no profiles retrieved from CAS. Default profile(s) will be used."); // Second attempt: check if there is/are valid default profile(s) $sCASDefaultProfiles = MetaModel::GetConfig()->Get('cas_default_profiles'); $aCASDefaultProfiles = explode(';', $sCASDefaultProfiles); foreach ($aCASDefaultProfiles as $sDefaultProfileName) { if (array_key_exists(strtolower($sDefaultProfileName), $aAllProfiles)) { $aProfiles[] = $aAllProfiles[strtolower($sDefaultProfileName)]; phpCAS::log("Info: Adding the default profile '" . $aAllProfiles[strtolower($sDefaultProfileName)] . "' from CAS."); } else { phpCAS::log("Warning: the default profile {$sDefaultProfileName} is not a valid iTop profile. Ignored."); } } if (count($aProfiles) == 0) { phpCAS::log("Error: The user '" . $oUser->GetName() . "' has no profiles in iTop, and therefore cannot be created."); return false; } } // Now synchronize the profiles $oProfilesSet = DBObjectSet::FromScratch('URP_UserProfile'); foreach ($aProfiles as $iProfileId) { $oLink = new URP_UserProfile(); $oLink->Set('profileid', $iProfileId); $oLink->Set('reason', 'CAS/LDAP Synchro'); $oProfilesSet->AddObject($oLink); } $oUser->Set('profile_list', $oProfilesSet); phpCAS::log("Info: the user '" . $oUser->GetName() . "' (id=" . $oUser->GetKey() . ") now has the following profiles: '" . implode("', '", $aProfiles) . "'."); if ($oUser->IsModified()) { $oMyChange = MetaModel::NewObject("CMDBChange"); $oMyChange->Set("date", time()); $oMyChange->Set("userinfo", 'CAS/LDAP Synchro'); $oMyChange->DBInsert(); if ($oUser->IsNew()) { $oUser->DBInsertTracked($oMyChange); } else { $oUser->DBUpdateTracked($oMyChange); } } return true; }
/** * Displays the form to select a Template * @param WebPage $oP Web page for the form output * @param Organization $oUserOrg The organization of the current user * @param $iSvcId Id of the selected service in case of pass-through (when there is only one service) * @param integer $iSubSvcId The identifier of the sub-service (fall through when there is only one sub-service) * @return void */ function SelectRequestTemplate($oP, $oUserOrg, $iSvcId = null, $iSubSvcId = null) { $aParameters = $oP->ReadAllParams(PORTAL_ALL_PARAMS . ',template_id'); if (!is_null($iSvcId)) { $aParameters['service_id'] = $iSvcId; } if (!is_null($iSubSvcId)) { $aParameters['servicesubcategory_id'] = $iSubSvcId; } $iDefaultTemplate = isset($aParameters['template_id']) ? $aParameters['template_id'] : 0; if (MetaModel::IsValidClass('Template')) { $sClass = ComputeClass($aParameters['servicesubcategory_id']); try { $sOql = GetConstant($sClass, 'TEMPLATE_QUERY'); } catch (Exception $e) { // Backward compatibility $sOql = REQUEST_TEMPLATE_QUERY; } $oSearch = DBObjectSearch::FromOQL($sOql); $oSearch->AllowAllData(); $oSet = new CMDBObjectSet($oSearch, array(), array('service_id' => $aParameters['service_id'], 'servicesubcategory_id' => $aParameters['servicesubcategory_id'])); if ($oSet->Count() == 0) { RequestCreationForm($oP, $oUserOrg, $aParameters['service_id'], $aParameters['servicesubcategory_id'], 0); return; } elseif ($oSet->Count() == 1) { $oTemplate = $oSet->Fetch(); $iTemplateId = $oTemplate->GetKey(); RequestCreationForm($oP, $oUserOrg, $aParameters['service_id'], $aParameters['servicesubcategory_id'], $iTemplateId); return; } $oServiceSubCategory = MetaModel::GetObject('ServiceSubcategory', $aParameters['servicesubcategory_id'], false); if (is_object($oServiceSubCategory)) { $oP->add("<div class=\"wizContainer\" id=\"form_select_servicesubcategory\">\n"); $oP->add("<h1 id=\"select_template\">" . Dict::Format('Portal:SelectRequestTemplate', $oServiceSubCategory->GetName()) . "</h1>\n"); $oP->WizardFormStart('request_wizard', 3); $oP->add("<table>\n"); while ($oTemplate = $oSet->Fetch()) { $id = $oTemplate->GetKey(); $sChecked = ""; if ($id == $iDefaultTemplate) { $sChecked = "checked"; } $oP->add("<tr>"); $oP->add("<td style=\"vertical-align:top\">"); $oP->p("<input name=\"attr_template_id\" {$sChecked} type=\"radio\" id=\"template_{$id}\" value=\"{$id}\">"); $oP->add("</td>"); $oP->add("<td style=\"vertical-align:top\">"); $oP->p("<b><label for=\"template_{$id}\">" . $oTemplate->GetAsHTML('label') . "</label></b>"); $oP->p($oTemplate->GetAsHTML('description')); $oP->add("</td>"); $oP->add("</tr>"); } $oP->add("</table>\n"); $oP->DumpHiddenParams($aParameters, array('template_id')); $oP->add("<input type=\"hidden\" name=\"operation\" value=\"create_request\">"); $oP->WizardFormButtons(BUTTON_BACK | BUTTON_NEXT | BUTTON_CANCEL); //Back button automatically discarded if on the first page $oP->WizardCheckSelectionOnSubmit(Dict::S('Portal:PleaseSelectATemplate')); $oP->WizardFormEnd(); $oP->add("</div>\n"); } else { $oP->p("Error: Invalid servicesubcategory_id = " . $aParameters['servicesubcategory_id']); } } else { RequestCreationForm($oP, $oUserOrg, $aParameters['service_id'], $aParameters['servicesubcategory_id']); return; } }
public function GetSiloSelectionForm() { // List of visible Organizations $iCount = 0; $oSet = null; if (MetaModel::IsValidClass('Organization')) { // Display the list of *favorite* organizations... but keeping in mind what is the real number of organizations $aFavoriteOrgs = appUserPreferences::GetPref('favorite_orgs', null); $oSearchFilter = new DBObjectSearch('Organization'); $oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true); $oSet = new CMDBObjectSet($oSearchFilter); $iCount = $oSet->Count(); // total number of existing Orgs // Now get the list of Orgs to be displayed in the menu $oSearchFilter = DBObjectSearch::FromOQL(ApplicationMenu::GetFavoriteSiloQuery()); $oSearchFilter->SetModifierProperty('UserRightsGetSelectFilter', 'bSearchMode', true); if (!empty($aFavoriteOrgs)) { $oSearchFilter->AddCondition('id', $aFavoriteOrgs, 'IN'); } $oSet = new CMDBObjectSet($oSearchFilter); // List of favorite orgs } switch ($iCount) { case 0: // No such dimension/silo => nothing to select $sHtml = '<div id="SiloSelection"><!-- nothing to select --></div>'; break; case 1: // Only one possible choice... no selection, but display the value $oOrg = $oSet->Fetch(); $sHtml = '<div id="SiloSelection">' . $oOrg->GetName() . '</div>'; $sHtml .= ''; break; default: $sHtml = ''; $oAppContext = new ApplicationContext(); $iCurrentOrganization = $oAppContext->GetCurrentValue('org_id'); $sHtml = '<div id="SiloSelection">'; $sHtml .= '<form style="display:inline" action="' . utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php">'; //<select class="org_combo" name="c[org_id]" title="Pick an organization" onChange="this.form.submit();">'; $sFavoriteOrgs = ''; $oWidget = new UIExtKeyWidget('Organization', 'org_id', '', true); $sHtml .= $oWidget->Display($this, 50, false, '', $oSet, $iCurrentOrganization, 'org_id', false, 'c[org_id]', '', array('iFieldSize' => 20, 'iMinChars' => MetaModel::GetConfig()->Get('min_autocomplete_chars'), 'sDefaultValue' => Dict::S('UI:AllOrganizations')), null, 'select', false); $this->add_ready_script('$("#org_id").bind("extkeychange", function() { $("#SiloSelection form").submit(); } )'); $this->add_ready_script("\$('#label_org_id').click( function() { \$(this).val(''); \$('#org_id').val(''); return true; } );\n"); // Add other dimensions/context information to this form $oAppContext->Reset('org_id'); // org_id is handled above and we want to be able to change it here ! $oAppContext->Reset('menu'); // don't pass the menu, since a menu may expect more parameters $sHtml .= $oAppContext->GetForForm(); // Pass what remains, if anything... $sHtml .= '</form>'; $sHtml .= '</div>'; } return $sHtml; }
public function CheckProjectionSpec($oProjectionSpec, $sProjectedClass) { $sExpression = $oProjectionSpec->Get('value'); $sAttribute = $oProjectionSpec->Get('attribute'); // Shortcut: "any value" or "no value" means no projection if (empty($sExpression)) { return; } if ($sExpression == '<any>') { return; } // 1st - compute the data type for the dimension // $sType = $this->Get('type'); if (MetaModel::IsValidClass($sType)) { $sExpectedType = $sType; } else { $sExpectedType = '_scalar_'; } // 2nd - compute the data type for the projection // $sTargetClass = ''; if ($sExpression == '<this>' || $sExpression == '<user>') { $sTargetClass = $sProjectedClass; } elseif ($sExpression == '<any>') { $sTargetClass = ''; } else { // Evaluate wether it is a constant or not try { $oObjectSearch = DBObjectSearch::FromOQL_AllData($sExpression); $sTargetClass = $oObjectSearch->GetClass(); } catch (OqlException $e) { } } if (empty($sTargetClass)) { $sFoundType = '_void_'; } else { if (empty($sAttribute)) { $sFoundType = $sTargetClass; } else { if (!MetaModel::IsValidAttCode($sTargetClass, $sAttribute)) { throw new CoreException('Unkown attribute code in projection specification', array('found' => $sAttribute, 'expecting' => MetaModel::GetAttributesList($sTargetClass), 'class' => $sTargetClass, 'projection' => $oProjectionSpec)); } $oAttDef = MetaModel::GetAttributeDef($sTargetClass, $sAttribute); if ($oAttDef->IsExternalKey()) { $sFoundType = $oAttDef->GetTargetClass(); } else { $sFoundType = '_scalar_'; } } } // Compare the dimension type and projection type if ($sFoundType != '_void_' && $sFoundType != $sExpectedType) { throw new CoreException('Wrong type in projection specification', array('found' => $sFoundType, 'expecting' => $sExpectedType, 'expression' => $sExpression, 'attribute' => $sAttribute, 'projection' => $oProjectionSpec)); } }
$sOutput = ReadParam($oP, 'output', 'string'); $sReconcKeys = ReadParam($oP, 'reconciliationkeys', 'raw_data'); $sSimulate = ReadParam($oP, 'simulate'); $sComment = ReadParam($oP, 'comment', 'raw_data'); $bLocalize = ReadParam($oP, 'no_localize') != 1; if (strtolower(trim($sSep)) == 'tab') { $sSep = "\t"; } ////////////////////////////////////////////////// // // Check parameters format/consistency // if (strlen($sCSVData) == 0) { throw new BulkLoadException("Missing data - at least one line is expected"); } if (!MetaModel::IsValidClass($sClass)) { throw new BulkLoadException("Unknown class: '{$sClass}'"); } if (strlen($sSep) > 1) { throw new BulkLoadException("Separator is limited to one character, found '{$sSep}'"); } if (strlen($sQualifier) > 1) { throw new BulkLoadException("Text qualifier is limited to one character, found '{$sQualifier}'"); } if (!in_array($sOutput, array('retcode', 'summary', 'details'))) { throw new BulkLoadException("Unknown output format: '{$sOutput}'"); } if (strlen($sDateFormat) == 0) { $sDateFormat = null; } if ($sCharSet == '') {
$aDefaultKeys[] = $sAttCodeEx; } $sDefaultKeys = '"' . implode('", "', $aDefaultKeys) . '"'; } $oPage->add_ready_script(<<<EOF \t\t\$('select[name^=field]').change( DoCheckMapping ); \t\taDefaultKeys = new Array({$sDefaultKeys}); \t\tDoCheckMapping(); EOF ); } break; case 'get_csv_template': $sClassName = utils::ReadParam('class_name'); $sFormat = utils::ReadParam('format', 'csv'); if (MetaModel::IsValidClass($sClassName)) { $oSearch = new DBObjectSearch($sClassName); $oSearch->AddCondition('id', 0, '='); // Make sure we create an empty set $oSet = new CMDBObjectSet($oSearch); $sResult = cmdbAbstractObject::GetSetAsCSV($oSet, array('showMandatoryFields' => true)); $sClassDisplayName = MetaModel::GetName($sClassName); $sDisposition = utils::ReadParam('disposition', 'inline'); if ($sDisposition == 'attachment') { switch ($sFormat) { case 'xlsx': $oPage = new ajax_page(""); $oPage->SetContentType('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); $oPage->SetContentDisposition('attachment', $sClassDisplayName . '.xlsx'); require_once APPROOT . '/application/excelexporter.class.inc.php'; $writer = new XLSXWriter();
/** * Get the context definitions from the parameters / configuration. The format of the "key" string is: * <module>/relation_context/<class>/<relation>/<direction> * The values will be retrieved for the given class and all its parents and merged together as a single array. * Entries with an invalid query are removed from the list. * @param string $sContextKey The key to fetch the queries in the configuration. Example: itop-tickets/relation_context/UserRequest/impacts/down * @param bool $bDevelopParams Whether or not to substitute the parameters inside the queries with the supplied "context params" * @param array $aContextParams Arguments for the queries (via ToArgs()) if $bDevelopParams == true * @return multitype:multitype:string */ public static function GetContextDefinitions($sContextKey, $bDevelopParams = true, $aContextParams = array()) { $aContextDefs = array(); $aLevels = explode('/', $sContextKey); if (count($aLevels) < 5) { IssueLog::Warning("GetContextDefinitions: invalid 'sContextKey' = '{$sContextKey}'. 5 levels of / are expected !"); } else { $sLeafClass = $aLevels[2]; if (!MetaModel::IsValidClass($sLeafClass)) { IssueLog::Warning("GetContextDefinitions: invalid 'sLeafClass' = '{$sLeafClass}'. A valid class name is expected in 3rd position inside '{$sContextKey}' !"); } else { $aRelationContext = MetaModel::GetConfig()->GetModuleSetting($aLevels[0], $aLevels[1], array()); foreach (MetaModel::EnumParentClasses($sLeafClass, ENUM_PARENT_CLASSES_ALL) as $sClass) { if (isset($aRelationContext[$sClass][$aLevels[3]][$aLevels[4]]['items'])) { $aContextDefs = array_merge($aContextDefs, $aRelationContext[$sClass][$aLevels[3]][$aLevels[4]]['items']); } } // Check if the queries are valid foreach ($aContextDefs as $sKey => $sDefs) { $sOQL = $aContextDefs[$sKey]['oql']; try { // Expand the parameters. If anything goes wrong, then the query is considered as invalid and removed from the list $oSearch = DBObjectSearch::FromOQL($sOQL); $aContextDefs[$sKey]['oql'] = $oSearch->ToOQL($bDevelopParams, $aContextParams); } catch (Exception $e) { IssueLog::Warning('Invalid OQL query: ' . $sOQL . ' in the parameter ' . $sContextKey); unset($aContextDefs[$sKey]); } } } } return $aContextDefs; }
/** * Tells whether the menu is enabled (i.e. displayed) for the current user * @return bool True if enabled, false otherwise */ public function IsEnabled() { foreach ($this->m_aEnableClasses as $index => $sClass) { if ($sClass != null) { if (MetaModel::IsValidClass($sClass)) { if ($this->m_aEnableStimuli[$index] != null) { if (!UserRights::IsStimulusAllowed($sClass, $this->m_aEnableStimuli[$index])) { return false; } } if ($this->m_aEnableActions[$index] != null) { $iResult = UserRights::IsActionAllowed($sClass, $this->m_aEnableActions[$index]); if (!($iResult & $this->m_aEnableActionResults[$index])) { return false; } } } else { return false; } } } return true; }
/** * Give a default value for item_org_id (if relevant...) * @return void */ public function SetDefaultOrgId() { // First check that the organization CAN be fetched from the target class // $sClass = $this->Get('item_class'); $aCallSpec = array($sClass, 'MapContextParam'); if (is_callable($aCallSpec)) { $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter if (MetaModel::IsValidAttCode($sClass, $sAttCode)) { // Second: check that the organization CAN be fetched from the current user // if (MetaModel::IsValidClass('Person')) { $aCallSpec = array($sClass, 'MapContextParam'); if (is_callable($aCallSpec)) { $sAttCode = call_user_func($aCallSpec, 'org_id'); // Returns null when there is no mapping for this parameter if (MetaModel::IsValidAttCode($sClass, $sAttCode)) { // OK - try it // $oCurrentPerson = MetaModel::GetObject('Person', UserRights::GetContactId(), false); if ($oCurrentPerson) { $this->Set('item_org_id', $oCurrentPerson->Get($sAttCode)); } } } } } } }
/** * Helper to link objects * * @param string sLinkAttCode * @param string sLinkedClass * @param array $aLinkList * @param DBObject oTargetObj * @param WebServiceResult oRes * * @return array List of objects that could not be found */ protected function AddLinkedObjects($sLinkAttCode, $sParamName, $sLinkedClass, $aLinkList, &$oTargetObj, &$oRes) { $oLinkAtt = MetaModel::GetAttributeDef(get_class($oTargetObj), $sLinkAttCode); $sLinkClass = $oLinkAtt->GetLinkedClass(); $sExtKeyToItem = $oLinkAtt->GetExtKeyToRemote(); $aItemsFound = array(); $aItemsNotFound = array(); if (is_null($aLinkList)) { return $aItemsNotFound; } foreach ($aLinkList as $aItemData) { if (!array_key_exists('class', $aItemData)) { $oRes->LogWarning("Parameter {$sParamName}: missing 'class' specification"); continue; // skip } $sTargetClass = $aItemData['class']; if (!MetaModel::IsValidClass($sTargetClass)) { $oRes->LogError("Parameter {$sParamName}: invalid class '{$sTargetClass}'"); continue; // skip } if (!MetaModel::IsParentClass($sLinkedClass, $sTargetClass)) { $oRes->LogError("Parameter {$sParamName}: '{$sTargetClass}' is not a child class of '{$sLinkedClass}'"); continue; // skip } $oReconFilter = new CMDBSearchFilter($sTargetClass); $aCIStringDesc = array(); foreach ($aItemData['search'] as $sAttCode => $value) { if (!MetaModel::IsValidFilterCode($sTargetClass, $sAttCode)) { $aCodes = array_keys(MetaModel::GetClassFilterDefs($sTargetClass)); $oRes->LogError("Parameter {$sParamName}: '{$sAttCode}' is not a valid filter code for class '{$sTargetClass}', expecting a value in {" . implode(', ', $aCodes) . "}"); continue 2; // skip the entire item } $aCIStringDesc[] = "{$sAttCode}: {$value}"; // The attribute is one of our reconciliation key $oReconFilter->AddCondition($sAttCode, $value, '='); } if (count($aCIStringDesc) == 1) { // take the last and unique value to describe the object $sItemDesc = $value; } else { // describe the object by the given keys $sItemDesc = $sTargetClass . '(' . implode('/', $aCIStringDesc) . ')'; } $oExtObjects = new CMDBObjectSet($oReconFilter); switch ($oExtObjects->Count()) { case 0: $oRes->LogWarning("Parameter {$sParamName}: object to link {$sLinkedClass} / {$sItemDesc} could not be found (searched: '" . $oReconFilter->ToOQL(true) . "')"); $aItemsNotFound[] = $sItemDesc; break; case 1: $aItemsFound[] = array('object' => $oExtObjects->Fetch(), 'link_values' => @$aItemData['link_values'], 'desc' => $sItemDesc); break; default: $oRes->LogWarning("Parameter {$sParamName}: Found " . $oExtObjects->Count() . " matches for item '{$sItemDesc}' (searched: '" . $oReconFilter->ToOQL(true) . "')"); $aItemsNotFound[] = $sItemDesc; } } if (count($aItemsFound) > 0) { $aLinks = array(); foreach ($aItemsFound as $aItemData) { $oLink = MetaModel::NewObject($sLinkClass); $oLink->Set($sExtKeyToItem, $aItemData['object']->GetKey()); foreach ($aItemData['link_values'] as $sKey => $value) { if (!MetaModel::IsValidAttCode($sLinkClass, $sKey)) { $oRes->LogWarning("Parameter {$sParamName}: Attaching item '" . $aItemData['desc'] . "', the attribute code '{$sKey}' is not valid ; check the class '{$sLinkClass}'"); } else { $oLink->Set($sKey, $value); } } $aLinks[] = $oLink; } $oImpactedInfraSet = DBObjectSet::FromArray($sLinkClass, $aLinks); $oTargetObj->Set($sLinkAttCode, $oImpactedInfraSet); } return $aItemsNotFound; }
public function CreateAdministrator($sAdminUser, $sAdminPwd, $sLanguage = 'EN US') { CMDBObject::SetTrackInfo('Initialization'); $oChange = CMDBObject::GetCurrentChange(); $iContactId = 0; // Support drastic data model changes: no organization class (or not writable)! if (MetaModel::IsValidClass('Organization') && !MetaModel::IsAbstract('Organization')) { $oOrg = new Organization(); $oOrg->Set('name', 'My Company/Department'); $oOrg->Set('code', 'SOMECODE'); $iOrgId = $oOrg->DBInsertTrackedNoReload($oChange, true); // Support drastic data model changes: no Person class (or not writable)! if (MetaModel::IsValidClass('Person') && !MetaModel::IsAbstract('Person')) { $oContact = new Person(); $oContact->Set('name', 'My last name'); $oContact->Set('first_name', 'My first name'); if (MetaModel::IsValidAttCode('Person', 'org_id')) { $oContact->Set('org_id', $iOrgId); } if (MetaModel::IsValidAttCode('Person', 'phone')) { $oContact->Set('phone', '+00 000 000 000'); } $oContact->Set('email', '*****@*****.**'); $iContactId = $oContact->DBInsertTrackedNoReload($oChange, true); } } $oUser = new UserLocal(); $oUser->Set('login', $sAdminUser); $oUser->Set('password', $sAdminPwd); if (MetaModel::IsValidAttCode('UserLocal', 'contactid') && $iContactId != 0) { $oUser->Set('contactid', $iContactId); } $oUser->Set('language', $sLanguage); // Language was chosen during the installation // Add this user to the very specific 'admin' profile $oAdminProfile = MetaModel::GetObjectFromOQL("SELECT URP_Profiles WHERE name = :name", array('name' => ADMIN_PROFILE_NAME), true); if (is_object($oAdminProfile)) { $oUserProfile = new URP_UserProfile(); //$oUserProfile->Set('userid', $iUserId); $oUserProfile->Set('profileid', $oAdminProfile->GetKey()); $oUserProfile->Set('reason', 'By definition, the administrator must have the administrator profile'); //$oUserProfile->DBInsertTrackedNoReload($oChange, true /* skip security */); $oSet = DBObjectSet::FromObject($oUserProfile); $oUser->Set('profile_list', $oSet); } $iUserId = $oUser->DBInsertTrackedNoReload($oChange, true); return true; }
/** * Find the object of the specified Class/ID. * @param WebPage $oP The current page * @return DBObject The found object, or throws an exception in case of failure */ public function FindObjectFromArgs($aAllowedClasses = null) { $sClass = utils::ReadParam('class', '', true, 'class'); $iId = utils::ReadParam('id', 0, true, 'integer'); if (empty($sClass)) { throw new Exception("Missing argument 'class'"); } if (!MetaModel::IsValidClass($sClass)) { throw new Exception("Wrong value for argument 'class': {$sClass}"); } if ($iId == 0) { throw new Exception("Missing argument 'id'"); } if (!is_null($aAllowedClasses)) { $bAllowed = false; foreach ($aAllowedClasses as $sParentClass) { if (MetaModel::IsParentClass($sParentClass, $sClass)) { $bAllowed = true; } } if (!$bAllowed) { throw new Exception("Class '{$sClass} not allowed in this implementation'"); } } $oObj = MetaModel::GetObject($sClass, $iId, false); if (!is_object($oObj)) { throw new Exception("Could not find the object {$sClass}/{$iId}"); } return $oObj; }
$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()); } }