public function GetRelationQueryData()
 {
     foreach (MetaModel::EnumRelationQueries($this->GetHostClass(), $this->Get('relation_code'), false) as $sDummy => $aQueryInfo) {
         if ($aQueryInfo['sFromClass'] == $this->Get('from_class')) {
             if ($aQueryInfo['sNeighbour'] == $this->Get('neighbour_id')) {
                 return $aQueryInfo;
             }
         }
     }
 }
예제 #2
0
 /**
  * Recursively find related objects, and add them into the graph
  * 
  * @param string $sRelCode The code of the relation to use for the computation
  * @param boolean $bDown The direction: downstream or upstream
  * @param array $oObjectNode The node from which to compute the neighbours
  * @param int $iMaxDepth
  * @param boolean $bEnableReduncancy
  * 
  * @return void
  */
 protected function AddRelatedObjects($sRelCode, $bDown, $oObjectNode, $iMaxDepth, $bEnableRedundancy)
 {
     if ($iMaxDepth > 0) {
         if ($oObjectNode instanceof RelationRedundancyNode) {
             // Note: this happens when recursing on an existing part of the graph
             // Skip that redundancy node
             $aRelatedEdges = $bDown ? $oObjectNode->GetOutgoingEdges() : $oObjectNode->GetIncomingEdges();
             foreach ($aRelatedEdges as $oRelatedEdge) {
                 $oRelatedNode = $bDown ? $oRelatedEdge->GetSinkNode() : $oRelatedEdge->GetSourceNode();
                 // Recurse (same depth)
                 $this->AddRelatedObjects($sRelCode, $bDown, $oRelatedNode, $iMaxDepth, $bEnableRedundancy);
             }
         } elseif ($oObjectNode->GetProperty('developped', false)) {
             // No need to execute the queries again... just dig into the nodes down/up to iMaxDepth
             //
             $aRelatedEdges = $bDown ? $oObjectNode->GetOutgoingEdges() : $oObjectNode->GetIncomingEdges();
             foreach ($aRelatedEdges as $oRelatedEdge) {
                 $oRelatedNode = $bDown ? $oRelatedEdge->GetSinkNode() : $oRelatedEdge->GetSourceNode();
                 // Recurse (decrement the depth)
                 $this->AddRelatedObjects($sRelCode, $bDown, $oRelatedNode, $iMaxDepth - 1, $bEnableRedundancy);
             }
         } else {
             $oObjectNode->SetProperty('developped', true);
             $oObject = $oObjectNode->GetProperty('object');
             foreach (MetaModel::EnumRelationQueries(get_class($oObject), $sRelCode, $bDown) as $sDummy => $aQueryInfo) {
                 $sQuery = $bDown ? $aQueryInfo['sQueryDown'] : $aQueryInfo['sQueryUp'];
                 try {
                     $oFlt = DBObjectSearch::FromOQL($sQuery);
                     $oObjSet = new DBObjectSet($oFlt, array(), $oObject->ToArgsForQuery());
                     $oRelatedObj = $oObjSet->Fetch();
                 } catch (Exception $e) {
                     $sDirection = $bDown ? 'downstream' : 'upstream';
                     throw new Exception("Wrong query ({$sDirection}) for the relation {$sRelCode}/{$aQueryInfo['sDefinedInClass']}/{$aQueryInfo['sNeighbour']}: " . $e->getMessage());
                 }
                 if ($oRelatedObj) {
                     do {
                         $sObjectRef = RelationObjectNode::MakeId($oRelatedObj);
                         $oRelatedNode = $this->GetNode($sObjectRef);
                         if (is_null($oRelatedNode)) {
                             $oRelatedNode = new RelationObjectNode($this, $oRelatedObj);
                         }
                         $oSourceNode = $bDown ? $oObjectNode : $oRelatedNode;
                         $oSinkNode = $bDown ? $oRelatedNode : $oObjectNode;
                         if ($bEnableRedundancy) {
                             $oRedundancyNode = $this->ComputeRedundancy($sRelCode, $aQueryInfo, $oSourceNode, $oSinkNode);
                         } else {
                             $oRedundancyNode = null;
                         }
                         if (!$oRedundancyNode) {
                             // Direct link (otherwise handled by ComputeRedundancy)
                             $oEdge = new RelationEdge($this, $oSourceNode, $oSinkNode);
                         }
                         // Recurse
                         $this->AddRelatedObjects($sRelCode, $bDown, $oRelatedNode, $iMaxDepth - 1, $bEnableRedundancy);
                     } while ($oRelatedObj = $oObjSet->Fetch());
                 }
             }
         }
     }
 }
