diff --git a/core/metamodel.class.php b/core/metamodel.class.php index e99c9bdc5..f502b2359 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -1183,11 +1183,11 @@ abstract class MetaModel { if ($bDown) { - // The legacy convention is confusing with regard to the way we have conceptualized the relations: - // In the former representation, the main stream was named after "up" - // Now, the relation from A to B says that something is transmitted from A to B, thus going DOWNstream as described in a petri net. - $sKey = "Relation:$sRelCode/DownStream"; - $sLegacy = Dict::S("Relation:$sRelCode/VerbUp", $sKey); + // The legacy convention is confusing with regard to the way we have conceptualized the relations: + // In the former representation, the main stream was named after "up" + // Now, the relation from A to B says that something is transmitted from A to B, thus going DOWNstream as described in a petri net. + $sKey = "Relation:$sRelCode/DownStream"; + $sLegacy = Dict::S("Relation:$sRelCode/VerbUp", $sKey); } else { @@ -1265,17 +1265,25 @@ abstract class MetaModel throw new Exception("Wrong definition for the relation $sRelCode/{$aNeighbourData['sDefinedInClass']}/{$aNeighbourData['sNeighbour']}: ".$e->getMessage()); } + if ($aNeighbourData['sDirection'] == 'down') + { + $aNeighbourData['sQueryUp'] = null; + } + $sArrowId = $aNeighbourData['sDefinedInClass'].'_'.$sNeighbourId; $aQueries[$sClass]['down'][$sArrowId] = $aNeighbourData; // Compute the reverse index if ($aNeighbourData['sDefinedInClass'] == $sClass) { - $sFromClass = $aNeighbourData['sFromClass']; - $sToClass = $aNeighbourData['sToClass']; - foreach (self::EnumChildClasses($sToClass, ENUM_CHILD_CLASSES_ALL) as $sSubClass) + if ($aNeighbourData['sDirection'] == 'both') { - $aQueries[$sSubClass]['up'][$sArrowId] = $aNeighbourData; + $sFromClass = $aNeighbourData['sFromClass']; + $sToClass = $aNeighbourData['sToClass']; + foreach (self::EnumChildClasses($sToClass, ENUM_CHILD_CLASSES_ALL) as $sSubClass) + { + $aQueries[$sSubClass]['up'][$sArrowId] = $aNeighbourData; + } } } } @@ -1320,7 +1328,9 @@ abstract class MetaModel 'sDefinedInClass' => $sClass, 'sFromClass' => $sClass, 'sToClass' => $sRemoteClass, + 'sDirection' => 'down', 'sQueryDown' => $aLegacyEntry['sQuery'], + 'sQueryUp' => null, 'sNeighbour' => $sRemoteClass // Normalize the neighbour id ); } @@ -1354,6 +1364,8 @@ abstract class MetaModel 'sDefinedInClass' => $sRemoteClass, 'sFromClass' => $sRemoteClass, 'sToClass' => $sClass, + 'sDirection' => 'both', + 'sQueryDown' => null, 'sQueryUp' => $aLegacyEntry['sQuery'], 'sNeighbour' => $sClass// Normalize the neighbour id ); @@ -1388,6 +1400,7 @@ abstract class MetaModel if (isset($aQueries[$sRemoteClass]['down'][$sLocalClass])) { $aQueries[$sRemoteClass]['down'][$sLocalClass]['sQueryUp'] = $aNeighbourData['sQueryUp']; + $aQueries[$sRemoteClass]['down'][$sLocalClass]['sDirection'] = 'both'; } else { @@ -1396,7 +1409,7 @@ abstract class MetaModel } } } - // Foreach "down" legacy query, update its "up" counterpart + // Foreach "down" legacy query, update its "up" counterpart (if any) foreach ($aQueries[$sClass]['down'] as $sNeighbourId => $aNeighbourData) { if (!$aNeighbourData['_legacy_']) continue; // Skip modern definitions @@ -1404,7 +1417,10 @@ abstract class MetaModel $sLocalClass = $aNeighbourData['sFromClass']; foreach (self::EnumChildClasses($aNeighbourData['sToClass'], ENUM_CHILD_CLASSES_ALL) as $sRemoteClass) { - //$aQueries[$sRemoteClass]['up'][$sLocalClass]['sQueryDown'] = $aNeighbourData['sQueryDown']; + if (isset($aQueries[$sRemoteClass]['up'][$sLocalClass])) + { + $aQueries[$sRemoteClass]['up'][$sLocalClass]['sQueryDown'] = $aNeighbourData['sQueryDown']; + } } } } diff --git a/datamodels/2.x/itop-config-mgmt/datamodel.itop-config-mgmt.xml b/datamodels/2.x/itop-config-mgmt/datamodel.itop-config-mgmt.xml index 0b882122a..4c0d9369a 100755 --- a/datamodels/2.x/itop-config-mgmt/datamodel.itop-config-mgmt.xml +++ b/datamodels/2.x/itop-config-mgmt/datamodel.itop-config-mgmt.xml @@ -1380,7 +1380,6 @@ -
@@ -1469,6 +1468,7 @@ contacts_list + down applicationsolution_list @@ -1743,7 +1743,6 @@ 0 -
@@ -2208,7 +2207,6 @@ true -
@@ -2522,7 +2520,6 @@ -
@@ -2835,7 +2832,6 @@ count -
@@ -2976,7 +2972,6 @@ list -
@@ -3138,7 +3133,6 @@ list -
@@ -3268,7 +3262,6 @@ 0 -
@@ -3416,7 +3409,6 @@ 0 -
@@ -3564,7 +3556,6 @@ 0 -
@@ -3946,7 +3937,6 @@ name -
@@ -4067,7 +4057,6 @@ name -
@@ -4194,7 +4183,6 @@ _blank -
diff --git a/datamodels/2.x/itop-datacenter-mgmt/datamodel.itop-datacenter-mgmt.xml b/datamodels/2.x/itop-datacenter-mgmt/datamodel.itop-datacenter-mgmt.xml index ec09b409c..740f9d146 100755 --- a/datamodels/2.x/itop-datacenter-mgmt/datamodel.itop-datacenter-mgmt.xml +++ b/datamodels/2.x/itop-datacenter-mgmt/datamodel.itop-datacenter-mgmt.xml @@ -231,7 +231,18 @@ 0 - + + + /** + * Placeholder for backward compatibility (iTop <= 2.1.0) + * in case an extension attempts to redefine this function... + */ + true + public + Overload-DBObject + + +
@@ -401,7 +412,18 @@ - + + + /** + * Placeholder for backward compatibility (iTop <= 2.1.0) + * in case an extension attempts to redefine this function... + */ + true + public + Overload-DBObject + + +
@@ -762,7 +784,6 @@ name -
diff --git a/datamodels/2.x/itop-storage-mgmt/datamodel.itop-storage-mgmt.xml b/datamodels/2.x/itop-storage-mgmt/datamodel.itop-storage-mgmt.xml index 03b9ac991..988eaa9c5 100644 --- a/datamodels/2.x/itop-storage-mgmt/datamodel.itop-storage-mgmt.xml +++ b/datamodels/2.x/itop-storage-mgmt/datamodel.itop-storage-mgmt.xml @@ -34,7 +34,6 @@ 0 -
@@ -299,7 +298,6 @@ -
@@ -560,7 +558,6 @@ 0 -
@@ -821,7 +818,6 @@ 0 -
@@ -1099,7 +1095,6 @@ name -
@@ -1206,7 +1201,6 @@ name -
@@ -1452,7 +1446,6 @@ -
diff --git a/datamodels/2.x/itop-virtualization-mgmt/datamodel.itop-virtualization-mgmt.xml b/datamodels/2.x/itop-virtualization-mgmt/datamodel.itop-virtualization-mgmt.xml index 14f9c79e5..44f237708 100644 --- a/datamodels/2.x/itop-virtualization-mgmt/datamodel.itop-virtualization-mgmt.xml +++ b/datamodels/2.x/itop-virtualization-mgmt/datamodel.itop-virtualization-mgmt.xml @@ -157,7 +157,6 @@ 0 -
@@ -300,7 +299,6 @@ name -
@@ -456,7 +454,6 @@ user -
@@ -649,7 +646,6 @@ true -
diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index 3bd43fe53..4450d1a90 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -1452,29 +1452,43 @@ EOF; if ($oNeighbour->tagName != 'neighbour') continue; $sNeighbourId = $oNeighbour->getAttribute('id'); - if (($oNeighbour->GetChildText('query_down') != '') && ($oNeighbour->GetChildText('query_up') == '')) - { - throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': missing the query_up specification"); - } - if (($oNeighbour->GetChildText('query_up') != '') && ($oNeighbour->GetChildText('query_down') == '')) - { - throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': missing the query_down specification"); - } - if (($oNeighbour->GetChildText('query_down') == '') && ($oNeighbour->GetChildText('attribute') == '')) + $sDirection = $oNeighbour->GetChildText('direction', 'both'); + $sAttribute = $oNeighbour->GetChildText('attribute'); + $sQueryDown = $oNeighbour->GetChildText('query_down'); + $sQueryUp = $oNeighbour->GetChildText('query_up'); + + if (($sQueryDown == '') && ($sAttribute == '')) { throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': either a query or an attribute must be specified"); } - if (($oNeighbour->GetChildText('query_down') != '') && ($oNeighbour->GetChildText('attribute') != '')) + if (($sQueryDown != '') && ($sAttribute != '')) { throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': both a query and and attribute have been specified... which one should be used?"); } + + if ($sDirection == 'both') + { + if (($sAttribute == '') && ($sQueryUp == '')) + { + throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': missing the query_up specification"); + } + } + elseif ($sDirection == 'down') + { + // Ok + } + else + { + throw new DOMFormatException("Relation '$sRelationId/$sNeighbourId': unknown direction ($sDirection), expecting 'both' or 'down'"); + } $aRelations[$sRelationId][$sNeighbourId] = array( '_legacy_' => false, + 'sDirection' => $sDirection, 'sDefinedInClass' => $sClass, 'sNeighbour' => $sNeighbourId, - 'sQueryDown' => $oNeighbour->GetChildText('query_down'), - 'sQueryUp' => $oNeighbour->GetChildText('query_up'), - 'sAttribute' => $oNeighbour->GetChildText('attribute'), + 'sQueryDown' => $sQueryDown, + 'sQueryUp' => $sQueryUp, + 'sAttribute' => $sAttribute, ); } }