/** * Presentation of the data model * * @copyright Copyright (C) 2010-2017 Combodo SARL * @license http://opensource.org/licenses/AGPL-3.0 */ require_once('../approot.inc.php'); require_once(APPROOT.'/application/application.inc.php'); require_once(APPROOT.'/application/itopwebpage.class.inc.php'); require_once(APPROOT.'/application/startup.inc.php'); require_once(APPROOT.'/application/loginwebpage.class.inc.php'); LoginWebPage::DoLogin(true); // Check user rights and prompt if needed (must be admin) /** * Helper for this page -> link to a class */ function MakeClassHLink($sClass, $sContext) { return "".MetaModel::GetName($sClass)." ($sClass)"; } /** * Helper for this page -> link to a class */ function MakeRelationHLink($sRelCode, $sContext) { $sDesc = MetaModel::GetRelationDescription($sRelCode); return "".$sRelCode.""; } /** * Helper for the global list and the details of a given class */ function DisplaySubclasses($oPage, $sClass, $sContext) { $aChildClasses = MetaModel::EnumChildClasses($sClass); if (count($aChildClasses) != 0) { $oPage->add("\n"); } } /** * Helper for the global list and the details of a given class */ function DisplayReferencingClasses($oPage, $sClass, $sContext) { $bSkipLinkingClasses = false; $aRefs = MetaModel::EnumReferencingClasses($sClass, $bSkipLinkingClasses); if (count($aRefs) != 0) { $oPage->add("\n"); } } /** * Helper for the global list and the details of a given class */ function DisplayLinkingClasses($oPage, $sClass, $sContext) { $bSkipLinkingClasses = false; $aRefs = MetaModel::EnumLinkingClasses($sClass); if (count($aRefs) != 0) { $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, $sContext) { if ($iLevels <= 0) return; $iLevels--; if (array_key_exists($sClass, $aVisitedClasses)) return; $aVisitedClasses[$sClass] = true; if ($bSubtree) $oPage->add("\n"); } /** * Helper for the list of classes related to the given class */ function DisplayRelatedClasses($oPage, $sClass, $sContext) { $oPage->add("

".Dict::Format('UI:Schema:Links:1-n', $sClass)."

\n"); DisplayReferencingClasses($oPage, $sClass, $sContext); $oPage->add("

".Dict::Format('UI:Schema:Links:n-n', $sClass)."

\n"); DisplayLinkingClasses($oPage, $sClass, $sContext); $oPage->add("

".Dict::S('UI:Schema:Links:All')."

\n"); $aEmpty = array(); DisplayRelatedClassesBestInClass($oPage, $sClass, 4, $aEmpty, true, $sContext); } /** * 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"); $oPage->add("

".Dict::S('UI:Schema:LifeCyleAttributeOptions')."

\n"); $oPage->add("\n"); } } /** * Helper for the trigger */ function DisplayTriggers($oPage, $sClass) { $sClassList = implode("', '", MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL)); $oSet = new CMDBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObject WHERE target_class IN ('$sClassList')")); cmdbAbstractObject::DisplaySet($oPage, $oSet, array('block_id' => 'triggers')); } /** * Display the list of classes from the business model */ function DisplayClassesList($oPage, $sContext) { $oPage->add("

".Dict::S('UI:Schema:Title')."

\n"); $oPage->add("\n"); $oPage->add("

".Dict::S('UI:Schema:Relationships')."

\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, $sContext) { $oPage->add("

".MetaModel::GetName($sClass)." ($sClass) - ".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')."

"); $aParentClasses = array(); foreach(MetaModel::EnumParentClasses($sClass) as $sParentClass) { $aParentClasses[] = MakeClassHLink($sParentClass, $sContext); } if (count($aParentClasses) > 0) { $sParents = implode(' >> ', $aParentClasses)." >> $sClass"; } else { $sParents = ''; } $oPage->p("[".Dict::S('UI:Schema:AllClasses')."] $sParents"); if (MetaModel::HasChildrenClasses($sClass)) { $oPage->add("\n"); $oPage->add_ready_script('$("#ClassHierarchy").treeview();'); } $oPage->p(''); $oPage->AddTabContainer('details'); $oPage->SetCurrentTabContainer('details'); // List the attributes of the object $aForwardChangeTracking = MetaModel::GetTrackForwardExternalKeys($sClass); $aDetails = array(); foreach(MetaModel::ListAttributeDefs($sClass) as $sAttCode=>$oAttDef) { if ($oAttDef->IsExternalKey()) { $sValue = Dict::Format('UI:Schema:ExternalKey_To',MakeClassHLink($oAttDef->GetTargetClass(), $sContext)); if (array_key_exists($sAttCode, $aForwardChangeTracking)) { $oLinkSet = $aForwardChangeTracking[$sAttCode]; $sRemoteClass = $oLinkSet->GetHostClass(); $sValue = $sValue."*"; } } elseif ($oAttDef->IsLinkSet()) { $sValue = MakeClassHLink($oAttDef->GetLinkedClass(), $sContext); } else { $sValue = $oAttDef->GetDescription(); } $sType = $oAttDef->GetType().' ('.$oAttDef->GetTypeDesc().')'; $sOrigin = MetaModel::GetAttributeOrigin($sClass, $sAttCode); $sAllowedValues = ""; $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 ($oAttDef instanceof AttributeEnum) { // Display localized values for the enum (which depend on the localization provided by the class) $aLocalizedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, array()); $aDescription = array(); foreach($aLocalizedValues as $val => $sDisplay) { $aDescription[] = htmlentities("$val => ", ENT_QUOTES, 'UTF-8').$sDisplay; } $sAllowedValues = implode(', ', $aDescription); } elseif (is_object($oAllowedValuesDef = $oAttDef->GetValuesDef())) { $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, $sContext); $oPage->SetCurrentTab(Dict::S('UI:Schema:ReferencingClasses')); DisplayReferencingClasses($oPage, $sClass, $sContext); $oPage->SetCurrentTab(Dict::S('UI:Schema:RelatedClasses')); DisplayRelatedClasses($oPage, $sClass, $sContext); $oPage->SetCurrentTab(Dict::S('UI:Schema:LifeCycle')); DisplayLifecycle($oPage, $sClass, $sContext); $oPage->SetCurrentTab(Dict::S('UI:Schema:Triggers')); DisplayTriggers($oPage, $sClass, $sContext); $oPage->SetCurrentTab(); $oPage->SetCurrentTabContainer(); } /** * 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("

".Dict::Format('UI:Schema:Relation_Code_Description', $sRelCode, $sDesc)."

"); $oPage->p(Dict::Format('UI:Schema:RelationUp_Description', $sLabel)); $oPage->add("