link to a class
*/
function MakeClassHLink($sClass)
{
return "".MetaModel::GetName($sClass)."";
}
/**
* Helper for this page -> link to a class
*/
function MakeRelationHLink($sRelCode)
{
$sDec = MetaModel::GetRelationProperty($sRelCode, 'description');
//$sVerbDown = MetaModel::GetRelationProperty($sRelCode, 'verb_down');
//$sVerbUp = MetaModel::GetRelationProperty($sRelCode, 'verb_up');
return "".$sRelCode."";
}
/**
* Helper for the global list and the details of a given class
*/
function DisplaySubclasses($oPage, $sClass)
{
$aChildClasses = MetaModel::EnumChildClasses($sClass);
if (count($aChildClasses) != 0)
{
$oPage->add("
\n");
foreach($aChildClasses as $sClassName)
{
// Skip indirect childs, they will be handled somewhere else
if (MetaModel::GetParentPersistentClass($sClassName) == $sClass)
{
$oPage->add("- ".MakeClassHLink($sClassName)."\n");
DisplaySubclasses($oPage, $sClassName);
$oPage->add("
\n");
}
}
$oPage->add("
\n");
}
}
/**
* Helper for the global list and the details of a given class
*/
function DisplayReferencingClasses($oPage, $sClass)
{
$bSkipLinkingClasses = false;
$aRefs = MetaModel::EnumReferencingClasses($sClass, $bSkipLinkingClasses);
if (count($aRefs) != 0)
{
$oPage->add("\n");
foreach ($aRefs as $sRemoteClass => $aRemoteKeys)
{
foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
{
$oPage->add("- ".Dict::Format('UI:Schema:Class_ReferencingClasses_From_By', $sClass, MakeClassHLink($sRemoteClass), $sExtKeyAttCode)."
\n");
}
}
$oPage->add("
\n");
}
}
/**
* Helper for the global list and the details of a given class
*/
function DisplayLinkingClasses($oPage, $sClass)
{
$bSkipLinkingClasses = false;
$aRefs = MetaModel::EnumLinkingClasses($sClass);
if (count($aRefs) != 0)
{
$oPage->add("\n");
foreach ($aRefs as $sLinkClass => $aRemoteClasses)
{
foreach($aRemoteClasses as $sExtKeyAttCode => $sRemoteClass)
{
$oPage->add("- ".Dict::Format('UI:Schema:Class_IsLinkedTo_Class_Via_ClassAndAttribute', $sClass, MakeClassHLink($sRemoteClass), MakeClassHLink($sLinkClass), $sExtKeyAttCode));
}
}
$oPage->add("
\n");
}
}
/**
* Helper for the global list and the details of a given class
*/
function DisplayRelatedClassesBestInClass($oPage, $sClass, $iLevels = 20, &$aVisitedClasses = array(), $bSubtree = true)
{
if ($iLevels <= 0) return;
$iLevels--;
if (array_key_exists($sClass, $aVisitedClasses)) return;
$aVisitedClasses[$sClass] = true;
if ($bSubtree) $oPage->add("\n");
foreach (MetaModel::EnumParentClasses($sClass) as $sParentClass)
{
DisplayRelatedClassesBestInClass($oPage, $sParentClass, $iLevels, $aVisitedClasses, false);
}
////$oPage->add("");
foreach (MetaModel::EnumReferencedClasses($sClass) as $sExtKeyAttCode => $sRemoteClass)
{
$sVisited = (array_key_exists($sRemoteClass, $aVisitedClasses)) ? " ..." : "";
if (MetaModel::GetAttributeOrigin($sClass, $sExtKeyAttCode) == $sClass)
{
$oPage->add("
- $sClass| $sExtKeyAttCode =>".MakeClassHLink($sRemoteClass)."$sVisited
\n");
DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses);
}
}
foreach (MetaModel::EnumReferencingClasses($sClass) as $sRemoteClass => $aRemoteKeys)
{
foreach ($aRemoteKeys as $sExtKeyAttCode => $oExtKeyAttDef)
{
$sVisited = (array_key_exists($sRemoteClass, $aVisitedClasses)) ? " ..." : "";
$oPage->add("- $sClass| <=".MakeClassHLink($sRemoteClass)."::$sExtKeyAttCode$sVisited
\n");
DisplayRelatedClassesBestInClass($oPage, $sRemoteClass, $iLevels, $aVisitedClasses);
}
}
////$oPage->add("");
if ($bSubtree) $oPage->add("
\n");
}
/**
* Helper for the list of classes related to the given class
*/
function DisplayRelatedClasses($oPage, $sClass)
{
$oPage->add("".Dict::Format('UI:Schema:Links:1-n', $sClass)."
\n");
DisplayReferencingClasses($oPage, $sClass);
$oPage->add("".Dict::Format('UI:Schema:Links:n-n', $sClass)."
\n");
DisplayLinkingClasses($oPage, $sClass);
$oPage->add("".Dict::S('UI:Schema:Links:All')."
\n");
DisplayRelatedClassesBestInClass($oPage, $sClass, 4);
}
/**
* Helper for the lifecycle details of a given class
*/
function DisplayLifecycle($oPage, $sClass)
{
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
if (empty($sStateAttCode))
{
$oPage->p(Dict::S('UI:Schema:NoLifeCyle'));
}
else
{
$aStates = MetaModel::EnumStates($sClass);
$aStimuli = MetaModel::EnumStimuli($sClass);
$oPage->add("
\n");
$oPage->add("".Dict::S('UI:Schema:LifeCycleTransitions')."
\n");
$oPage->add("\n");
foreach ($aStates as $sStateCode => $aStateDef)
{
$sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode);
$sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode);
$oPage->add("- $sStateLabel ($sStateDescription)
\n");
$oPage->add("\n");
foreach(MetaModel::EnumTransitions($sClass, $sStateCode) as $sStimulusCode => $aTransitionDef)
{
$sStimulusLabel = $aStimuli[$sStimulusCode]->GetLabel();
$sTargetStateLabel = MetaModel::GetStateLabel($sClass, $aTransitionDef['target_state']);
if (count($aTransitionDef['actions']) > 0)
{
$sActions = " (".implode(', ', $aTransitionDef['actions']).")";
}
else
{
$sActions = "";
}
$oPage->add("- $sStimulusLabel => $sTargetStateLabel $sActions
\n");
}
$oPage->add("
\n");
}
$oPage->add("
\n");
$oPage->add("".Dict::S('UI:Schema:LifeCyleAttributeOptions')."
\n");
$oPage->add("\n");
foreach ($aStates as $sStateCode => $aStateDef)
{
$sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode);
$sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode);
$oPage->add("- $sStateLabel ($sStateDescription)
\n");
if (count($aStates[$sStateCode]['attribute_list']) > 0)
{
$oPage->add("\n");
foreach($aStates[$sStateCode]['attribute_list'] as $sAttCode => $iOptions)
{
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
$sAttLabel = $oAttDef->GetLabel();
$aOptions = array();
if ($iOptions & OPT_ATT_HIDDEN) $aOptions[] = Dict::S('UI:Schema:LifeCycleHiddenAttribute');
if ($iOptions & OPT_ATT_READONLY) $aOptions[] = Dict::S('UI:Schema:LifeCycleReadOnlyAttribute');
if ($iOptions & OPT_ATT_MANDATORY) $aOptions[] = Dict::S('UI:Schema:LifeCycleMandatoryAttribute');
if ($iOptions & OPT_ATT_MUSTCHANGE) $aOptions[] = Dict::S('UI:Schema:LifeCycleAttributeMustChange');
if ($iOptions & OPT_ATT_MUSTPROMPT) $aOptions[] = Dict::S('UI:Schema:LifeCycleAttributeMustPrompt');
if (count($aOptions))
{
$sOptions = implode(', ', $aOptions);
}
else
{
$sOptions = "";
}
$oPage->add("- $sAttLabel $sOptions
\n");
}
$oPage->add("
\n");
}
else
{
$oPage->p("".Dict::S('UI:Schema:LifeCycleEmptyList')."");
}
}
$oPage->add("
\n");
}
}
/**
* Helper for the trigger
*/
function DisplayTriggers($oPage, $sClass)
{
$oSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnStateChange WHERE target_class = '$sClass'"));
cmdbAbstractObject::DisplaySet($oPage, $oSet);
}
/**
* Display the list of classes from the business model
*/
function DisplayClassesList($oPage)
{
$oPage->add("".Dict::S('UI:Schema:Title')."
\n");
$oPage->add("\n");
foreach(MetaModel::EnumCategories() as $sCategory)
{
if (empty($sCategory)) continue; // means 'all' -> skip
$sClosed = ($sCategory == 'bizmodel') ? '' : ' class="closed"';
$oPage->add("- ".Dict::Format('UI:Schema:CategoryMenuItem', $sCategory)."\n");
$oPage->add("
\n");
foreach(MetaModel::GetClasses($sCategory) as $sClassName)
{
if (MetaModel::IsStandaloneClass($sClassName))
{
$oPage->add("- ".MakeClassHLink($sClassName)."
\n");
}
else if (MetaModel::IsRootClass($sClassName))
{
$oPage->add("- ".MakeClassHLink($sClassName)."\n");
DisplaySubclasses($oPage, $sClassName);
$oPage->add("
\n");
}
}
$oPage->add("
\n");
$oPage->add(" \n");
}
$oPage->add("
\n");
$oPage->add("".Dict::S('UI:Schema:Relationships')."
\n");
$oPage->add("\n");
foreach (MetaModel::EnumRelations() as $sRelCode)
{
$oPage->add("- ".MakeRelationHLink($sRelCode)."\n");
$oPage->add("
\n");
foreach (MetaModel::EnumRelationProperties($sRelCode) as $sProp => $sValue)
{
$oPage->add("- $sProp: ".htmlentities($sValue)."
\n");
}
$oPage->add("
\n");
$oPage->add(" \n");
}
$oPage->add("
\n");
$oPage->add_ready_script('$("#ClassesList").treeview();');
$oPage->add_ready_script('$("#ClassesRelationships").treeview();');
}
/**
* Display the details of a given class of objects
*/
function DisplayClassDetails($oPage, $sClass)
{
$oPage->p("$sClass
\n".MetaModel::GetClassDescription($sClass)."
\n");
if (MetaModel::IsAbstract($sClass))
{
$oPage->p(Dict::S('UI:Schema:AbstractClass'));
}
else
{
$oPage->p(Dict::S('UI:Schema:NonAbstractClass'));
}
$oPage->p("".Dict::S('UI:Schema:ClassHierarchyTitle')."
");
$oPage->p("[".Dict::S('UI:Schema:AllClasses')."]");
// List the parent classes
$sParent = MetaModel::GetParentPersistentClass($sClass);
$aParents = array();
$aParents[] = $sClass;
while($sParent != "" && $sParent != 'cmdbAbstractObject')
{
$aParents[] = $sParent;
$sParent = MetaModel::GetParentPersistentClass($sParent);
}
$iIndex = count($aParents);
$sSpace ="";
$oPage->add("");
while ($iIndex > 0)
{
$iIndex--;
$oPage->add("- ".MakeClassHLink($aParents[$iIndex])."\n");
$oPage->add("
\n");
}
for($iIndex = 0; $iIndex < count($aParents); $iIndex++)
{
$oPage->add("
\n \n");
}
$oPage->add("
\n");
$oPage->add_ready_script('$("#ClassHierarchy").treeview();');
$oPage->p('');
$oPage->AddTabContainer('details');
$oPage->SetCurrentTabContainer('details');
// List the attributes of the object
$aDetails = array();
foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode=>$oAttDef)
{
if ($oAttDef->IsExternalKey())
{
$sValue = Dict::Format('UI:Schema:ExternalKey_To',MakeClassHLink($oAttDef->GetTargetClass()));
}
else
{
$sValue = $oAttDef->GetDescription();
}
$sType = $oAttDef->GetType().' ('.$oAttDef->GetTypeDesc().')';
$sOrigin = MetaModel::GetAttributeOrigin($sClass, $sAttCode);
$sAllowedValues = "";
$oAllowedValuesDef = $oAttDef->GetValuesDef();
$sMoreInfo = "";
$aCols = array();
foreach($oAttDef->GetSQLColumns() as $sCol => $sFieldDesc)
{
$aCols[] = "$sCol: $sFieldDesc";
}
if (count($aCols) > 0)
{
$sCols = implode(', ', $aCols);
$aMoreInfo = array();
$aMoreInfo[] = Dict::Format('UI:Schema:Columns_Description', $sCols);
$aMoreInfo[] = Dict::Format('UI:Schema:Default_Description', $oAttDef->GetDefaultValue());
$aMoreInfo[] = $oAttDef->IsNullAllowed() ? Dict::S('UI:Schema:NullAllowed') : Dict::S('UI:Schema:NullNotAllowed');
$sMoreInfo .= implode(', ', $aMoreInfo);
}
if (is_object($oAllowedValuesDef)) $sAllowedValues = $oAllowedValuesDef->GetValuesDescription();
else $sAllowedValues = '';
$aDetails[] = array('code' => $oAttDef->GetCode(), 'type' => $sType, 'origin' => $sOrigin, 'label' => $oAttDef->GetLabel(), 'description' => $sValue, 'values' => $sAllowedValues, 'moreinfo' => $sMoreInfo);
}
$oPage->SetCurrentTab(Dict::S('UI:Schema:Attributes'));
$aConfig = array( 'code' => array('label' => Dict::S('UI:Schema:AttributeCode'), 'description' => Dict::S('UI:Schema:AttributeCode+')),
'label' => array('label' => Dict::S('UI:Schema:Label'), 'description' => Dict::S('UI:Schema:Label+')),
'type' => array('label' => Dict::S('UI:Schema:Type'), 'description' => Dict::S('UI:Schema:Type+')),
'origin' => array('label' => Dict::S('UI:Schema:Origin'), 'description' => Dict::S('UI:Schema:Origin+')),
'description' => array('label' => Dict::S('UI:Schema:Description'), 'description' => Dict::S('UI:Schema:Description+')),
'values' => array('label' => Dict::S('UI:Schema:AllowedValues'), 'description' => Dict::S('UI:Schema:AllowedValues+')),
'moreinfo' => array('label' => Dict::S('UI:Schema:MoreInfo'), 'description' => Dict::S('UI:Schema:MoreInfo+')),
);
$oPage->table($aConfig, $aDetails);
// List the search criteria for this object
$aDetails = array();
foreach (MetaModel::GetClassFilterDefs($sClass) as $sFilterCode => $oFilterDef)
{
$aOpDescs = array();
foreach ($oFilterDef->GetOperators() as $sOpCode => $sOpDescription)
{
$sIsTheLooser = ($sOpCode == $oFilterDef->GetLooseOperator()) ? " (loose search)" : "";
$aOpDescs[] = "$sOpCode ($sOpDescription)$sIsTheLooser";
}
$aDetails[] = array( 'code' => $sFilterCode, 'description' => $oFilterDef->GetLabel(),'operators' => implode(" / ", $aOpDescs));
}
$oPage->SetCurrentTab(Dict::S('UI:Schema:SearchCriteria'));
$aConfig = array( 'code' => array('label' => Dict::S('UI:Schema:FilterCode'), 'description' => Dict::S('UI:Schema:FilterCode+')),
'description' => array('label' => Dict::S('UI:Schema:FilterDescription'), 'description' => Dict::S('UI:Schema:FilterDescription+')),
'operators' => array('label' => Dict::S('UI:Schema:AvailOperators'), 'description' => Dict::S('UI:Schema:AvailOperators+'))
);
$oPage->table($aConfig, $aDetails);
$oPage->SetCurrentTab(Dict::S('UI:Schema:ChildClasses'));
DisplaySubclasses($oPage, $sClass);
$oPage->SetCurrentTab(Dict::S('UI:Schema:ReferencingClasses'));
DisplayReferencingClasses($oPage, $sClass);
$oPage->SetCurrentTab(Dict::S('UI:Schema:RelatedClasses'));
DisplayRelatedClasses($oPage, $sClass);
$oPage->SetCurrentTab(Dict::S('UI:Schema:LifeCycle'));
DisplayLifecycle($oPage, $sClass);
$oPage->SetCurrentTab(Dict::S('UI:Schema:Triggers'));
DisplayTriggers($oPage, $sClass);
$oPage->SetCurrentTab();
$oPage->SetCurrentTabContainer();
}
/**
* Display the details of a given relation (e.g. "impacts")
*/
function DisplayRelationDetails($oPage, $sRelCode)
{
$sDesc = MetaModel::GetRelationProperty($sRelCode, 'description');
$sVerbDown = MetaModel::GetRelationProperty($sRelCode, 'verb_down');
$sVerbUp = MetaModel::GetRelationProperty($sRelCode, 'verb_up');
$oPage->add("".Dict::Format('UI:Schema:Relation_Code_Description', $sRelCode, $sDesc)."
");
$oPage->p(Dict::Format('UI:Schema:RelationDown_Description', $sVerbDown));
$oPage->p(Dict::Format('UI:Schema:RelationUp_Description', $sVerbUp));
$oPage->add("\n");
foreach(MetaModel::GetClasses() as $sClass)
{
$aRelQueries = MetaModel::EnumRelationQueries($sClass, $sRelCode);
if (count($aRelQueries) > 0)
{
$oPage->add("- class ".MakeClassHLink($sClass)."\n");
$oPage->add("
\n");
foreach ($aRelQueries as $sRelKey => $aQuery)
{
$sQuery = $aQuery['sQuery'];
$iDistance = $aQuery['iDistance'];
if ($aQuery['bPropagate'])
{
$oPage->add("- ".Dict::Format('UI:Schema:RelationPropagates', $sRelKey, $iDistance, $sQuery)."
\n");
}
else
{
$oPage->add("- ".Dict::Format('UI:Schema:RelationDoesNotPropagate', $sRelKey, $iDistance, $sQuery)."
\n");
}
}
$oPage->add("
\n");
$oPage->add(" \n");
}
}
$oPage->add_ready_script('$("#RelationshipDetails").treeview();');
}
require_once('../application/loginwebpage.class.inc.php');
LoginWebPage::DoLogin(); // Check user rights and prompt if needed
// Display the menu on the left
$oContext = new UserContext();
$oAppContext = new ApplicationContext();
$iActiveNodeId = utils::ReadParam('menu', -1);
$currentOrganization = utils::ReadParam('org_id', 1);
$operation = utils::ReadParam('operation', '');
$oPage = new iTopWebPage(Dict::S('UI:Schema:Title'), $currentOrganization);
$oPage->no_cache();
$operation = utils::ReadParam('operation', '');
switch($operation)
{
case 'details_class':
$sClass = utils::ReadParam('class', 'logRealObject');
DisplayClassDetails($oPage, $sClass);
break;
case 'details_relation':
$sRelCode = utils::ReadParam('relcode', '');
DisplayRelationDetails($oPage, $sRelCode);
break;
case 'list':
default:
DisplayClassesList($oPage);
}
$oPage->output();
?>