Exemple #1
0
 function DisplayBareProperties(WebPage $oPage, $bEditMode = false, $sPrefix = '', $aExtraParams = array())
 {
     $aFieldsMap = parent::DisplayBareProperties($oPage, $bEditMode, $sPrefix, $aExtraParams);
     if (!$bEditMode) {
         $sUrl = utils::GetAbsoluteUrlAppRoot() . 'webservices/export-v2.php?format=spreadsheet&login_mode=basic&query=' . $this->GetKey();
         $sOql = $this->Get('oql');
         $sMessage = null;
         try {
             $oSearch = DBObjectSearch::FromOQL($sOql);
             $aParameters = $oSearch->GetQueryParams();
             foreach ($aParameters as $sParam => $val) {
                 $sUrl .= '&arg_' . $sParam . '=["' . $sParam . '"]';
             }
             $oPage->p(Dict::S('UI:Query:UrlForExcel') . ':<br/><textarea cols="80" rows="3" READONLY>' . $sUrl . '</textarea>');
             if (count($aParameters) == 0) {
                 $oBlock = new DisplayBlock($oSearch, 'list');
                 $aExtraParams = array('table_id' => 'query_preview_' . $this->getKey());
                 $sBlockId = 'block_query_preview_' . $this->GetKey();
                 // make a unique id (edition occuring in the same DOM)
                 $oBlock->Display($oPage, $sBlockId, $aExtraParams);
             }
         } catch (OQLException $e) {
             $sMessage = '<div class="message message_error" style="padding-left: 30px;"><div style="padding: 10px;">' . Dict::Format('UI:RunQuery:Error', $e->getHtmlDesc()) . '</div></div>';
             $oPage->p($sMessage);
         }
     }
     return $aFieldsMap;
 }
