/**
  * Add a condition (restriction) to the current DBSearch on which the display block is based
  * taking into account the hierarchical keys for which the condition is based on the 'below' operator
  */
 protected function AddCondition($sFilterCode, $condition, $sOpCode = null)
 {
     // Workaround to an issue revealed whenever a condition on org_id is applied twice (with a hierarchy of organizations)
     // Moreover, it keeps the query as simple as possible
     if (isset($this->m_aConditions[$sFilterCode]) && $condition == $this->m_aConditions[$sFilterCode]) {
         // Skip
         return;
     }
     $this->m_aConditions[$sFilterCode] = $condition;
     $sClass = $this->m_oFilter->GetClass();
     $bConditionAdded = false;
     // If the condition is an external key with a class having a hierarchy, use a "below" criteria
     if (MetaModel::IsValidAttCode($sClass, $sFilterCode)) {
         $oAttDef = MetaModel::GetAttributeDef($sClass, $sFilterCode);
         if ($oAttDef->IsExternalKey()) {
             $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass($oAttDef->GetTargetClass());
             if ($sHierarchicalKeyCode !== false) {
                 $oFilter = new DBObjectSearch($oAttDef->GetTargetClass());
                 if ($sOpCode == 'IN' && is_array($condition)) {
                     $oFilter->AddConditionExpression(self::GetConditionIN($oFilter, 'id', $condition));
                 } else {
                     $oFilter->AddCondition('id', $condition);
                 }
                 $oHKFilter = new DBObjectSearch($oAttDef->GetTargetClass());
                 $oHKFilter->AddCondition_PointingTo($oFilter, $sHierarchicalKeyCode, TREE_OPERATOR_BELOW);
                 // Use the 'below' operator by default
                 $this->m_oFilter->AddCondition_PointingTo($oHKFilter, $sFilterCode);
                 $bConditionAdded = true;
             } else {
                 if ($sOpCode == 'IN' && is_array($condition)) {
                     $this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
                     $bConditionAdded = true;
                 }
             }
         } else {
             if ($sOpCode == 'IN' && is_array($condition)) {
                 $this->m_oFilter->AddConditionExpression(self::GetConditionIN($this->m_oFilter, $sFilterCode, $condition));
                 $bConditionAdded = true;
             }
         }
     }
     // In all other cases, just add the condition directly
     if (!$bConditionAdded) {
         $this->m_oFilter->AddCondition($sFilterCode, $condition);
         // Use the default 'loose' operator
     }
 }
 /**
  * Describe (as a text string) the modifications corresponding to this change
  */
 public function GetDescription()
 {
     $sResult = '';
     $oTargetObjectClass = $this->Get('objclass');
     $oTargetObjectKey = $this->Get('objkey');
     $oTargetSearch = new DBObjectSearch($oTargetObjectClass);
     $oTargetSearch->AddCondition('id', $oTargetObjectKey, '=');
     $oMonoObjectSet = new DBObjectSet($oTargetSearch);
     if (UserRights::IsActionAllowedOnAttribute($this->Get('objclass'), $this->Get('attcode'), UR_ACTION_READ, $oMonoObjectSet) == UR_ALLOWED_YES) {
         if (!MetaModel::IsValidAttCode($this->Get('objclass'), $this->Get('attcode'))) {
             return '';
         }
         // Protects against renamed attributes...
         $oAttDef = MetaModel::GetAttributeDef($this->Get('objclass'), $this->Get('attcode'));
         $sAttName = $oAttDef->GetLabel();
         $sLinkClass = $oAttDef->GetLinkedClass();
         $aLinkClasses = MetaModel::EnumChildClasses($sLinkClass, ENUM_CHILD_CLASSES_ALL);
         // Search for changes on the corresponding link
         //
         $oSearch = new DBObjectSearch('CMDBChangeOpSetAttribute');
         $oSearch->AddCondition('change', $this->Get('change'), '=');
         $oSearch->AddCondition('objkey', $this->Get('link_id'), '=');
         if (count($aLinkClasses) == 1) {
             // Faster than the whole building of the expression below for just one value ??
             $oSearch->AddCondition('objclass', $sLinkClass, '=');
         } else {
             $oField = new FieldExpression('objclass', $oSearch->GetClassAlias());
             $sListExpr = '(' . implode(', ', CMDBSource::Quote($aLinkClasses)) . ')';
             $sOQLCondition = $oField->Render() . " IN {$sListExpr}";
             $oNewCondition = Expression::FromOQL($sOQLCondition);
             $oSearch->AddConditionExpression($oNewCondition);
         }
         $oSet = new DBObjectSet($oSearch);
         $aChanges = array();
         while ($oChangeOp = $oSet->Fetch()) {
             $aChanges[] = $oChangeOp->GetDescription();
         }
         if (count($aChanges) == 0) {
             return '';
         }
         $sItemDesc = MetaModel::GetHyperLink($this->Get('item_class'), $this->Get('item_id'));
         $sResult = $sAttName . ' - ';
         $sResult .= Dict::Format('Change:LinkSet:Modified', $sItemDesc);
         $sResult .= ' : ' . implode(', ', $aChanges);
     }
     return $sResult;
 }
 public function GetSelectFilter($oUser, $sClass, $aSettings = array())
 {
     $aConditions = array();
     foreach ($this->m_aDimensions as $iDimension => $oDimension) {
         $oClassProj = @$this->m_aClassProjs[$sClass][$iDimension];
         if (is_null($oClassProj)) {
             // Authorize any for this dimension, then no additional criteria is required
             continue;
         }
         // 1 - Get class projection info
         //
         $oExpression = null;
         $sExpr = $oClassProj->Get('value');
         if ($sExpr == '<this>') {
             $sColumn = $oClassProj->Get('attribute');
             if (empty($sColumn)) {
                 $oExpression = new FieldExpression('id', $sClass);
             } else {
                 $oExpression = new FieldExpression($sColumn, $sClass);
             }
         } elseif ($sExpr == '<any>' || $sExpr == '') {
             // Authorize any for this dimension, then no additional criteria is required
             continue;
         } elseif (strtolower(substr($sExpr, 0, 6)) == 'select') {
             throw new CoreException('Sorry, projections by the mean of OQL are not supported currently, please specify an attribute instead', array('class' => $sClass, 'expression' => $sExpr));
         } else {
             // Constant value(s)
             // unsupported
             throw new CoreException('Sorry, constant projections are not supported currently, please specify an attribute instead', array('class' => $sClass, 'expression' => $sExpr));
             //				$aRes = explode(';', trim($sExpr));
         }
         // 2 - Get profile projection info and use it if needed
         //
         $aProjections = self::GetReadableProjectionsByDim($oUser, $sClass, $oDimension);
         if (is_null($aProjections)) {
             // Authorize any for this dimension, then no additional criteria is required
             continue;
         } elseif (count($aProjections) == 0) {
             // Authorize none, then exit as quickly as possible
             return false;
         } else {
             // Authorize the given set of values
             $oListExpr = ListExpression::FromScalars($aProjections);
             $oCondition = new BinaryExpression($oExpression, 'IN', $oListExpr);
             $aConditions[] = $oCondition;
         }
     }
     if (count($aConditions) == 0) {
         // allow all
         return true;
     } else {
         $oFilter = new DBObjectSearch($sClass);
         foreach ($aConditions as $oCondition) {
             $oFilter->AddConditionExpression($oCondition);
         }
         //return true;
         return $oFilter;
     }
 }
