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;
     }
 }
Exemplo n.º 2
0
 /**
  * Retrieve the DBSearch corresponding to the objects present in this set
  * 
  * Limitation:
  * This method will NOT work for sets with several columns (i.e. several objects per row)
  * 
  * @return DBObjectSearch
  */
 public function GetFilter()
 {
     // Make sure that we carry on the parameters of the set with the filter
     $oFilter = $this->m_oFilter->DeepClone();
     // Note: the arguments found within a set can be object (but not in a filter)
     // That's why PrepareQueryArguments must be invoked there
     $oFilter->SetInternalParams(array_merge($oFilter->GetInternalParams(), MetaModel::PrepareQueryArguments($this->m_aArgs)));
     if (count($this->m_aAddedIds) == 0) {
         return $oFilter;
     } else {
         $oIdListExpr = ListExpression::FromScalars(array_keys($this->m_aAddedIds));
         $oIdExpr = new FieldExpression('id', $oFilter->GetClassAlias());
         $oIdInList = new BinaryExpression($oIdExpr, 'IN', $oIdListExpr);
         $oFilter->MergeConditionExpression($oIdInList);
         return $oFilter;
     }
 }
 /**
  *	...
  */
 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;
 }
 /**
  *	Get the friendly name for the class and its subclasses (if finalclass = 'subclass' ...)
  *	Simplifies the final expression by grouping classes having the same name expression	 
  *	Used when querying a parent class 	 
  */
 protected static function GetExtendedNameExpression($sClass)
 {
     // 1st step - get all of the required expressions (instantiable classes)
     //            and group them using their OQL representation
     //
     $aFNExpressions = array();
     // signature => array('expression' => oExp, 'classes' => array of classes)
     foreach (MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL) as $sSubClass) {
         if ($sSubClass != $sClass && MetaModel::IsAbstract($sSubClass)) {
             continue;
         }
         $oSubClassName = MetaModel::GetNameExpression($sSubClass);
         $sSignature = $oSubClassName->Render();
         if (!array_key_exists($sSignature, $aFNExpressions)) {
             $aFNExpressions[$sSignature] = array('expression' => $oSubClassName, 'classes' => array());
         }
         $aFNExpressions[$sSignature]['classes'][] = $sSubClass;
     }
     // 2nd step - build the final name expression depending on the finalclass
     //
     if (count($aFNExpressions) == 1) {
         $aExpData = reset($aFNExpressions);
         $oNameExpression = $aExpData['expression'];
     } else {
         $oNameExpression = null;
         foreach ($aFNExpressions as $sSignature => $aExpData) {
             $oClassListExpr = ListExpression::FromScalars($aExpData['classes']);
             $oClassExpr = new FieldExpression('finalclass', $sClass);
             $oClassInList = new BinaryExpression($oClassExpr, 'IN', $oClassListExpr);
             if (is_null($oNameExpression)) {
                 $oNameExpression = $aExpData['expression'];
             } else {
                 $oNameExpression = new FunctionExpression('IF', array($oClassInList, $aExpData['expression'], $oNameExpression));
             }
         }
     }
     return $oNameExpression;
 }
 /**
  * Specify a condition on external keys or link sets
  * @param sAttSpec Can be either an attribute code or extkey->[sAttSpec] or linkset->[sAttSpec] and so on, recursively
  *                 Example: infra_list->ci_id->location_id->country	 
  * @param value The value to match (can be an array => IN(val1, val2...)
  * @return void
  */
 public function AddConditionAdvanced($sAttSpec, $value)
 {
     $sClass = $this->GetClass();
     $iPos = strpos($sAttSpec, '->');
     if ($iPos !== false) {
         $sAttCode = substr($sAttSpec, 0, $iPos);
         $sSubSpec = substr($sAttSpec, $iPos + 2);
         if (!MetaModel::IsValidAttCode($sClass, $sAttCode)) {
             throw new Exception("Invalid attribute code '{$sClass}/{$sAttCode}' in condition specification '{$sAttSpec}'");
         }
         $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
         if ($oAttDef->IsLinkSet()) {
             $sTargetClass = $oAttDef->GetLinkedClass();
             $sExtKeyToMe = $oAttDef->GetExtKeyToMe();
             $oNewFilter = new DBObjectSearch($sTargetClass);
             $oNewFilter->AddConditionAdvanced($sSubSpec, $value);
             $this->AddCondition_ReferencedBy($oNewFilter, $sExtKeyToMe);
         } elseif ($oAttDef->IsExternalKey(EXTKEY_ABSOLUTE)) {
             $sTargetClass = $oAttDef->GetTargetClass(EXTKEY_ABSOLUTE);
             $oNewFilter = new DBObjectSearch($sTargetClass);
             $oNewFilter->AddConditionAdvanced($sSubSpec, $value);
             $this->AddCondition_PointingTo($oNewFilter, $sAttCode);
         } else {
             throw new Exception("Attribute specification '{$sAttSpec}', '{$sAttCode}' should be either a link set or an external key");
         }
     } else {
         // $sAttSpec is an attribute code
         //
         if (is_array($value)) {
             $oField = new FieldExpression($sAttSpec, $this->GetClass());
             $oListExpr = ListExpression::FromScalars($value);
             $oInValues = new BinaryExpression($oField, 'IN', $oListExpr);
             $this->AddConditionExpression($oInValues);
         } else {
             $this->AddCondition($sAttSpec, $value);
         }
     }
 }