예제 #3
0
 public function GetRelatedObjects($sRelCode, $iMaxDepth = 99, &$aResults = array())
 {
     foreach (MetaModel::EnumRelationQueries(get_class($this), $sRelCode) as $sDummy => $aQueryInfo) {
         MetaModel::DbgTrace("object=" . $this->GetKey() . ", depth={$iMaxDepth}, rel=" . $aQueryInfo["sQuery"]);
         $sQuery = $aQueryInfo["sQuery"];
         $bPropagate = $aQueryInfo["bPropagate"];
         $iDistance = $aQueryInfo["iDistance"];
         $iDepth = $bPropagate ? $iMaxDepth - 1 : 0;
         $oFlt = DBObjectSearch::FromOQL($sQuery);
         $oObjSet = new DBObjectSet($oFlt, array(), $this->ToArgsForQuery());
         while ($oObj = $oObjSet->Fetch()) {
             $sRootClass = MetaModel::GetRootClass(get_class($oObj));
             $sObjKey = $oObj->GetKey();
             if (array_key_exists($sRootClass, $aResults)) {
                 if (array_key_exists($sObjKey, $aResults[$sRootClass])) {
                     continue;
                     // already visited, skip
                 }
             }
             $aResults[$sRootClass][$sObjKey] = $oObj;
             if ($iDepth > 0) {
                 $oObj->GetRelatedObjects($sRelCode, $iDepth, $aResults);
             }
         }
     }
     return $aResults;
 }
예제 #4
0
/**
 * Display the details of a given relation (e.g. "impacts")
 */
function DisplayRelationDetails($oPage, $sRelCode, $sContext)
{
    $sDesc = MetaModel::GetRelationDescription($sRelCode);
    $sVerbDown = MetaModel::GetRelationVerbDown($sRelCode);
    $sVerbUp = MetaModel::GetRelationVerbUp($sRelCode);
    $oPage->add("<h1>" . Dict::Format('UI:Schema:Relation_Code_Description', $sRelCode, $sDesc) . "</h1>");
    $oPage->p(Dict::Format('UI:Schema:RelationDown_Description', $sVerbDown));
    $oPage->p(Dict::Format('UI:Schema:RelationUp_Description', $sVerbUp));
    $oPage->add("<ul id=\"RelationshipDetails\" class=\"treeview\">\n");
    foreach (MetaModel::GetClasses() as $sClass) {
        $aRelQueries = MetaModel::EnumRelationQueries($sClass, $sRelCode);
        if (count($aRelQueries) > 0) {
            $oPage->add("<li>class " . MakeClassHLink($sClass, $sContext) . "\n");
            $oPage->add("<ul>\n");
            foreach ($aRelQueries as $sRelKey => $aQuery) {
                $sQuery = $aQuery['sQuery'];
                $iDistance = $aQuery['iDistance'];
                if ($aQuery['bPropagate']) {
                    $oPage->add("<li>" . Dict::Format('UI:Schema:RelationPropagates', $sRelKey, $iDistance, $sQuery) . "</li>\n");
                } else {
                    $oPage->add("<li>" . Dict::Format('UI:Schema:RelationDoesNotPropagate', $sRelKey, $iDistance, $sQuery) . "</li>\n");
                }
            }
            $oPage->add("</ul>\n");
            $oPage->add("</li>\n");
        }
    }
    $oPage->add_ready_script('$("#RelationshipDetails").treeview();');
}
예제 #5
0
/**
 * Display the details of a given relation (e.g. "impacts")
 */