Example #4
0
 /**
  * Create an empty set (in-memory), for the given class (and its subclasses) of objects
  * 
  * @param string $sClass The class (or an ancestor) for the objects to be added in this set
  * 
  * @return DBObject The empty set
  */
 public static function FromScratch($sClass)
 {
     $oFilter = new DBObjectSearch($sClass);
     $oFilter->AddConditionExpression(new FalseExpression());
     $oRetSet = new self($oFilter);
     $oRetSet->m_bLoaded = true;
     // no DB load
     $oRetSet->m_iNumTotalDBRows = 0;
     // Nothing from the DB
     return $oRetSet;
 }
 /**
  * Read and cache profiles of the given user
  */
 protected function GetUserProfiles($iUser)
 {
     if (!array_key_exists($iUser, $this->m_aUserProfiles)) {
         $oSearch = new DBObjectSearch('URP_UserProfile');
         $oSearch->AllowAllData();
         $oCondition = new BinaryExpression(new FieldExpression('userid'), '=', new VariableExpression('userid'));
         $oSearch->AddConditionExpression($oCondition);
         $this->m_aUserProfiles[$iUser] = array();
         $oUserProfileSet = new DBObjectSet($oSearch, array(), array('userid' => $iUser));
         while ($oUserProfile = $oUserProfileSet->Fetch()) {
             $this->m_aUserProfiles[$iUser][$oUserProfile->Get('profileid')] = $oUserProfile;
         }
     }
     return $this->m_aUserProfiles[$iUser];
 }
 public static function FromScratch($sClass)
 {
     $oFilter = new DBObjectSearch($sClass);
     $oFilter->AddConditionExpression(new FalseExpression());
     $oRetSet = new self($oFilter);
     // NOTE: THIS DOES NOT WORK IF m_bLoaded is private in the base class (and you will not get any error message)
     $oRetSet->m_bLoaded = true;
     // no DB load
     return $oRetSet;
 }
 /**
  *	...
  */
 public function MakeSelectFilter($sClass, $aAllowedOrgs, $aSettings = array(), $sAttCode = null)
 {
     if ($sAttCode == null) {
         $sAttCode = $this->GetOwnerOrganizationAttCode($sClass);
     }
     if (empty($sAttCode)) {
         return $oFilter = new DBObjectSearch($sClass);
     }
     $oExpression = new FieldExpression($sAttCode, $sClass);
     $oFilter = new DBObjectSearch($sClass);
     $oListExpr = ListExpression::FromScalars($aAllowedOrgs);
     $oCondition = new BinaryExpression($oExpression, 'IN', $oListExpr);
     $oFilter->AddConditionExpression($oCondition);
     if ($this->HasSharing()) {
         if ($sAttCode == 'id' && isset($aSettings['bSearchMode']) && $aSettings['bSearchMode']) {
             // Querying organizations (or derived)
             // and the expected list of organizations will be used as a search criteria
             // Therefore the query can also return organization having objects shared with the allowed organizations
             //
             // 1) build the list of organizations sharing something with the allowed organizations
             // Organization <== sharing_org_id == SharedObject having org_id IN {user orgs}
             $oShareSearch = new DBObjectSearch('SharedObject');
             $oOrgField = new FieldExpression('org_id', 'SharedObject');
             $oShareSearch->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr));
             $oSearchSharers = new DBObjectSearch('Organization');
             $oSearchSharers->AllowAllData();
             $oSearchSharers->AddCondition_ReferencedBy($oShareSearch, 'sharing_org_id');
             $aSharers = array();
             foreach ($oSearchSharers->ToDataArray(array('id')) as $aRow) {
                 $aSharers[] = $aRow['id'];
             }
             // 2) Enlarge the overall results: ... OR id IN(id1, id2, id3)
             if (count($aSharers) > 0) {
                 $oSharersList = ListExpression::FromScalars($aSharers);
                 $oFilter->MergeConditionExpression(new BinaryExpression($oExpression, 'IN', $oSharersList));
             }
         }
         $aShareProperties = SharedObject::GetSharedClassProperties($sClass);
         if ($aShareProperties) {
             $sShareClass = $aShareProperties['share_class'];
             $sShareAttCode = $aShareProperties['attcode'];
             $oSearchShares = new DBObjectSearch($sShareClass);
             $oSearchShares->AllowAllData();
             $sHierarchicalKeyCode = MetaModel::IsHierarchicalClass('Organization');
             $oOrgField = new FieldExpression('org_id', $sShareClass);
             $oSearchShares->AddConditionExpression(new BinaryExpression($oOrgField, 'IN', $oListExpr));
             $aShared = array();
             foreach ($oSearchShares->ToDataArray(array($sShareAttCode)) as $aRow) {
                 $aShared[] = $aRow[$sShareAttCode];
             }
             if (count($aShared) > 0) {
                 $oObjId = new FieldExpression('id', $sClass);
                 $oSharedIdList = ListExpression::FromScalars($aShared);
                 $oFilter->MergeConditionExpression(new BinaryExpression($oObjId, 'IN', $oSharedIdList));
             }
         }
     }
     // if HasSharing
     return $oFilter;
 }