diff --git a/application/cmdbabstract.class.inc.php b/application/cmdbabstract.class.inc.php index d9fcc2361..15404aaab 100644 --- a/application/cmdbabstract.class.inc.php +++ b/application/cmdbabstract.class.inc.php @@ -2464,16 +2464,13 @@ EOF } $sActionLabel = $aStimuli[$sStimulus]->GetLabel(); $sActionDetails = $aStimuli[$sStimulus]->GetDescription(); - $aTransition = $aTransitions[$sStimulus]; - $sTargetState = $aTransition['target_state']; - $aTargetStates = MetaModel::EnumStates($sClass); - $oPage->add("
\n"); - $oPage->add("

$sActionLabel - {$this->GetName()}

\n"); - $oPage->set_title($sActionLabel); - $oPage->add("
\n"); - $aTargetState = $aTargetStates[$sTargetState]; - $aExpectedAttributes = $aTargetState['attribute_list']; - $oPage->add("

$sActionDetails

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

$sActionLabel - {$this->GetName()}

\n"); + $oPage->set_title($sActionLabel); + $oPage->add("
\n"); + $oPage->add("

$sActionDetails

\n"); + $sTargetState = $aTransitions[$sStimulus]['target_state']; + $aExpectedAttributes = $this->GetTransitionAttributes($sStimulus /*, current state*/); $sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position'); if ($sButtonsPosition == 'bottom') { diff --git a/core/dbobject.class.php b/core/dbobject.class.php index ab01de12e..c9dc7b6f5 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -1,5 +1,5 @@ Get($sStateAttCode); + } + + // Retrieving attribute flags + $iAttributeFlags = $this->GetAttributeFlags($sAttCode, $aReasons, $sOriginState); + + // Retrieving transition flags + $iTransitionFlags = MetaModel::GetTransitionFlags(get_class($this), $sOriginState, $sStimulus, $sAttCode); + + // Merging transition flags with attribute flags + $iFlags = $iTransitionFlags | $iAttributeFlags; + + return $iFlags; + } + + /** + * Returns an array of attribute codes (with their flags) when $sStimulus is applied on the object in the $sOriginState state. + * Note: Attributes (and flags) from the target state and the transition are combined. + * + * @param $sStimulus string + * @param $sOriginState string Default is current state + * @return array + */ + public function GetTransitionAttributes($sStimulus, $sOriginState = null) + { + $sObjClass = get_class($this); + + // Defining current state as origin state if not specified + if($sOriginState === null) + { + $sOriginState = $this->GetState(); + } + + $aAttributes = MetaModel::GetTransitionAttributes($sObjClass, $sStimulus, $sOriginState); + + return $aAttributes; + } + /** * Returns the set of flags (OPT_ATT_HIDDEN, OPT_ATT_READONLY, OPT_ATT_MANDATORY...) * for the given attribute for the current state of the object considered as an INITIAL state diff --git a/core/metamodel.class.php b/core/metamodel.class.php index 34b492975..e21fa7c34 100644 --- a/core/metamodel.class.php +++ b/core/metamodel.class.php @@ -1,5 +1,5 @@ $iAttributeFlags) + { + if(array_key_exists($sAttCode, $aAttributes)) + { + $aAttributes[$sAttCode] = $aAttributes[$sAttCode] | $iAttributeFlags; + } + else + { + $aAttributes[$sAttCode] = $iAttributeFlags; + } + } + + return $aAttributes; + } /** * Combines the flags from the all states that compose the initial_state_path diff --git a/pages/UI.php b/pages/UI.php index cbd8932e7..a2b86841a 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -1120,17 +1120,16 @@ EOF $sActionLabel = $aStimuli[$sStimulus]->GetLabel(); $sActionDetails = $aStimuli[$sStimulus]->GetDescription(); - $aTransition = $aTransitions[$sStimulus]; - $sTargetState = $aTransition['target_state']; + $sTargetState = $aTransitions[$sStimulus]['target_state']; $aStates = MetaModel::EnumStates($sClass); $aTargetStateDef = $aStates[$sTargetState]; - + $oP->set_title(Dict::Format('UI:StimulusModify_N_ObjectsOf_Class', $sActionLabel, count($aSelectObject), $sClass)); $oP->add(''); - $aExpectedAttributes = $aTargetStateDef['attribute_list']; + $aExpectedAttributes = MetaModel::GetTransitionAttributes($sClass, $sStimulus, $sState); $aDetails = array(); $iFieldIndex = 0; $aFieldsMap = array(); @@ -1326,16 +1325,13 @@ EOF { $sActionLabel = $aStimuli[$sStimulus]->GetLabel(); $sActionDetails = $aStimuli[$sStimulus]->GetDescription(); - $aTransition = $aTransitions[$sStimulus]; - $sTargetState = $aTransition['target_state']; - $aTargetStates = MetaModel::EnumStates($sClass); - $aTargetState = $aTargetStates[$sTargetState]; - $aExpectedAttributes = $aTargetState['attribute_list']; + $sTargetState = $aTransitions[$sStimulus]['target_state']; + $aExpectedAttributes = $oObj->GetTransitionAttributes($sStimulus /* cureent state */); $aDetails = array(); $aErrors = array(); foreach($aExpectedAttributes as $sAttCode => $iExpectCode) { - $iFlags = $oObj->GetAttributeFlags($sAttCode); + $iFlags = $oObj->GetTransitionFlags($sAttCode, $sStimulus); if (($iExpectCode & (OPT_ATT_MUSTCHANGE|OPT_ATT_MUSTPROMPT)) || ($oObj->Get($sAttCode) == '') ) { $paramValue = utils::ReadPostedParam("attr_$sAttCode", '', 'raw_data'); @@ -1450,16 +1446,13 @@ EOF { $sActionLabel = $aStimuli[$sStimulus]->GetLabel(); $sActionDetails = $aStimuli[$sStimulus]->GetDescription(); - $aTransition = $aTransitions[$sStimulus]; - $sTargetState = $aTransition['target_state']; - $aTargetStates = MetaModel::EnumStates($sClass); - $aTargetState = $aTargetStates[$sTargetState]; - $aExpectedAttributes = $aTargetState['attribute_list']; + $sTargetState = $aTransitions[$sStimulus]['target_state']; + $aExpectedAttributes = $oObj->GetTransitionAttributes($sStimulus /*, current state*/); $aDetails = array(); $aErrors = array(); foreach($aExpectedAttributes as $sAttCode => $iExpectCode) { - $iFlags = $oObj->GetAttributeFlags($sAttCode); + $iFlags = $oObj->GetTransitionFlags($sAttCode, $sStimulus); if (($iExpectCode & (OPT_ATT_MUSTCHANGE|OPT_ATT_MUSTPROMPT)) || ($oObj->Get($sAttCode) == '') ) { $paramValue = utils::ReadPostedParam("attr_$sAttCode", '', 'raw_data'); diff --git a/setup/compiler.class.inc.php b/setup/compiler.class.inc.php index d353c38a8..7ea224cec 100644 --- a/setup/compiler.class.inc.php +++ b/setup/compiler.class.inc.php @@ -1536,7 +1536,29 @@ EOF $aVerbs[] = "array('verb' => '$sVerb', 'params' => $sActionParams)"; } $sActions = implode(', ', $aVerbs); - $sLifecycle .= " MetaModel::Init_DefineTransition(\"$sState\", \"$sStimulus\", array(\"target_state\"=>\"$sTargetState\", \"actions\"=>array($sActions), \"user_restriction\"=>null));\n"; + + $sLifecycle .= " MetaModel::Init_DefineTransition(\"$sState\", \"$sStimulus\", array(\n"; + $sLifecycle .= " \"target_state\"=>\"$sTargetState\",\n"; + $sLifecycle .= " \"actions\"=>array($sActions),\n"; + $sLifecycle .= " \"user_restriction\"=>null,\n"; + $sLifecycle .= " \"attribute_list\"=>array(\n"; + + $oFlags = $oTransition->GetOptionalElement('flags'); + if($oFlags !== null) + { + foreach ($oFlags->getElementsByTagName('attribute') as $oAttributeNode) + { + $sFlags = $this->FlagsToPHP($oAttributeNode); + if (strlen($sFlags) > 0) + { + $sAttCode = $oAttributeNode->GetAttribute('id'); + $sLifecycle .= " '$sAttCode' => $sFlags,\n"; + } + } + } + + $sLifecycle .= " )\n"; + $sLifecycle .= " ));\n"; } } } diff --git a/setup/itopdesignformat.class.inc.php b/setup/itopdesignformat.class.inc.php index cd5bd2d6c..dc798f44c 100644 --- a/setup/itopdesignformat.class.inc.php +++ b/setup/itopdesignformat.class.inc.php @@ -1,5 +1,5 @@ LogWarning('The attribute _delta="force" is not supported, converted to _delta="define" ('.$iCount.' instances processed).'); } + + // Remove attribute flags on transitions + // + $oNodeList = $oXPath->query("/itop_design/classes//class/lifecycle/states/state/transitions/transition/flags"); + $this->LogWarning('Before removing flags nodes'); + foreach ($oNodeList as $oNode) + { + $this->LogWarning('Attribute flags '.self::GetItopNodePath($oNode).' is irrelevant on transition and must be removed.'); + $this->DeleteNode($oNode); + } }