function DisplayRelationDetails($oPage, $sRelCode, $sContext)
{
    $sDesc = MetaModel::GetRelationDescription($sRelCode);
    $sLabel = MetaModel::GetRelationLabel($sRelCode);
    $oPage->add("<h1>" . Dict::Format('UI:Schema:Relation_Code_Description', $sRelCode, $sDesc) . "</h1>");
    $oPage->p(Dict::Format('UI:Schema:RelationUp_Description', $sLabel));
    $oPage->add("<ul id=\"RelationshipDetails\" class=\"treeview\">\n");
    foreach (MetaModel::GetClasses() as $sClass) {
        $aRelQueries = MetaModel::EnumRelationQueries($sClass, $sRelCode);
        if (count($aRelQueries) > 0) {
            $oPage->add("<li>class " . MakeClassHLink($sClass, $sContext) . "\n");
            $oPage->add("<ul>\n");
            foreach ($aRelQueries as $sRelKey => $aQuery) {
                $sQueryDown = isset($aQuery['sQueryDown']) ? $aQuery['sQueryDown'] : '';
                $sQueryUp = isset($aQuery['sQueryUp']) ? $aQuery['sQueryUp'] : '';
                $sAttribute = isset($aQuery['sAttribute']) ? $aQuery['sAttribute'] : '';
                /*
                if ($aQuery['bPropagate'])
                {
                	$oPage->add("<li>".Dict::Format('UI:Schema:RelationPropagates', $sRelKey, $iDistance, $sQuery)."</li>\n");
                }
                else
                {
                	$oPage->add("<li>".Dict::Format('UI:Schema:RelationDoesNotPropagate', $sRelKey, $iDistance, $sQuery)."</li>\n");
                }
                */
                $sLabel = strlen($sQueryDown) > 0 ? $sQueryDown : $sAttribute;
                if ($aQuery['_legacy_']) {
                    $sLabel .= ' (<b>Old style specification</b>: it is recommended to upgrade to XML)';
                }
                $oPage->add("<li>" . $sLabel . "</li>\n");
            }
            $oPage->add("</ul>\n");
            $oPage->add("</li>\n");
        }
    }
    $oPage->add_ready_script('$("#RelationshipDetails").treeview();');
}
예제 #6
0
 /**
  * Will be deprecated soon - use GetRelatedObjectsDown/Up instead to take redundancy into account
  */
 public function GetRelatedObjects($sRelCode, $iMaxDepth = 99, &$aResults = array())
 {
     // Temporary patch: until the impact analysis GUI gets rewritten,
     // let's consider that "depends on" is equivalent to "impacts/up"
     // The current patch has been implemented in DBObject and MetaModel
     $sHackedRelCode = $sRelCode;
     $bDown = true;
     if ($sRelCode == 'depends on') {
         $sHackedRelCode = 'impacts';
         $bDown = false;
     }
     foreach (MetaModel::EnumRelationQueries(get_class($this), $sHackedRelCode, $bDown) as $sDummy => $aQueryInfo) {
         $sQuery = $bDown ? $aQueryInfo['sQueryDown'] : $aQueryInfo['sQueryUp'];
         //$bPropagate = $aQueryInfo["bPropagate"];
         //$iDepth = $bPropagate ? $iMaxDepth - 1 : 0;
         $iDepth = $iMaxDepth - 1;
         // Note: the loop over the result set has been written in an unusual way for error reporting purposes
         // In the case of a wrong query parameter name, the error occurs on the first call to Fetch,
         // thus we need to have this first call into the try/catch, but
         // we do NOT want to nest the try/catch for the error message to be clear
         try {
             $oFlt = DBObjectSearch::FromOQL($sQuery);
             $oObjSet = new DBObjectSet($oFlt, array(), $this->ToArgsForQuery());
             $oObj = $oObjSet->Fetch();
         } catch (Exception $e) {
             $sClassOfDefinition = $aQueryInfo['_legacy_'] ? get_class($this) . '(or a parent)::GetRelationQueries()' : $aQueryInfo['sDefinedInClass'];
             throw new Exception("Wrong query for the relation {$sRelCode}/{$sClassOfDefinition}/{$aQueryInfo['sNeighbour']}: " . $e->getMessage());
         }
         if ($oObj) {
             do {
                 $sRootClass = MetaModel::GetRootClass(get_class($oObj));
                 $sObjKey = $oObj->GetKey();
                 if (array_key_exists($sRootClass, $aResults)) {
                     if (array_key_exists($sObjKey, $aResults[$sRootClass])) {
                         continue;
                         // already visited, skip
                     }
                 }
                 $aResults[$sRootClass][$sObjKey] = $oObj;
                 if ($iDepth > 0) {
                     $oObj->GetRelatedObjects($sRelCode, $iDepth, $aResults);
                 }
             } while ($oObj = $oObjSet->Fetch());
         }
     }
     return $aResults;
 }
예제 #7
0
 function test_relations()
 {
     echo "<h4>Test relations</h4>";
     //self::DumpVariable(MetaModel::EnumRelationQueries("cmdbObjectHomeMade", "Potes"));
     self::DumpVariable(MetaModel::EnumRelationQueries("cmdbContact", "Potes"));
     $iMaxDepth = 9;
     echo "Max depth = {$iMaxDepth}</br>\n";
     $oObj = MetaModel::GetObject("cmdbContact", 18);
     $aRels = $oObj->GetRelatedObjects("Potes", $iMaxDepth);
     echo $oObj->Get('name') . " has some 'Potes'...</br>\n";
     foreach ($aRels as $sClass => $aObjs) {
         echo "{$sClass}, count = " . count($aObjs) . " =&gt; " . implode(', ', array_keys($aObjs)) . "</br>\n";
         $oObjectSet = CMDBObjectSet::FromArray($sClass, $aObjs);
         $this->show_list($oObjectSet);
     }
     echo "<h4>Test relations - same results, by the mean of a OQL</h4>";
     $this->search_and_show_list_from_oql("cmdbContact: RELATED (Potes, {$iMaxDepth}) TO (cmdbContact: pkey = 18)");
 }