Exemple #2
0
function GetRuleResultFilter($iRuleId, $oDefinitionFilter, $oAppContext)
{
    $oRule = MetaModel::GetObject('AuditRule', $iRuleId);
    $sOql = $oRule->Get('query');
    $oRuleFilter = DBObjectSearch::FromOQL($sOql);
    FilterByContext($oRuleFilter, $oAppContext);
    // Not needed since this filter is a subset of the definition filter, but may speedup things
    if ($oRule->Get('valid_flag') == 'false') {
        // The query returns directly the invalid elements
        $oFilter = $oRuleFilter->Intersect($oDefinitionFilter);
    } else {
        // The query returns only the valid elements, all the others are invalid
        $aValidRows = $oRuleFilter->ToDataArray(array('id'));
        $aValidIds = array();
        foreach ($aValidRows as $aRow) {
            $aValidIds[] = $aRow['id'];
        }
        $oFilter = $oDefinitionFilter->DeepClone();
        if (count($aValidIds) > 0) {
            $aInDefSet = array();
            foreach ($oDefinitionFilter->ToDataArray(array('id')) as $aRow) {
                $aInDefSet[] = $aRow['id'];
            }
            $aInvalids = array_diff($aInDefSet, $aValidIds);
            if (count($aInvalids) > 0) {
                $oFilter->AddCondition('id', $aInvalids, 'IN');
            } else {
                $oFilter->AddCondition('id', 0, '=');
            }
        }
    }
    return $oFilter;
}
 /**
  * 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 function Process($iTimeLimit)
 {
     $sNow = date('Y-m-d H:i:s');
     // Criteria: planned, and expected to occur... ASAP or in the past
     $sOQL = "SELECT AsyncTask WHERE (status = 'planned') AND (ISNULL(planned) OR (planned < '{$sNow}'))";
     $iProcessed = 0;
     while (time() < $iTimeLimit) {
         // Next one ?
         $oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true), array(), null, 1);
         $oTask = $oSet->Fetch();
         if (is_null($oTask)) {
             // Nothing to be done
             break;
         }
         $iProcessed++;
         if ($oTask->Process()) {
             $oTask->DBDelete();
         }
     }
     return "processed {$iProcessed} tasks";
 }
 public function Process($iTimeLimit)
 {
     $sDateLimit = date('Y-m-d H:i:s', time() - 24 * 3600);
     // Every BulkExportResult older than one day will be deleted
     $sOQL = "SELECT BulkExportResult WHERE created < '{$sDateLimit}'";
     $iProcessed = 0;
     while (time() < $iTimeLimit) {
         // Next one ?
         $oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL), array('created' => true), array(), null, 1);
         $oSet->OptimizeColumnLoad(array('temp_file_path'));
         $oResult = $oSet->Fetch();
         if (is_null($oResult)) {
             // Nothing to be done
             break;
         }
         $iProcessed++;
         @unlink($oResult->Get('temp_file_path'));
         $oResult->DBDelete();
     }
     return "Cleaned {$iProcessed} old export results(s).";
 }
 public function Process($iTimeLimit)
 {
     $oMyChange = new CMDBChange();
     $oMyChange->Set("date", time());
     $oMyChange->Set("userinfo", "Automatic updates");
     $iChangeId = $oMyChange->DBInsertNoReload();
     $aReport = array();
     $oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT ResponseTicket WHERE status = \'new\' AND tto_escalation_deadline <= NOW()'));
     while (time() < $iTimeLimit && ($oToEscalate = $oSet->Fetch())) {
         $oToEscalate->ApplyStimulus('ev_timeout');
         //$oToEscalate->Set('tto_escalation_deadline', null);
         $oToEscalate->DBUpdateTracked($oMyChange, true);
         $aReport['reached TTO ESCALATION deadline'][] = $oToEscalate->Get('ref');
     }
     $oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT ResponseTicket WHERE status = \'assigned\' AND ttr_escalation_deadline <= NOW()'));
     while (time() < $iTimeLimit && ($oToEscalate = $oSet->Fetch())) {
         $oToEscalate->ApplyStimulus('ev_timeout');
         //$oToEscalate->Set('ttr_escalation_deadline', null);
         $oToEscalate->DBUpdateTracked($oMyChange, true);
         $aReport['reached TTR ESCALATION deadline'][] = $oToEscalate->Get('ref');
     }
     $oSet = new DBObjectSet(DBObjectSearch::FromOQL('SELECT ResponseTicket WHERE status = \'resolved\' AND closure_deadline <= NOW()'));
     while (time() < $iTimeLimit && ($oToEscalate = $oSet->Fetch())) {
         $oToEscalate->ApplyStimulus('ev_close');
         //$oToEscalate->Set('closure_deadline', null);
         $oToEscalate->DBUpdateTracked($oMyChange, true);
         $aReport['reached closure deadline'][] = $oToEscalate->Get('ref');
     }
     $aStringReport = array();
     foreach ($aReport as $sOperation => $aTicketRefs) {
         if (count($aTicketRefs) > 0) {
             $aStringReport[] = $sOperation . ': ' . count($aTicketRefs) . ' {' . implode(', ', $aTicketRefs) . '}';
         }
     }
     if (count($aStringReport) == 0) {
         return "No ticket to process";
     } else {
         return "Some tickets reached the limit - " . implode('; ', $aStringReport);
     }
 }
 /**
  * Handler called after the creation/update of the database schema
  * @param $oConfiguration Config The new configuration of the application
  * @param $sPreviousVersion string PRevious version number of the module (empty string in case of first install)
  * @param $sCurrentVersion string Current version number of the module
  */
 public static function AfterDatabaseCreation(Config $oConfiguration, $sPreviousVersion, $sCurrentVersion)
 {
     // For each record having item_org_id unset,
     //    get the org_id from the container object
     //
     // Prerequisite: change null into 0 (workaround to the fact that we cannot use IS NULL in OQL)
     SetupPage::log_info("Initializing attachment/item_org_id - null to zero");
     $sTableName = MetaModel::DBGetTable('Attachment');
     $sRepair = "UPDATE `{$sTableName}` SET `item_org_id` = 0 WHERE `item_org_id` IS NULL";
     CMDBSource::Query($sRepair);
     SetupPage::log_info("Initializing attachment/item_org_id - zero to the container");
     $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_org_id = 0");
     $oSet = new DBObjectSet($oSearch);
     $iUpdated = 0;
     while ($oAttachment = $oSet->Fetch()) {
         $oContainer = MetaModel::GetObject($oAttachment->Get('item_class'), $oAttachment->Get('item_id'), false, true);
         if ($oContainer) {
             $oAttachment->SetItem($oContainer, true);
             $iUpdated++;
         }
     }
     SetupPage::log_info("Initializing attachment/item_org_id - {$iUpdated} records have been adjusted");
 }
 public static function RenderOQLSearch($sOql, $sTitle, $sUsageId, $bSearchPane, $bSearchOpen, WebPage $oPage, $aExtraParams = array())
 {
     $sUsageId = utils::GetSafeId($sUsageId);
     $oSearch = DBObjectSearch::FromOQL($sOql);
     $sIcon = MetaModel::GetClassIcon($oSearch->GetClass());
     if ($bSearchPane) {
         $aParams = array_merge(array('open' => $bSearchOpen, 'table_id' => $sUsageId), $aExtraParams);
         $oBlock = new DisplayBlock($oSearch, 'search', false, $aParams);
         $oBlock->Display($oPage, 0);
     }
     $oPage->add("<p class=\"page-header\">{$sIcon} " . Dict::S($sTitle) . "</p>");
     $aParams = array_merge(array('table_id' => $sUsageId), $aExtraParams);
     $oBlock = new DisplayBlock($oSearch, 'list', false, $aParams);
     $oBlock->Display($oPage, $sUsageId);
 }
             // No accelerator query
             array_unshift($aSearchClasses, $sClassName);
         }
     }
 }
 $aSearchClasses = array_values($aSearchClasses);
 // renumbers the array starting from zero, removing the missing indexes
 $fStarted = microtime(true);
 $iFoundInThisRound = 0;
 for ($iPos = $iCurrentPos; $iPos < count($aSearchClasses); $iPos++) {
     if ($iFoundInThisRound && microtime(true) - $fStarted >= $sMaxChunkDuration) {
         break;
     }
     $sClassSpec = $aSearchClasses[$iPos];
     if (substr($sClassSpec, 0, 7) == 'SELECT ') {
         $oFilter = DBObjectSearch::FromOQL($sClassSpec);
         $sClassName = $oFilter->GetClass();
         $sNeedleFormat = isset($aAccelerators[$sClassName]['needle']) ? $aAccelerators[$sClassName]['needle'] : '%$needle$%';
         $sNeedle = str_replace('$needle$', $sFullText, $sNeedleFormat);
         $aParams = array('needle' => $sNeedle);
     } else {
         $sClassName = $sClassSpec;
         $oFilter = new DBObjectSearch($sClassName);
         $aParams = array();
         foreach ($aFullTextNeedles as $sSearchText) {
             $oFilter->AddCondition_FullText($sSearchText);
         }
     }
     // Skip abstract classes
     if (MetaModel::IsAbstract($sClassName)) {
         continue;
 public function Process($iTimeLimit)
 {
     $aList = array();
     foreach (MetaModel::GetClasses() as $sClass) {
         foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
             if ($oAttDef instanceof AttributeStopWatch) {
                 foreach ($oAttDef->ListThresholds() as $iThreshold => $aThresholdData) {
                     $iPercent = $aThresholdData['percent'];
                     // could be different than the index !
                     $sNow = date('Y-m-d H:i:s');
                     $sExpression = "SELECT {$sClass} WHERE {$sAttCode}_laststart AND {$sAttCode}_{$iThreshold}_triggered = 0 AND {$sAttCode}_{$iThreshold}_deadline < '{$sNow}'";
                     $oFilter = DBObjectSearch::FromOQL($sExpression);
                     $oSet = new DBObjectSet($oFilter);
                     while (time() < $iTimeLimit && ($oObj = $oSet->Fetch())) {
                         $sClass = get_class($oObj);
                         $aList[] = $sClass . '::' . $oObj->GetKey() . ' ' . $sAttCode . ' ' . $iThreshold;
                         // Execute planned actions
                         //
                         foreach ($aThresholdData['actions'] as $aActionData) {
                             $sVerb = $aActionData['verb'];
                             $aParams = $aActionData['params'];
                             $aValues = array();
                             foreach ($aParams as $def) {
                                 if (is_string($def)) {
                                     // Old method (pre-2.1.0) non typed parameters
                                     $aValues[] = $def;
                                 } else {
                                     $sParamType = array_key_exists('type', $def) ? $def['type'] : 'string';
                                     switch ($sParamType) {
                                         case 'int':
                                             $value = (int) $def['value'];
                                             break;
                                         case 'float':
                                             $value = (double) $def['value'];
                                             break;
                                         case 'bool':
                                             $value = (bool) $def['value'];
                                             break;
                                         case 'reference':
                                             $value = ${$def['value']};
                                             break;
                                         case 'string':
                                         default:
                                             $value = (string) $def['value'];
                                     }
                                     $aValues[] = $value;
                                 }
                             }
                             $aCallSpec = array($oObj, $sVerb);
                             call_user_func_array($aCallSpec, $aValues);
                         }
                         // Mark the threshold as "triggered"
                         //
                         $oSW = $oObj->Get($sAttCode);
                         $oSW->MarkThresholdAsTriggered($iThreshold);
                         $oObj->Set($sAttCode, $oSW);
                         if ($oObj->IsModified()) {
                             CMDBObject::SetTrackInfo("Automatic - threshold triggered");
                             $oMyChange = CMDBObject::GetCurrentChange();
                             $oObj->DBUpdateTracked($oMyChange, true);
                         }
                         // Activate any existing trigger
                         //
                         $sClassList = implode("', '", MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL));
                         $oTriggerSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnThresholdReached AS t WHERE t.target_class IN ('{$sClassList}') AND stop_watch_code=:stop_watch_code AND threshold_index = :threshold_index"), array(), array('stop_watch_code' => $sAttCode, 'threshold_index' => $iThreshold));
                         while ($oTrigger = $oTriggerSet->Fetch()) {
                             $oTrigger->DoActivate($oObj->ToArgs('this'));
                         }
                     }
                 }
             }
         }
     }
     $iProcessed = count($aList);
     return "Triggered {$iProcessed} threshold(s):" . implode(", ", $aList);
 }
 /**
  * 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;
 }
 protected static function UpdateAttachments($oObject, $oChange = null)
 {
     self::$m_bIsModified = false;
     if (utils::ReadParam('attachment_plugin', 'not-in-form') == 'not-in-form') {
         // Workaround to an issue in iTop < 2.0
         // Leave silently if there is no trace of the attachment form
         return;
     }
     $iTransactionId = utils::ReadParam('transaction_id', null);
     if (!is_null($iTransactionId)) {
         $aActions = array();
         $aAttachmentIds = utils::ReadParam('attachments', array());
         // Get all current attachments
         $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
         $oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
         while ($oAttachment = $oSet->Fetch()) {
             // Remove attachments that are no longer attached to the current object
             if (!in_array($oAttachment->GetKey(), $aAttachmentIds)) {
                 $oAttachment->DBDelete();
                 $aActions[] = self::GetActionDescription($oAttachment, false);
             }
         }
         // Attach new (temporary) attachements
         $sTempId = session_id() . '_' . $iTransactionId;
         // The object is being created from a form, check if there are pending attachments
         // for this object, but deleting the "new" ones that were already removed from the form
         $aRemovedAttachmentIds = utils::ReadParam('removed_attachments', array());
         $sOQL = 'SELECT Attachment WHERE temp_id = :temp_id';
         $oSearch = DBObjectSearch::FromOQL($sOQL);
         foreach ($aAttachmentIds as $iAttachmentId) {
             $oSet = new DBObjectSet($oSearch, array(), array('temp_id' => $sTempId));
             while ($oAttachment = $oSet->Fetch()) {
                 if (in_array($oAttachment->GetKey(), $aRemovedAttachmentIds)) {
                     $oAttachment->DBDelete();
                     // temporary attachment removed, don't even mention it in the history
                 } else {
                     $oAttachment->SetItem($oObject);
                     $oAttachment->Set('temp_id', '');
                     $oAttachment->DBUpdate();
                     // temporary attachment confirmed, list it in the history
                     $aActions[] = self::GetActionDescription($oAttachment, true);
                 }
             }
         }
         if (count($aActions) > 0) {
             if ($oChange == null) {
                 // Let's create a change if non is supplied
                 $oChange = MetaModel::NewObject("CMDBChange");
                 $oChange->Set("date", time());
                 $sUserString = CMDBChange::GetCurrentUserName();
                 $oChange->Set("userinfo", $sUserString);
                 $iChangeId = $oChange->DBInsert();
             }
             foreach ($aActions as $sActionDescription) {
                 self::RecordHistory($oChange, $oObject, $sActionDescription);
             }
             self::$m_bIsModified = true;
         }
     }
 }
 /**
  * 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);
         }
     }
 }
 protected function DeleteConnectedNetworkDevice()
 {
     // The device might be already deleted (reentrance in the current procedure when both device are NETWORK devices!)
     $oDevice = MetaModel::GetObject('ConnectableCI', $this->Get('connectableci_id'), false);
     if (is_object($oDevice) && get_class($oDevice) == 'NetworkDevice') {
         // Track and delete the counterpart link
         $sOQL = "SELECT  lnkConnectableCIToNetworkDevice WHERE connectableci_id = :device AND networkdevice_id = :network AND network_port = :nwport AND device_port = :devport";
         $oConnectionSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array('network' => $this->Get('connectableci_id'), 'device' => $this->Get('networkdevice_id'), 'devport' => $this->Get('network_port'), 'nwport' => $this->Get('device_port')));
         // There should be one link - do it in a safe manner anyway
         while ($oConnection = $oConnectionSet->Fetch()) {
             $oConnection->DBDelete();
         }
     }
 }
 /**
  * Do the synchronization job #3: Delete replica depending on the obsolescence scheme
  * @param integer $iMaxReplica Limit the number of replicas to process 
  * @param integer $iCurrPos Current position where to resume the processing 
  * @return true if the process must be continued
  */
 protected function DoJob3($iMaxReplica = null, $iCurrPos = -1)
 {
     $sDeletePolicy = $this->m_oDataSource->Get('delete_policy');
     if ($sDeletePolicy != 'update_then_delete') {
         // Job complete!
         $this->m_oStatLog->Set('status_curr_job', 0);
         $this->m_oStatLog->Set('status_curr_pos', -1);
         return false;
     }
     $bFirstPass = $iCurrPos == -1;
     // Get all the replicas that are to be deleted
     //
     $oDeletionDate = $this->m_oLastFullLoadStartDate;
     $iDeleteRetention = $this->m_oDataSource->Get('delete_policy_retention');
     // Duration in seconds
     if ($iDeleteRetention > 0) {
         $sInterval = "-{$iDeleteRetention} seconds";
         $oDeletionDate->Modify($sInterval);
     }
     $sDeletionDate = $oDeletionDate->Format('Y-m-d H:i:s');
     if ($bFirstPass) {
         $this->m_oStatLog->AddTrace("Deletion date: {$sDeletionDate}");
     }
     $sSelectToDelete = "SELECT SynchroReplica WHERE id > :curr_pos AND sync_source_id = :source_id AND status IN ('obsolete') AND status_last_seen < :last_import";
     $oSetScope = new DBObjectSet(DBObjectSearch::FromOQL($sSelectToDelete), array(), array('source_id' => $this->m_oDataSource->GetKey(), 'last_import' => $sDeletionDate, 'curr_pos' => $iCurrPos));
     $iCountScope = $oSetScope->Count();
     if ($iMaxReplica) {
         // Consider a given subset, starting from replica iCurrPos, limited to the count of iMaxReplica
         // The replica have to be ordered by id
         $oSetToProcess = new DBObjectSet(DBObjectSearch::FromOQL($sSelectToDelete), array('id' => true), array('source_id' => $this->m_oDataSource->GetKey(), 'last_import' => $sDeletionDate, 'curr_pos' => $iCurrPos));
         $oSetToProcess->SetLimit($iMaxReplica);
     } else {
         $oSetToProcess = $oSetScope;
     }
     $iLastReplicaProcessed = -1;
     while ($oReplica = $oSetToProcess->Fetch()) {
         $iLastReplicaProcessed = $oReplica->GetKey();
         $this->m_oStatLog->AddTrace("Destination object to be DELETED", $oReplica);
         $oReplica->DeleteDestObject($this->m_oChange, $this->m_oStatLog);
     }
     if ($iMaxReplica) {
         if ($iMaxReplica < $iCountScope) {
             // Continue with this job!
             $this->m_oStatLog->Set('status_curr_pos', $iLastReplicaProcessed);
             return true;
         }
     }
     // Job complete!
     $this->m_oStatLog->Set('status_curr_job', 0);
     $this->m_oStatLog->Set('status_curr_pos', -1);
     return false;
 }
 public function IsTargetObject($iObjectId)
 {
     $sFilter = trim($this->Get('filter'));
     if (strlen($sFilter) > 0) {
         $oSearch = DBObjectSearch::FromOQL($sFilter);
         $oSearch->AddCondition('id', $iObjectId, '=');
         $oSet = new DBObjectSet($oSearch);
         $bRet = $oSet->Count() > 0;
     } else {
         $bRet = true;
     }
     return $bRet;
 }
 public function GetAllowedValuesAsObjectSet($aArgs = array(), $sContains = '')
 {
     $oValSetDef = $this->GetValuesDef();
     if (array_key_exists('this', $aArgs)) {
         // Hierarchical keys have one more constraint: the "parent value" cannot be
         // "under" themselves
         $iRootId = $aArgs['this']->GetKey();
         if ($iRootId > 0) {
             $aValuesSetDef = $this->GetValuesDef();
             $sClass = $this->m_sTargetClass;
             $oFilter = DBObjectSearch::FromOQL("SELECT {$sClass} AS node JOIN {$sClass} AS root ON node." . $this->GetCode() . " NOT BELOW root.id WHERE root.id = {$iRootId}");
             $oValSetDef->AddCondition($oFilter);
         }
     }
     $oSet = $oValSetDef->ToObjectSet($aArgs, $sContains);
     return $oSet;
 }
