예제 #1
0
/**
 * Helper to determine the supported types of tickets
 */
function GetTicketClasses()
{
    $aClasses = array();
    foreach (explode(',', MetaModel::GetConfig()->Get('portal_tickets')) as $sRawClass) {
        $sRawClass = trim($sRawClass);
        if (!MetaModel::IsValidClass($sRawClass)) {
            throw new Exception("Class '{$sRawClass}' is not a valid class, please review your configuration (portal_tickets)");
        }
        if (!MetaModel::IsParentClass('Ticket', $sRawClass)) {
            throw new Exception("Class '{$sRawClass}' does not inherit from Ticket, please review your configuration (portal_tickets)");
        }
        $aClasses[] = $sRawClass;
    }
    return $aClasses;
}
 /**
  * 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;
 }
 /**
  * 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;
 }
예제 #4
0
 public function DoCheckToWrite()
 {
     parent::DoCheckToWrite();
     $sFilter = trim($this->Get('filter'));
     if (strlen($sFilter) > 0) {
         try {
             $oSearch = DBObjectSearch::FromOQL($sFilter);
             if (!MetaModel::IsParentClass($this->Get('target_class'), $oSearch->GetClass())) {
                 $this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterClass', $this->Get('target_class'));
             }
         } catch (OqlException $e) {
             $this->m_aCheckIssues[] = Dict::Format('TriggerOnObject:WrongFilterQuery', $e->getMessage());
         }
     }
 }
 /**
  * Read and interpret object search criteria from a Rest/Json structure
  * 	  	 
  * @param string $sClass Name of the class
  * @param StdClass $oCriteria Hash of attribute code => value (can be a substructure or a scalar, depending on the nature of the attriute)
  * @return object The object found
  * @throws Exception If the input structure is not valid or it could not find exactly one object
  */
 protected static function FindObjectFromCriteria($sClass, $oCriteria)
 {
     $aCriteriaReport = array();
     if (isset($oCriteria->finalclass)) {
         if (!MetaModel::IsValidClass($oCriteria->finalclass)) {
             throw new Exception("finalclass: Unknown class '" . $oCriteria->finalclass . "'");
         }
         if (!MetaModel::IsParentClass($sClass, $oCriteria->finalclass)) {
             throw new Exception("finalclass: '" . $oCriteria->finalclass . "' is not a child class of '{$sClass}'");
         }
         $sClass = $oCriteria->finalclass;
     }
     $oSearch = new DBObjectSearch($sClass);
     foreach ($oCriteria as $sAttCode => $value) {
         $realValue = static::MakeValue($sClass, $sAttCode, $value);
         $oSearch->AddCondition($sAttCode, $realValue, '=');
         if (is_object($value) || is_array($value)) {
             $value = json_encode($value);
         }
         $aCriteriaReport[] = "{$sAttCode}: {$value} ({$realValue})";
     }
     $oSet = new DBObjectSet($oSearch);
     $iCount = $oSet->Count();
     if ($iCount == 0) {
         throw new Exception("No item found with criteria: " . implode(', ', $aCriteriaReport));
     } elseif ($iCount > 1) {
         throw new Exception("Several items found ({$iCount}) with criteria: " . implode(', ', $aCriteriaReport));
     }
     $res = $oSet->Fetch();
     return $res;
 }
 protected function MakeSQLObjectQuery(&$oBuild, $aAttToLoad = null, $aValues = array())
 {
     // Note: query class might be different than the class of the filter
     // -> this occurs when we are linking our class to an external class (referenced by, or pointing to)
     $sClass = $this->GetFirstJoinedClass();
     $sClassAlias = $this->GetFirstJoinedClassAlias();
     $bIsOnQueriedClass = array_key_exists($sClassAlias, $oBuild->GetRootFilter()->GetSelectedClasses());
     self::DbgTrace("Entering: " . $this->ToOQL() . ", " . ($bIsOnQueriedClass ? "MAIN" : "SECONDARY"));
     $sRootClass = MetaModel::GetRootClass($sClass);
     $sKeyField = MetaModel::DBGetKey($sClass);
     if ($bIsOnQueriedClass) {
         // default to the whole list of attributes + the very std id/finalclass
         $oBuild->m_oQBExpressions->AddSelect($sClassAlias . 'id', new FieldExpression('id', $sClassAlias));
         if (is_null($aAttToLoad) || !array_key_exists($sClassAlias, $aAttToLoad)) {
             $sSelectedClass = $oBuild->GetSelectedClass($sClassAlias);
             $aAttList = MetaModel::ListAttributeDefs($sSelectedClass);
         } else {
             $aAttList = $aAttToLoad[$sClassAlias];
         }
         foreach ($aAttList as $sAttCode => $oAttDef) {
             if (!$oAttDef->IsScalar()) {
                 continue;
             }
             // keep because it can be used for sorting - if (!$oAttDef->LoadInObject()) continue;
             foreach ($oAttDef->GetSQLExpressions() as $sColId => $sSQLExpr) {
                 $oBuild->m_oQBExpressions->AddSelect($sClassAlias . $sAttCode . $sColId, new FieldExpression($sAttCode . $sColId, $sClassAlias));
             }
         }
         // Transform the full text condition into additional condition expression
         $aFullText = $this->GetCriteria_FullText();
         if (count($aFullText) > 0) {
             $aFullTextFields = array();
             foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
                 if (!$oAttDef->IsScalar()) {
                     continue;
                 }
                 if ($oAttDef->IsExternalKey()) {
                     continue;
                 }
                 $aFullTextFields[] = new FieldExpression($sAttCode, $sClassAlias);
             }
             $oTextFields = new CharConcatWSExpression(' ', $aFullTextFields);
             foreach ($aFullText as $sFTNeedle) {
                 $oNewCond = new BinaryExpression($oTextFields, 'LIKE', new ScalarExpression("%{$sFTNeedle}%"));
                 $oBuild->m_oQBExpressions->AddCondition($oNewCond);
             }
         }
     }
     //echo "<p>oQBExpr ".__LINE__.": <pre>\n".print_r($oBuild->m_oQBExpressions, true)."</pre></p>\n";
     $aExpectedAtts = array();
     // array of (attcode => fieldexpression)
     //echo "<p>".__LINE__.": GetUnresolvedFields($sClassAlias, ...)</p>\n";
     $oBuild->m_oQBExpressions->GetUnresolvedFields($sClassAlias, $aExpectedAtts);
     // Compute a clear view of required joins (from the current class)
     // Build the list of external keys:
     // -> ext keys required by an explicit join
     // -> ext keys mentionned in a 'pointing to' condition
     // -> ext keys required for an external field
     // -> ext keys required for a friendly name
     //
     $aExtKeys = array();
     // array of sTableClass => array of (sAttCode (keys) => array of (sAttCode (fields)=> oAttDef))
     //
     // Optimization: could be partially computed once for all (cached) ?
     //
     if ($bIsOnQueriedClass) {
         // Get all Ext keys for the queried class (??)
         foreach (MetaModel::GetKeysList($sClass) as $sKeyAttCode) {
             $sKeyTableClass = MetaModel::GetAttributeOrigin($sClass, $sKeyAttCode);
             $aExtKeys[$sKeyTableClass][$sKeyAttCode] = array();
         }
     }
     // Get all Ext keys used by the filter
     foreach ($this->GetCriteria_PointingTo() as $sKeyAttCode => $aPointingTo) {
         if (array_key_exists(TREE_OPERATOR_EQUALS, $aPointingTo)) {
             $sKeyTableClass = MetaModel::GetAttributeOrigin($sClass, $sKeyAttCode);
             $aExtKeys[$sKeyTableClass][$sKeyAttCode] = array();
         }
     }
     $aFNJoinAlias = array();
     // array of (subclass => alias)
     if (array_key_exists('friendlyname', $aExpectedAtts)) {
         // To optimize: detect a restriction on child classes in the condition expression
         //    e.g. SELECT FunctionalCI WHERE finalclass IN ('Server', 'VirtualMachine')
         $oNameExpression = self::GetExtendedNameExpression($sClass);
         $aNameFields = array();
         $oNameExpression->GetUnresolvedFields('', $aNameFields);
         $aTranslateNameFields = array();
         foreach ($aNameFields as $sSubClass => $aFields) {
             foreach ($aFields as $sAttCode => $oField) {
                 $oAttDef = MetaModel::GetAttributeDef($sSubClass, $sAttCode);
                 if ($oAttDef->IsExternalKey()) {
                     $sClassOfAttribute = MetaModel::GetAttributeOrigin($sSubClass, $sAttCode);
                     $aExtKeys[$sClassOfAttribute][$sAttCode] = array();
                 } elseif ($oAttDef->IsExternalField() || $oAttDef instanceof AttributeFriendlyName) {
                     $sKeyAttCode = $oAttDef->GetKeyAttCode();
                     $sClassOfAttribute = MetaModel::GetAttributeOrigin($sSubClass, $sKeyAttCode);
                     $aExtKeys[$sClassOfAttribute][$sKeyAttCode][$sAttCode] = $oAttDef;
                 } else {
                     $sClassOfAttribute = MetaModel::GetAttributeOrigin($sSubClass, $sAttCode);
                 }
                 if (MetaModel::IsParentClass($sClassOfAttribute, $sClass)) {
                     // The attribute is part of the standard query
                     //
                     $sAliasForAttribute = $sClassAlias;
                 } else {
                     // The attribute will be available from an additional outer join
                     // For each subclass (table) one single join is enough
                     //
                     if (!array_key_exists($sClassOfAttribute, $aFNJoinAlias)) {
                         $sAliasForAttribute = $oBuild->GenerateClassAlias($sClassAlias . '_fn_' . $sClassOfAttribute, $sClassOfAttribute);
                         $aFNJoinAlias[$sClassOfAttribute] = $sAliasForAttribute;
                     } else {
                         $sAliasForAttribute = $aFNJoinAlias[$sClassOfAttribute];
                     }
                 }
                 $aTranslateNameFields[$sSubClass][$sAttCode] = new FieldExpression($sAttCode, $sAliasForAttribute);
             }
         }
         $oNameExpression = $oNameExpression->Translate($aTranslateNameFields, false);
         $aTranslateNow = array();
         $aTranslateNow[$sClassAlias]['friendlyname'] = $oNameExpression;
         $oBuild->m_oQBExpressions->Translate($aTranslateNow, false);
     }
     // Add the ext fields used in the select (eventually adds an external key)
     foreach (MetaModel::ListAttributeDefs($sClass) as $sAttCode => $oAttDef) {
         if ($oAttDef->IsExternalField() || $oAttDef instanceof AttributeFriendlyName) {
             if (array_key_exists($sAttCode, $aExpectedAtts)) {
                 $sKeyAttCode = $oAttDef->GetKeyAttCode();
                 if ($sKeyAttCode != 'id') {
                     // Add the external attribute
                     $sKeyTableClass = MetaModel::GetAttributeOrigin($sClass, $sKeyAttCode);
                     $aExtKeys[$sKeyTableClass][$sKeyAttCode][$sAttCode] = $oAttDef;
                 }
             }
         }
     }
     // First query built upon on the leaf (ie current) class
     //
     self::DbgTrace("Main (=leaf) class, call MakeSQLObjectQuerySingleTable()");
     if (MetaModel::HasTable($sClass)) {
         $oSelectBase = $this->MakeSQLObjectQuerySingleTable($oBuild, $aAttToLoad, $sClass, $aExtKeys, $aValues);
     } else {
         $oSelectBase = null;
         // As the join will not filter on the expected classes, we have to specify it explicitely
         $sExpectedClasses = implode("', '", MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL));
         $oFinalClassRestriction = Expression::FromOQL("`{$sClassAlias}`.finalclass IN ('{$sExpectedClasses}')");
         $oBuild->m_oQBExpressions->AddCondition($oFinalClassRestriction);
     }
     // Then we join the queries of the eventual parent classes (compound model)
     foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass) {
         if (!MetaModel::HasTable($sParentClass)) {
             continue;
         }
         self::DbgTrace("Parent class: {$sParentClass}... let's call MakeSQLObjectQuerySingleTable()");
         $oSelectParentTable = $this->MakeSQLObjectQuerySingleTable($oBuild, $aAttToLoad, $sParentClass, $aExtKeys, $aValues);
         if (is_null($oSelectBase)) {
             $oSelectBase = $oSelectParentTable;
         } else {
             $oSelectBase->AddInnerJoin($oSelectParentTable, $sKeyField, MetaModel::DBGetKey($sParentClass));
         }
     }
     // Filter on objects referencing me
     foreach ($this->GetCriteria_ReferencedBy() as $sForeignClass => $aKeysAndFilters) {
         foreach ($aKeysAndFilters as $sForeignKeyAttCode => $oForeignFilter) {
             $oForeignKeyAttDef = MetaModel::GetAttributeDef($sForeignClass, $sForeignKeyAttCode);
             self::DbgTrace("Referenced by foreign key: {$sForeignKeyAttCode}... let's call MakeSQLObjectQuery()");
             //self::DbgTrace($oForeignFilter);
             //self::DbgTrace($oForeignFilter->ToOQL());
             //self::DbgTrace($oSelectForeign);
             //self::DbgTrace($oSelectForeign->RenderSelect(array()));
             $sForeignClassAlias = $oForeignFilter->GetFirstJoinedClassAlias();
             $oBuild->m_oQBExpressions->PushJoinField(new FieldExpression($sForeignKeyAttCode, $sForeignClassAlias));
             if ($oForeignKeyAttDef instanceof AttributeObjectKey) {
                 $sClassAttCode = $oForeignKeyAttDef->Get('class_attcode');
                 // Add the condition: `$sForeignClassAlias`.$sClassAttCode IN (subclasses of $sClass')
                 $oClassListExpr = ListExpression::FromScalars(MetaModel::EnumChildClasses($sClass, ENUM_CHILD_CLASSES_ALL));
                 $oClassExpr = new FieldExpression($sClassAttCode, $sForeignClassAlias);
                 $oClassRestriction = new BinaryExpression($oClassExpr, 'IN', $oClassListExpr);
                 $oBuild->m_oQBExpressions->AddCondition($oClassRestriction);
             }
             $oSelectForeign = $oForeignFilter->MakeSQLObjectQuery($oBuild, $aAttToLoad);
             $oJoinExpr = $oBuild->m_oQBExpressions->PopJoinField();
             $sForeignKeyTable = $oJoinExpr->GetParent();
             $sForeignKeyColumn = $oJoinExpr->GetName();
             $oSelectBase->AddInnerJoin($oSelectForeign, $sKeyField, $sForeignKeyColumn, $sForeignKeyTable);
         }
     }
     // Additional JOINS for Friendly names
     //
     foreach ($aFNJoinAlias as $sSubClass => $sSubClassAlias) {
         $oSubClassFilter = new DBObjectSearch($sSubClass, $sSubClassAlias);
         $oSelectFN = $oSubClassFilter->MakeSQLObjectQuerySingleTable($oBuild, $aAttToLoad, $sSubClass, $aExtKeys, array());
         $oSelectBase->AddLeftJoin($oSelectFN, $sKeyField, MetaModel::DBGetKey($sSubClass));
     }
     // That's all... cross fingers and we'll get some working query
     //MyHelpers::var_dump_html($oSelectBase, true);
     //MyHelpers::var_dump_html($oSelectBase->RenderSelect(), true);
     if (self::$m_bDebugQuery) {
         $oSelectBase->DisplayHtml();
     }
     return $oSelectBase;
 }
 protected function LoadValues($aArgs)
 {
     $this->m_aValues = array();
     if (!array_key_exists('this', $aArgs)) {
         throw new CoreException("Missing 'this' in arguments", array('args' => $aArgs));
     }
     $oTarget = $aArgs['this->object()'];
     // Nodes from which we will start the search for neighbourhood
     $oNodes = DBObjectSet::FromLinkSet($oTarget, $this->m_sLinkSetAttCode, $this->m_sExtKeyToRemote);
     // Neighbours, whatever their class
     $aRelated = $oNodes->GetRelatedObjects($this->m_sRelationCode, $this->m_iMaxDepth);
     $sRootClass = MetaModel::GetRootClass($this->m_sTargetClass);
     if (array_key_exists($sRootClass, $aRelated)) {
         $aLinksToCreate = array();
         foreach ($aRelated[$sRootClass] as $iKey => $oObject) {
             if (MetaModel::IsParentClass($this->m_sTargetClass, get_class($oObject))) {
                 $oNewLink = MetaModel::NewObject($this->m_sTargetLinkClass);
                 $oNewLink->Set($this->m_sTargetExtKey, $iKey);
                 //$oNewLink->Set('role', 'concerned by an impacted CI');
                 $aLinksToCreate[] = $oNewLink;
             }
         }
         // #@# or AddObjectArray($aObjects) ?
         $oSetToCreate = DBObjectSet::FromArray($this->m_sTargetLinkClass, $aLinksToCreate);
         $this->m_aValues[$oObject->GetKey()] = $oObject->GetName();
     }
     return true;
 }
