/** * Helper to generate a Graphviz code for displaying the life cycle of a class * @param string $sClass The class to display * @return string The Graph description in Graphviz/Dot syntax */ function GraphvizLifecycle($sClass) { $sDotFileContent = ""; $sStateAttCode = MetaModel::GetStateAttributeCode($sClass); if (empty($sStateAttCode)) { //$oPage->p("no lifecycle for this class"); } else { $aStates = MetaModel::EnumStates($sClass); $aStimuli = MetaModel::EnumStimuli($sClass); $sDotFileContent .= "digraph finite_state_machine {\r\n\tgraph [bgcolor = \"transparent\"];\r\n\trankdir=LR;\r\n\tsize=\"12,12\"\r\n\tnode [ fontname=Verdana style=filled fillcolor=\"#ffffff\" ];\r\n\tedge [ fontname=Verdana ];\r\n"; $aStatesLinks = array(); foreach ($aStates as $sStateCode => $aStateDef) { $aStatesLinks[$sStateCode] = array('in' => 0, 'out' => 0); } foreach ($aStates as $sStateCode => $aStateDef) { $sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode); $sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode); foreach (MetaModel::EnumTransitions($sClass, $sStateCode) as $sStimulusCode => $aTransitionDef) { $aStatesLinks[$sStateCode]['out']++; $aStatesLinks[$aTransitionDef['target_state']]['in']++; $sStimulusLabel = $aStimuli[$sStimulusCode]->GetLabel(); $sTargetStateLabel = MetaModel::GetStateLabel($sClass, $aTransitionDef['target_state']); $sDotFileContent .= "\t{$sStateCode} -> {$aTransitionDef['target_state']} [ label=\"" . GraphvizEscape($sStimulusLabel) . "\"];\n"; } } foreach ($aStates as $sStateCode => $aStateDef) { if ($aStatesLinks[$sStateCode]['out'] > 0 || $aStatesLinks[$sStateCode]['in'] > 0) { // Show only reachable states $sStateLabel = str_replace(' ', '\\n', MetaModel::GetStateLabel($sClass, $sStateCode)); if ($aStatesLinks[$sStateCode]['in'] == 0 || $aStatesLinks[$sStateCode]['out'] == 0) { // End or Start state, make it look different $sDotFileContent .= "\t{$sStateCode} [ shape=doublecircle,label=\"" . GraphvizEscape($sStateLabel) . "\"];\n"; } else { $sDotFileContent .= "\t{$sStateCode} [ shape=circle,label=\"" . GraphvizEscape($sStateLabel) . "\"];\n"; } } } $sDotFileContent .= "}\n"; } return $sDotFileContent; }
public function EnumTransitions() { $sStateAttCode = MetaModel::GetStateAttributeCode(get_class($this)); if (empty($sStateAttCode)) { return array(); } $sState = $this->Get(MetaModel::GetStateAttributeCode(get_class($this))); return MetaModel::EnumTransitions(get_class($this), $sState); }
$aSelectObject = explode(',', $sSelectObject); if (empty($sFilter) || empty($sStimulus) || empty($sState)) { throw new ApplicationException(Dict::Format('UI:Error:3ParametersMissing', 'filter', 'stimulus', 'state')); } $sTransactionId = utils::ReadPostedParam('transaction_id', ''); if (!utils::IsTransactionValid($sTransactionId)) { $oP->p(Dict::S('UI:Error:ObjectAlreadyUpdated')); } else { // For archiving the modification $oFilter = DBObjectSearch::unserialize($sFilter); $sClass = $oFilter->GetClass(); $aObjects = array(); foreach ($aSelectObject as $iId) { $aObjects[] = MetaModel::GetObject($sClass, $iId); } $aTransitions = MetaModel::EnumTransitions($sClass, $sState); $aStimuli = MetaModel::EnumStimuli($sClass); $sActionLabel = $aStimuli[$sStimulus]->GetLabel(); $sActionDetails = $aStimuli[$sStimulus]->GetDescription(); $oP->set_title(Dict::Format('UI:StimulusModify_N_ObjectsOf_Class', $sActionLabel, count($aObjects), $sClass)); $oP->add('<div class="page_header">'); $oP->add('<h1>' . MetaModel::GetClassIcon($sClass) . ' ' . Dict::Format('UI:StimulusModify_N_ObjectsOf_Class', $sActionLabel, count($aObjects), $sClass) . '</h1>'); $oP->add('</div>'); $oSet = DBObjectSet::FromArray($sClass, $aObjects); // For reporting $aHeaders = array('object' => array('label' => MetaModel::GetName($sClass), 'description' => Dict::S('UI:ModifiedObject')), 'status' => array('label' => Dict::S('UI:BulkModifyStatus'), 'description' => Dict::S('UI:BulkModifyStatus+')), 'errors' => array('label' => Dict::S('UI:BulkModifyErrors'), 'description' => Dict::S('UI:BulkModifyErrors+'))); $aRows = array(); while ($oObj = $oSet->Fetch()) { $sError = Dict::S('UI:BulkModifyStatusOk'); try { $aTransitions = $oObj->EnumTransitions();
/** * 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("<img src=\"" . utils::GetAbsoluteUrlAppRoot() . "pages/graphviz.php?class={$sClass}\">\n"); $oPage->add("<h3>" . Dict::S('UI:Schema:LifeCycleTransitions') . "</h3>\n"); $oPage->add("<ul>\n"); foreach ($aStates as $sStateCode => $aStateDef) { $sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode); $sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode); $oPage->add("<li title=\"code: {$sStateCode}\">{$sStateLabel} <span style=\"color:grey;\">({$sStateCode}) {$sStateDescription}</span></li>\n"); $oPage->add("<ul>\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 = " <em>(" . implode(', ', $aTransitionDef['actions']) . ")</em>"; } else { $sActions = ""; } $oPage->add("<li><span style=\"color:red;font-weight=bold;\">{$sStimulusLabel}</span> => {$sTargetStateLabel} {$sActions}</li>\n"); } $oPage->add("</ul>\n"); } $oPage->add("</ul>\n"); $oPage->add("<h3>" . Dict::S('UI:Schema:LifeCyleAttributeOptions') . "</h3>\n"); $oPage->add("<ul>\n"); foreach ($aStates as $sStateCode => $aStateDef) { $sStateLabel = MetaModel::GetStateLabel($sClass, $sStateCode); $sStateDescription = MetaModel::GetStateDescription($sClass, $sStateCode); $oPage->add("<li title=\"code: {$sStateCode}\">{$sStateLabel} <span style=\"color:grey;\">({$sStateCode}) {$sStateDescription}</span></li>\n"); if (count($aStates[$sStateCode]['attribute_list']) > 0) { $oPage->add("<ul>\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("<li><span style=\"color:purple;font-weight=bold;\">{$sAttLabel}</span> {$sOptions}</li>\n"); } $oPage->add("</ul>\n"); } else { $oPage->p("<em>" . Dict::S('UI:Schema:LifeCycleEmptyList') . "</em>"); } } $oPage->add("</ul>\n"); } }
function test_object_lifecycle() { echo "<h4>Test object lifecycle</h4>"; self::DumpVariable(MetaModel::GetStateAttributeCode("cmdbContact")); self::DumpVariable(MetaModel::EnumStates("cmdbContact")); self::DumpVariable(MetaModel::EnumStimuli("cmdbContact")); foreach (MetaModel::EnumStates("cmdbContact") as $sStateCode => $aStateDef) { echo "<p>Transition from <strong>{$sStateCode}</strong></p>\n"; self::DumpVariable(MetaModel::EnumTransitions("cmdbContact", $sStateCode)); } $oObj = MetaModel::GetObject("cmdbContact", 18); echo "Current state: " . $oObj->GetState() . "... let's go to school..."; self::DumpVariable($oObj->EnumTransitions()); $oObj->ApplyStimulus("toschool"); echo "New state: " . $oObj->GetState() . "... let's get older..."; self::DumpVariable($oObj->EnumTransitions()); $oObj->ApplyStimulus("raise"); echo "New state: " . $oObj->GetState() . "... let's try to go further... (should give an error)"; self::DumpVariable($oObj->EnumTransitions()); $oObj->ApplyStimulus("raise"); // should give an error }