Exemple #18
0
/**
 * Determine if the current user can be considered as being a portal power user
 */
function IsPowerUSer()
{
    $iUserID = UserRights::GetUserId();
    $sOQLprofile = "SELECT URP_Profiles AS p JOIN URP_UserProfile AS up ON up.profileid=p.id WHERE up.userid = :user AND p.name = :profile";
    $oProfileSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQLprofile), array(), array('user' => $iUserID, 'profile' => PORTAL_POWER_USER_PROFILE));
    $bRes = $oProfileSet->count() > 0;
    return $bRes;
}
 /**
  * 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;
 }
    protected function RenderChart($oPage, $sId, $aValues, $sDrillDown = '', $aRows = array())
    {
        // 1- Compute Open Flash Chart data
        //
        $aValueKeys = array();
        $index = 0;
        if (count($aValues) > 0 && $sDrillDown != '') {
            $oFilter = DBObjectSearch::FromOQL($sDrillDown);
            $sClass = $oFilter->GetClass();
            $sOQLClause = str_replace('SELECT ' . $sClass, '', $sDrillDown);
            $aSQLColNames = array_keys(current($aRows));
            // Read the list of columns from the current (i.e. first) element of the array
            $oAppContext = new ApplicationContext();
            $sURL = utils::GetAbsoluteUrlAppRoot() . 'pages/UI.php?operation=search_oql&search_form=0&oql_class=' . $sClass . '&format=html&' . $oAppContext->GetForLink() . '&oql_clause=';
        }
        $aURLs = array();
        foreach ($aValues as $key => $value) {
            // Make sure that values are integers (so that max() will work....)
            // and build an array of STRING with the keys (numeric keys are transformed into string by PHP :-(
            $aValues[$key] = (int) $value;
            $aValueKeys[] = (string) $key;
            // Build the custom query for the 'drill down' on each element
            if ($sDrillDown != '') {
                $sFilter = $sOQLClause;
                foreach ($aSQLColNames as $sColName) {
                    $sFilter = str_replace(':' . $sColName, "'" . addslashes($aRows[$key][$sColName]) . "'", $sFilter);
                    $aURLs[$index] = $sURL . urlencode($sFilter);
                }
            }
            $index++;
        }
        $oChart = new open_flash_chart();
        if ($this->m_sType == 'bars') {
            $oChartElement = new bar_glass();
            if (count($aValues) > 0) {
                $maxValue = max($aValues);
            } else {
                $maxValue = 1;
            }
            $oYAxis = new y_axis();
            $aMagicValues = array(1, 2, 5, 10);
            $iMultiplier = 1;
            $index = 0;
            $iTop = $aMagicValues[$index % count($aMagicValues)] * $iMultiplier;
            while ($maxValue > $iTop) {
                $index++;
                $iTop = $aMagicValues[$index % count($aMagicValues)] * $iMultiplier;
                if ($index % count($aMagicValues) == 0) {
                    $iMultiplier = $iMultiplier * 10;
                }
            }
            //echo "oYAxis->set_range(0, $iTop, $iMultiplier);\n";
            $oYAxis->set_range(0, $iTop, $iMultiplier);
            $oChart->set_y_axis($oYAxis);
            $aBarValues = array();
            foreach ($aValues as $iValue) {
                $oBarValue = new bar_value($iValue);
                $oBarValue->on_click("ofc_drilldown_{$sId}");
                $aBarValues[] = $oBarValue;
            }
            $oChartElement->set_values($aBarValues);
            //$oChartElement->set_values(array_values($aValues));
            $oXAxis = new x_axis();
            $oXLabels = new x_axis_labels();
            // set them vertical
            $oXLabels->set_vertical();
            // set the label text
            $oXLabels->set_labels($aValueKeys);
            // Add the X Axis Labels to the X Axis
            $oXAxis->set_labels($oXLabels);
            $oChart->set_x_axis($oXAxis);
        } else {
            $oChartElement = new pie();
            $oChartElement->set_start_angle(35);
            $oChartElement->set_animate(true);
            $oChartElement->set_tooltip('#label# - #val# (#percent#)');
            $oChartElement->set_colours(array('#FF8A00', '#909980', '#2C2B33', '#CCC08D', '#596664'));
            $aData = array();
            foreach ($aValues as $sValue => $iValue) {
                $oPieValue = new pie_value($iValue, $sValue);
                //@@ BUG: not passed via ajax !!!
                $oPieValue->on_click("ofc_drilldown_{$sId}");
                $aData[] = $oPieValue;
            }
            $oChartElement->set_values($aData);
            $oChart->x_axis = null;
        }
        // Title given in HTML
        //$oTitle = new title($this->m_sTitle);
        //$oChart->set_title($oTitle);
        $oChart->set_bg_colour('#FFFFFF');
        $oChart->add_element($oChartElement);
        $sData = $oChart->toPrettyString();
        $sData = json_encode($sData);
        // 2- Declare the Javascript function that will render the chart data\
        //
        $oPage->add_script(<<<EOF
function ofc_get_data_{$sId}()
{
\treturn {$sData};
}
EOF
);
        if (count($aURLs) > 0) {
            $sURLList = '';
            foreach ($aURLs as $index => $sURL) {
                $sURLList .= "\taURLs[{$index}] = '" . addslashes($sURL) . "';\n";
            }
            $oPage->add_script(<<<EOF
function ofc_drilldown_{$sId}(index)
{
\tvar aURLs = new Array();
{$sURLList}
\tvar sURL = aURLs[index];
\t
\twindow.location.href = sURL; // Navigate ! 
}
EOF
);
        }
        // 3- Insert the Open Flash chart
        //
        $oPage->add("<div id=\"{$sId}\"><div>\n");
        $oPage->add_ready_script(<<<EOF
swfobject.embedSWF(\t"../images/open-flash-chart.swf", 
\t"{$sId}", 
\t"100%", "300","9.0.0",
\t"expressInstall.swf",
\t{"get-data":"ofc_get_data_{$sId}", "id":"{$sId}"}, 
\t{'wmode': 'transparent'}
);
EOF
);
    }
 /**
  *	throws an exception in case of a wrong syntax
  */
 public function __construct($sOQL, ModelReflection $oModelReflection)
 {
     $this->oFilter = DBObjectSearch::FromOQL($sOQL);
 }
 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);
     }
 }