예제 #8
0
 /**
  * Lifecycle action: Set the current logged in CONTACT for the given attribute
  */
 public function SetCurrentPerson($sAttCode)
 {
     $oAttDef = MetaModel::GetAttributeDef(get_class($this), $sAttCode);
     if ($oAttDef instanceof AttributeString) {
         $iPerson = UserRights::GetContactId();
         if ($iPerson == 0) {
             $this->Set($sAttCode, '');
         } else {
             $oPerson = MetaModel::GetObject('Person', $iPerson);
             $this->Set($sAttCode, $oPerson->Get('friendlyname'));
         }
     } else {
         if ($oAttDef->IsExternalKey()) {
             if (!MetaModel::IsParentClass($oAttDef->GetTargetClass(), 'Person')) {
                 throw new Exception("SetCurrentContact: the attribute {$sAttCode} must be an external key to 'Person' or any other class above 'Person', found '" . $oAttDef->GetTargetClass() . "'");
             }
         }
         $this->Set($sAttCode, UserRights::GetContactId());
     }
     return true;
 }
 /**
  * Change the class (only subclasses are supported as of now, because the conditions must fit the new class)
  * Defaults to the first selected class (most of the time it is also the first joined class	 
  */
 public function ChangeClass($sNewClass, $sAlias = null)
 {
     if (is_null($sAlias)) {
         $sAlias = $this->GetClassAlias();
     } else {
         if (!array_key_exists($sAlias, $this->m_aClasses)) {
             // discard silently - necessary when recursing on the related nodes (see code below)
             return;
         }
     }
     $sCurrClass = $this->GetClassName($sAlias);
     if (!MetaModel::IsParentClass($sCurrClass, $sNewClass)) {
         throw new Exception("Could not change the search class from '{$sCurrClass}' to '{$sNewClass}'. Only child classes are permitted.");
     }
     // Change for this node
     //
     $this->m_aSelectedClasses[$sAlias] = $sNewClass;
     $this->m_aClasses[$sAlias] = $sNewClass;
     // Change for all the related node (yes, this was necessary with some queries - strange effects otherwise)
     //
     foreach ($this->m_aRelatedTo as $aRelatedTo) {
         $aRelatedTo['flt']->ChangeClass($sNewClass, $sAlias);
     }
     foreach ($this->m_aPointingTo as $sExtKeyAttCode => $aPointingTo) {
         foreach ($aPointingTo as $iOperatorCode => $aFilter) {
             foreach ($aFilter as $oExtFilter) {
                 $oExtFilter->ChangeClass($sNewClass, $sAlias);
             }
         }
     }
     foreach ($this->m_aReferencedBy as $sForeignClass => $aReferences) {
         foreach ($aReferences as $sForeignExtKeyAttCode => $oForeignFilter) {
             $oForeignFilter->ChangeClass($sNewClass, $sAlias);
         }
     }
 }