Exemple #23
0
/**
 * Checks the parameters and returns the appropriate exporter (if any)
 * @param string $sExpression The OQL query to export or null
 * @param string $sQueryId The entry in the query phrasebook if $sExpression is null
 * @param string $sFormat The code of export format: csv, pdf, html, xlsx
 * @throws MissingQueryArgument
 * @return Ambigous <iBulkExport, NULL>
 */
function CheckParameters($sExpression, $sQueryId, $sFormat)
{
    $oExporter = null;
    if ($sExpression === null && $sQueryId === null) {
        ReportErrorAndUsage("Missing parameter. The parameter 'expression' or 'query' must be specified.");
    }
    // Either $sExpression or $sQueryId must be specified
    if ($sExpression === 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();
            $sExpression = $oQuery->Get('oql');
            $sFields = $oQuery->Get('fields');
            if (strlen($sFields) == 0) {
                $sFields = trim($oQuery->Get('fields'));
            }
        } else {
            ReportErrorAndExit("Invalid query phrasebook identifier: '{$sQueryId}'");
        }
    }
    if ($sFormat === null) {
        ReportErrorAndUsage("Missing parameter 'format'.");
    }
    // Check if the supplied query is valid (and all the parameters are supplied
    try {
        $oSearch = DBObjectSearch::FromOQL($sExpression);
        $aArgs = array();
        foreach ($oSearch->GetQueryParams() as $sParam => $foo) {
            $value = utils::ReadParam('arg_' . $sParam, null, true, 'raw_data');
            if (!is_null($value)) {
                $aArgs[$sParam] = $value;
            } else {
                throw new MissingQueryArgument("Missing parameter '--arg_{$sParam}'");
            }
        }
        $oSearch->SetInternalParams($aArgs);
        $sFormat = utils::ReadParam('format', 'html', true, 'raw_data');
        $oExporter = BulkExport::FindExporter($sFormat, $oSearch);
        if ($oExporter == null) {
            $aSupportedFormats = BulkExport::FindSupportedFormats();
            ReportErrorAndExit("Invalid output format: '{$sFormat}'. The supported formats are: " . implode(', ', array_keys($aSupportedFormats)));
        }
    } catch (MissingQueryArgument $e) {
        ReportErrorAndUsage("Invalid OQL query: '{$sExpression}'.\n" . $e->getMessage());
    } catch (OQLException $e) {
        ReportErrorAndExit("Invalid OQL query: '{$sExpression}'.\n" . $e->getMessage());
    } catch (Exception $e) {
        ReportErrorAndExit($e->getMessage());
    }
    $oExporter->SetFormat($sFormat);
    $oExporter->SetChunkSize(EXPORTER_DEFAULT_CHUNK_SIZE);
    $oExporter->SetObjectList($oSearch);
    $oExporter->ReadParameters();
    return $oExporter;
}
 protected function _SearchObjects($sOQL)
 {
     $oRes = new WebServiceResult();
     try {
         $oSearch = DBObjectSearch::FromOQL($sOQL);
         $oSet = new DBObjectSet($oSearch);
         $aData = $oSet->ToArrayOfValues();
         foreach ($aData as $iRow => $aRow) {
             $oRes->AddResultRow("row_{$iRow}", $aRow);
         }
     } catch (CoreException $e) {
         $oRes->LogError($e->getMessage());
     } catch (Exception $e) {
         $oRes->LogError($e->getMessage());
     }
     $this->LogUsage(__FUNCTION__, $oRes);
     return $oRes;
 }
    /**
     * Display a form for modifying several objects at once
     * The form will be submitted to the current page, with the specified additional values	 
     */
    public static function DisplayBulkModifyForm($oP, $sClass, $aSelectedObj, $sCustomOperation, $sCancelUrl, $aExcludeAttributes = array(), $aContextData = array())
    {
        if (count($aSelectedObj) > 0) {
            $iAllowedCount = count($aSelectedObj);
            $sSelectedObj = implode(',', $aSelectedObj);
            $sOQL = "SELECT {$sClass} WHERE id IN (" . $sSelectedObj . ")";
            $oSet = new CMDBObjectSet(DBObjectSearch::FromOQL($sOQL));
            // Compute the distribution of the values for each field to determine which of the "scalar" fields are homogenous
            $aList = MetaModel::ListAttributeDefs($sClass);
            $aValues = array();
            foreach ($aList as $sAttCode => $oAttDef) {
                if ($oAttDef->IsScalar()) {
                    $aValues[$sAttCode] = array();
                }
            }
            while ($oObj = $oSet->Fetch()) {
                foreach ($aList as $sAttCode => $oAttDef) {
                    if ($oAttDef->IsScalar() && $oAttDef->IsWritable()) {
                        $currValue = $oObj->Get($sAttCode);
                        if ($oAttDef instanceof AttributeCaseLog) {
                            $currValue = ' ';
                            // Don't put an empty string, in case the field would be considered as mandatory...
                        }
                        if (is_object($currValue)) {
                            continue;
                        }
                        // Skip non scalar values...
                        if (!array_key_exists($currValue, $aValues[$sAttCode])) {
                            $aValues[$sAttCode][$currValue] = array('count' => 1, 'display' => $oObj->GetAsHTML($sAttCode));
                        } else {
                            $aValues[$sAttCode][$currValue]['count']++;
                        }
                    }
                }
            }
            // Now create an object that has values for the homogenous values only
            $oDummyObj = new $sClass();
            // @@ What if the class is abstract ?
            $aComments = array();
            function MyComparison($a, $b)
            {
                if ($a['count'] == $b['count']) {
                    return 0;
                }
                return $a['count'] > $b['count'] ? -1 : 1;
            }
            $iFormId = cmdbAbstractObject::GetNextFormId();
            // Identifier that prefixes all the form fields
            $sReadyScript = '';
            $aDependsOn = array();
            $sFormPrefix = '2_';
            foreach ($aList as $sAttCode => $oAttDef) {
                $aPrerequisites = MetaModel::GetPrerequisiteAttributes($sClass, $sAttCode);
                // List of attributes that are needed for the current one
                if (count($aPrerequisites) > 0) {
                    // When 'enabling' a field, all its prerequisites must be enabled too
                    $sFieldList = "['{$sFormPrefix}" . implode("','{$sFormPrefix}", $aPrerequisites) . "']";
                    $oP->add_ready_script("\$('#enable_{$sFormPrefix}{$sAttCode}').bind('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, {$sFieldList}, true); } );\n");
                }
                $aDependents = MetaModel::GetDependentAttributes($sClass, $sAttCode);
                // List of attributes that are needed for the current one
                if (count($aDependents) > 0) {
                    // When 'disabling' a field, all its dependent fields must be disabled too
                    $sFieldList = "['{$sFormPrefix}" . implode("','{$sFormPrefix}", $aDependents) . "']";
                    $oP->add_ready_script("\$('#enable_{$sFormPrefix}{$sAttCode}').bind('change', function(evt, sFormId) { return PropagateCheckBox( this.checked, {$sFieldList}, false); } );\n");
                }
                if ($oAttDef->IsScalar() && $oAttDef->IsWritable()) {
                    if ($oAttDef->GetEditClass() == 'One Way Password') {
                        $sTip = "Unknown values";
                        $sReadyScript .= "\$('#multi_values_{$sAttCode}').qtip( { content: '{$sTip}', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );";
                        $oDummyObj->Set($sAttCode, null);
                        $aComments[$sAttCode] = '<input type="checkbox" id="enable_' . $iFormId . '_' . $sAttCode . '" onClick="ToogleField(this.checked, \'' . $iFormId . '_' . $sAttCode . '\')"/>';
                        $aComments[$sAttCode] .= '<div class="multi_values" id="multi_values_' . $sAttCode . '"> ? </div>';
                        $sReadyScript .= 'ToogleField(false, \'' . $iFormId . '_' . $sAttCode . '\');' . "\n";
                    } else {
                        $iCount = count($aValues[$sAttCode]);
                        if ($iCount == 1) {
                            // Homogenous value
                            reset($aValues[$sAttCode]);
                            $aKeys = array_keys($aValues[$sAttCode]);
                            $currValue = $aKeys[0];
                            // The only value is the first key
                            //echo "<p>current value for $sAttCode : $currValue</p>";
                            $oDummyObj->Set($sAttCode, $currValue);
                            $aComments[$sAttCode] = '';
                            if ($sAttCode != MetaModel::GetStateAttributeCode($sClass)) {
                                $aComments[$sAttCode] .= '<input type="checkbox" checked id="enable_' . $iFormId . '_' . $sAttCode . '"  onClick="ToogleField(this.checked, \'' . $iFormId . '_' . $sAttCode . '\')"/>';
                            }
                            $aComments[$sAttCode] .= '<div class="mono_value">1</div>';
                        } else {
                            // Non-homogenous value
                            $aMultiValues = $aValues[$sAttCode];
                            uasort($aMultiValues, 'MyComparison');
                            $iMaxCount = 5;
                            $sTip = "<p><b>" . Dict::Format('UI:BulkModify_Count_DistinctValues', $iCount) . "</b><ul>";
                            $index = 0;
                            foreach ($aMultiValues as $sCurrValue => $aVal) {
                                $sDisplayValue = empty($aVal['display']) ? '<i>' . Dict::S('Enum:Undefined') . '</i>' : str_replace(array("\n", "\r"), " ", $aVal['display']);
                                $sTip .= "<li>" . Dict::Format('UI:BulkModify:Value_Exists_N_Times', $sDisplayValue, $aVal['count']) . "</li>";
                                $index++;
                                if ($iMaxCount == $index) {
                                    $sTip .= "<li>" . Dict::Format('UI:BulkModify:N_MoreValues', count($aMultiValues) - $iMaxCount) . "</li>";
                                    break;
                                }
                            }
                            $sTip .= "</ul></p>";
                            $sTip = addslashes($sTip);
                            $sReadyScript .= "\$('#multi_values_{$sAttCode}').qtip( { content: '{$sTip}', show: 'mouseover', hide: 'mouseout', style: { name: 'dark', tip: 'leftTop' }, position: { corner: { target: 'rightMiddle', tooltip: 'leftTop' }} } );";
                            $oDummyObj->Set($sAttCode, null);
                            $aComments[$sAttCode] = '';
                            if ($sAttCode != MetaModel::GetStateAttributeCode($sClass)) {
                                $aComments[$sAttCode] .= '<input type="checkbox" id="enable_' . $iFormId . '_' . $sAttCode . '" onClick="ToogleField(this.checked, \'' . $iFormId . '_' . $sAttCode . '\')"/>';
                            }
                            $aComments[$sAttCode] .= '<div class="multi_values" id="multi_values_' . $sAttCode . '">' . $iCount . '</div>';
                        }
                        $sReadyScript .= 'ToogleField(' . ($iCount == 1 ? 'true' : 'false') . ', \'' . $iFormId . '_' . $sAttCode . '\');' . "\n";
                    }
                }
            }
            $sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
            if ($sStateAttCode != '' && $oDummyObj->GetState() == '') {
                // Hmmm, it's not gonna work like this ! Set a default value for the "state"
                // Maybe we should use the "state" that is the most common among the objects...
                $aMultiValues = $aValues[$sStateAttCode];
                uasort($aMultiValues, 'MyComparison');
                foreach ($aMultiValues as $sCurrValue => $aVal) {
                    $oDummyObj->Set($sStateAttCode, $sCurrValue);
                    break;
                }
                //$oStateAtt = MetaModel::GetAttributeDef($sClass, $sStateAttCode);
                //$oDummyObj->Set($sStateAttCode, $oStateAtt->GetDefaultValue());
            }
            $oP->add("<div class=\"page_header\">\n");
            $oP->add("<h1>" . $oDummyObj->GetIcon() . "&nbsp;" . Dict::Format('UI:Modify_M_ObjectsOf_Class_OutOf_N', $iAllowedCount, $sClass, $iAllowedCount) . "</h1>\n");
            $oP->add("</div>\n");
            $oP->add("<div class=\"wizContainer\">\n");
            $sDisableFields = json_encode($aExcludeAttributes);
            $aParams = array('fieldsComments' => $aComments, 'noRelations' => true, 'custom_operation' => $sCustomOperation, 'custom_button' => Dict::S('UI:Button:PreviewModifications'), 'selectObj' => $sSelectedObj, 'preview_mode' => true, 'disabled_fields' => $sDisableFields, 'disable_plugins' => true);
            $aParams = $aParams + $aContextData;
            // merge keeping associations
            $oDummyObj->DisplayModifyForm($oP, $aParams);
            $oP->add("</div>\n");
            $oP->add_ready_script($sReadyScript);
            $oP->add_ready_script(<<<EOF
\$('.wizContainer button.cancel').unbind('click');
\$('.wizContainer button.cancel').click( function() { window.location.href = '{$sCancelUrl}'; } );
EOF
);
        } else {
            $oP->p("No object selected !, nothing to do");
        }
    }
 /**
  * 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');\">&nbsp;&nbsp;");
     $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");
 }
                    $oAttachment->Set('item_class', $sObjClass);
                    $oAttachment->SetDefaultOrgId();
                    $oAttachment->Set('contents', $oDoc);
                    $iAttId = $oAttachment->DBInsert();
                    $aResult['msg'] = $oDoc->GetFileName();
                    $aResult['icon'] = utils::GetAbsoluteUrlAppRoot() . AttachmentPlugIn::GetFileIcon($oDoc->GetFileName());
                    $aResult['att_id'] = $iAttId;
                    $aResult['preview'] = $oDoc->IsPreviewAvailable() ? 'true' : 'false';
                } catch (FileUploadException $e) {
                    $aResult['error'] = $e->GetMessage();
                }
            }
            $oPage->add(json_encode($aResult));
            break;
        case 'remove':
            $iAttachmentId = utils::ReadParam('att_id', '');
            $oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE id = :id");
            $oSet = new DBObjectSet($oSearch, array(), array('id' => $iAttachmentId));
            while ($oAttachment = $oSet->Fetch()) {
                $oAttachment->DBDelete();
            }
            break;
        default:
            $oPage->p("Missing argument 'operation'");
    }
    $oPage->output();
} catch (Exception $e) {
    // note: transform to cope with XSS attacks
    echo htmlentities($e->GetMessage(), ENT_QUOTES, 'utf-8');
    IssueLog::Error($e->getMessage());
}
 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;
 }
 /**
  * Determine if there is a redundancy (or use the existing one) and add the corresponding nodes/edges	
  */
 protected function ComputeRedundancy($sRelCode, $aQueryInfo, $oFromNode, $oToNode)
 {
     $oRedundancyNode = null;
     $oObject = $oToNode->GetProperty('object');
     if ($this->IsRedundancyEnabled($sRelCode, $aQueryInfo, $oToNode)) {
         $sId = RelationRedundancyNode::MakeId($sRelCode, $aQueryInfo['sNeighbour'], $oToNode->GetProperty('object'));
         $oRedundancyNode = $this->GetNode($sId);
         if (is_null($oRedundancyNode)) {
             // Get the upper neighbours
             $sQuery = $aQueryInfo['sQueryUp'];
             try {
                 $oFlt = DBObjectSearch::FromOQL($sQuery);
                 $oObjSet = new DBObjectSet($oFlt, array(), $oObject->ToArgsForQuery());
                 $iCount = $oObjSet->Count();
             } catch (Exception $e) {
                 throw new Exception("Wrong query (upstream) for the relation {$sRelCode}/{$aQueryInfo['sDefinedInClass']}/{$aQueryInfo['sNeighbour']}: " . $e->getMessage());
             }
             $iMinUp = $this->GetRedundancyMinUp($sRelCode, $aQueryInfo, $oToNode, $iCount);
             $fThreshold = max(0, $iCount - $iMinUp);
             $oRedundancyNode = new RelationRedundancyNode($this, $sId, $iMinUp, $fThreshold);
             new RelationEdge($this, $oRedundancyNode, $oToNode);
             while ($oUpperObj = $oObjSet->Fetch()) {
                 $sObjectRef = RelationObjectNode::MakeId($oUpperObj);
                 $oUpperNode = $this->GetNode($sObjectRef);
                 if (is_null($oUpperNode)) {
                     $oUpperNode = new RelationObjectNode($this, $oUpperObj);
                 }
                 new RelationEdge($this, $oUpperNode, $oRedundancyNode);
             }
         }
     }
     return $oRedundancyNode;
 }
 public function InSyncScope()
 {
     //
     // Optimization: cache the list of Data Sources and classes candidates for synchro
     //
     static $aSynchroClasses = null;
     if (is_null($aSynchroClasses)) {
         $aSynchroClasses = array();
         $sOQL = "SELECT SynchroDataSource AS datasource";
         $oSourceSet = new DBObjectSet(DBObjectSearch::FromOQL($sOQL), array(), array());
         while ($oSource = $oSourceSet->Fetch()) {
             $sTarget = $oSource->Get('scope_class');
             $aSynchroClasses[] = $sTarget;
         }
     }
     foreach ($aSynchroClasses as $sClass) {
         if ($this instanceof $sClass) {
             return true;
         }
     }
     return false;
 }