mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
#965 (Retrofit from trunk) Proper handling of CheckToWrite in ApplyStimulus
SVN:2.0.2[3285]
This commit is contained in:
@@ -2121,6 +2121,138 @@ EOF
|
||||
}
|
||||
return $oObj->DisplayModifyForm( $oPage, $aExtraParams);
|
||||
}
|
||||
|
||||
public function DisplayStimulusForm(WebPage $oPage, $sStimulus)
|
||||
{
|
||||
$sClass = get_class($this);
|
||||
$aTransitions = $this->EnumTransitions();
|
||||
$aStimuli = MetaModel::EnumStimuli($sClass);
|
||||
if (!isset($aTransitions[$sStimulus]))
|
||||
{
|
||||
// Invalid stimulus
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $this->GetName(), $this->GetStateLabel()));
|
||||
}
|
||||
$sActionLabel = $aStimuli[$sStimulus]->GetLabel();
|
||||
$sActionDetails = $aStimuli[$sStimulus]->GetDescription();
|
||||
$aTransition = $aTransitions[$sStimulus];
|
||||
$sTargetState = $aTransition['target_state'];
|
||||
$aTargetStates = MetaModel::EnumStates($sClass);
|
||||
$oPage->add("<div class=\"page_header\">\n");
|
||||
$oPage->add("<h1>$sActionLabel - <span class=\"hilite\">{$this->GetName()}</span></h1>\n");
|
||||
$oPage->set_title($sActionLabel);
|
||||
$oPage->add("</div>\n");
|
||||
$aTargetState = $aTargetStates[$sTargetState];
|
||||
$aExpectedAttributes = $aTargetState['attribute_list'];
|
||||
$oPage->add("<h1>$sActionDetails</h1>\n");
|
||||
$sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position');
|
||||
if ($sButtonsPosition == 'bottom')
|
||||
{
|
||||
// bottom: Displays the ticket details BEFORE the actions
|
||||
$oPage->add('<div class="ui-widget-content">');
|
||||
$this->DisplayBareProperties($oPage);
|
||||
$oPage->add('</div>');
|
||||
}
|
||||
$oPage->add("<div class=\"wizContainer\">\n");
|
||||
$oPage->add("<form id=\"apply_stimulus\" method=\"post\" onSubmit=\"return OnSubmit('apply_stimulus');\">\n");
|
||||
$aDetails = array();
|
||||
$iFieldIndex = 0;
|
||||
$aFieldsMap = array();
|
||||
|
||||
$aDetailsList =$this->FlattenZList(MetaModel::GetZListItems($sClass, 'details'));
|
||||
// Order the fields based on their dependencies, set the fields for which there is only one possible value
|
||||
// and perform this in the order of dependencies to avoid dead-ends
|
||||
$aDeps = array();
|
||||
foreach($aDetailsList as $sAttCode)
|
||||
{
|
||||
$aDeps[$sAttCode] = MetaModel::GetPrequisiteAttributes($sClass, $sAttCode);
|
||||
}
|
||||
$aList =$this->OrderDependentFields($aDeps);
|
||||
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
// Consider only the "expected" fields for the target state
|
||||
if (array_key_exists($sAttCode, $aExpectedAttributes))
|
||||
{
|
||||
$iExpectCode = $aExpectedAttributes[$sAttCode];
|
||||
// Prompt for an attribute if
|
||||
// - the attribute must be changed or must be displayed to the user for confirmation
|
||||
// - or the field is mandatory and currently empty
|
||||
if ( ($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) ||
|
||||
(($iExpectCode & OPT_ATT_MANDATORY) && ($this->Get($sAttCode) == '')) )
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$aArgs = array('this' => $this);
|
||||
// If the field is mandatory, set it to the only possible value
|
||||
if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY))
|
||||
{
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs);
|
||||
if ($oAllowedValues->Count() == 1)
|
||||
{
|
||||
$oRemoteObj = $oAllowedValues->Fetch();
|
||||
$this->Set($sAttCode, $oRemoteObj->GetKey());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
|
||||
if (count($aAllowedValues) == 1)
|
||||
{
|
||||
$aValues = array_keys($aAllowedValues);
|
||||
$this->Set($sAttCode, $aValues[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oPage, $sClass, $sAttCode, $oAttDef,$this->Get($sAttCode),$this->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode, $aArgs);
|
||||
$aDetails[] = array('label' => '<span>'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_att_$iFieldIndex\">$sHTMLValue</span>");
|
||||
$aFieldsMap[$sAttCode] = 'att_'.$iFieldIndex;
|
||||
$iFieldIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oPage->add('<table><tr><td>');
|
||||
$oPage->details($aDetails);
|
||||
$oPage->add('</td></tr></table>');
|
||||
$oPage->add("<input type=\"hidden\" name=\"id\" value=\"".$this->GetKey()."\" id=\"id\">\n");
|
||||
$aFieldsMap['id'] = 'id';
|
||||
$oPage->add("<input type=\"hidden\" name=\"class\" value=\"$sClass\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"operation\" value=\"apply_stimulus\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"stimulus\" value=\"$sStimulus\">\n");
|
||||
$oPage->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\">\n");
|
||||
$oAppContext = new ApplicationContext();
|
||||
$oPage->add($oAppContext->GetForForm());
|
||||
$oPage->add("<button type=\"button\" class=\"action\" onClick=\"BackToDetails('$sClass', ".$this->GetKey().")\"><span>".Dict::S('UI:Button:Cancel')."</span></button> \n");
|
||||
$oPage->add("<button type=\"submit\" class=\"action\"><span>$sActionLabel</span></button>\n");
|
||||
$oPage->add("</form>\n");
|
||||
$oPage->add("</div>\n");
|
||||
if ($sButtonsPosition != 'top')
|
||||
{
|
||||
// bottom or both: Displays the ticket details AFTER the actions
|
||||
$oPage->add('<div class="ui-widget-content">');
|
||||
$this->DisplayBareProperties($oPage);
|
||||
$oPage->add('</div>');
|
||||
}
|
||||
|
||||
$iFieldsCount = count($aFieldsMap);
|
||||
$sJsonFieldsMap = json_encode($aFieldsMap);
|
||||
|
||||
$oPage->add_script(
|
||||
<<<EOF
|
||||
// Initializes the object once at the beginning of the page...
|
||||
var oWizardHelper = new WizardHelper('$sClass', '', '$sTargetState');
|
||||
oWizardHelper.SetFieldsMap($sJsonFieldsMap);
|
||||
oWizardHelper.SetFieldsCount($iFieldsCount);
|
||||
EOF
|
||||
);
|
||||
$oPage->add_ready_script(
|
||||
<<<EOF
|
||||
// Starts the validation when the page is ready
|
||||
CheckFields('apply_stimulus', false);
|
||||
EOF
|
||||
);
|
||||
}
|
||||
|
||||
public static function ProcessZlist($aList, $aDetails, $sCurrentTab, $sCurrentCol, $sCurrentSet)
|
||||
{
|
||||
@@ -2965,7 +3097,7 @@ EOF
|
||||
if (!isset($aTransitions[$sStimulus]))
|
||||
{
|
||||
// Invalid stimulus
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $oObj->GetName(), $oObj->GetStateLabel()));
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus,$this->GetName(),$this->GetStateLabel()));
|
||||
}
|
||||
$aTransition = $aTransitions[$sStimulus];
|
||||
$sTargetState = $aTransition['target_state'];
|
||||
|
||||
178
pages/UI.php
178
pages/UI.php
@@ -398,6 +398,7 @@ try
|
||||
case 'form_for_modify_all': // Form to modify multiple objects (bulk modify)
|
||||
case 'bulk_stimulus': // For to apply a stimulus to multiple objects
|
||||
case 'stimulus': // Form displayed when applying a stimulus (state change)
|
||||
case 'apply_stimulus': // Form displayed when applying a stimulus (state change)
|
||||
$oP->add_linked_script("../js/json.js");
|
||||
$oP->add_linked_script("../js/forms-json-utils.js");
|
||||
$oP->add_linked_script("../js/wizardhelper.js");
|
||||
@@ -1381,132 +1382,7 @@ EOF
|
||||
$oObj = MetaModel::GetObject($sClass, $id, false);
|
||||
if ($oObj != null)
|
||||
{
|
||||
$aTransitions = $oObj->EnumTransitions();
|
||||
$aStimuli = MetaModel::EnumStimuli($sClass);
|
||||
if (!isset($aTransitions[$sStimulus]))
|
||||
{
|
||||
// Invalid stimulus
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $oObj->GetName(), $oObj->GetStateLabel()));
|
||||
}
|
||||
$sActionLabel = $aStimuli[$sStimulus]->GetLabel();
|
||||
$sActionDetails = $aStimuli[$sStimulus]->GetDescription();
|
||||
$aTransition = $aTransitions[$sStimulus];
|
||||
$sTargetState = $aTransition['target_state'];
|
||||
$aTargetStates = MetaModel::EnumStates($sClass);
|
||||
$oP->add("<div class=\"page_header\">\n");
|
||||
$oP->add("<h1>$sActionLabel - <span class=\"hilite\">{$oObj->GetName()}</span></h1>\n");
|
||||
$oP->set_title($sActionLabel);
|
||||
$oP->add("</div>\n");
|
||||
$aTargetState = $aTargetStates[$sTargetState];
|
||||
$aExpectedAttributes = $aTargetState['attribute_list'];
|
||||
$oP->add("<h1>$sActionDetails</h1>\n");
|
||||
$sButtonsPosition = MetaModel::GetConfig()->Get('buttons_position');
|
||||
if ($sButtonsPosition == 'bottom')
|
||||
{
|
||||
// bottom: Displays the ticket details BEFORE the actions
|
||||
$oP->add('<div class="ui-widget-content">');
|
||||
$oObj->DisplayBareProperties($oP);
|
||||
$oP->add('</div>');
|
||||
}
|
||||
$oP->add("<div class=\"wizContainer\">\n");
|
||||
$oP->add("<form id=\"apply_stimulus\" method=\"post\" onSubmit=\"return OnSubmit('apply_stimulus');\">\n");
|
||||
$aDetails = array();
|
||||
$iFieldIndex = 0;
|
||||
$aFieldsMap = array();
|
||||
|
||||
$aDetailsList = $oObj->FlattenZList(MetaModel::GetZListItems($sClass, 'details'));
|
||||
// Order the fields based on their dependencies, set the fields for which there is only one possible value
|
||||
// and perform this in the order of dependencies to avoid dead-ends
|
||||
$aDeps = array();
|
||||
foreach($aDetailsList as $sAttCode)
|
||||
{
|
||||
$aDeps[$sAttCode] = MetaModel::GetPrequisiteAttributes($sClass, $sAttCode);
|
||||
}
|
||||
$aList = $oObj->OrderDependentFields($aDeps);
|
||||
|
||||
foreach($aList as $sAttCode)
|
||||
{
|
||||
// Consider only the "expected" fields for the target state
|
||||
if (array_key_exists($sAttCode, $aExpectedAttributes))
|
||||
{
|
||||
$iExpectCode = $aExpectedAttributes[$sAttCode];
|
||||
// Prompt for an attribute if
|
||||
// - the attribute must be changed or must be displayed to the user for confirmation
|
||||
// - or the field is mandatory and currently empty
|
||||
if ( ($iExpectCode & (OPT_ATT_MUSTCHANGE | OPT_ATT_MUSTPROMPT)) ||
|
||||
(($iExpectCode & OPT_ATT_MANDATORY) && ($oObj->Get($sAttCode) == '')) )
|
||||
{
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
|
||||
$aArgs = array('this' => $oObj);
|
||||
// If the field is mandatory, set it to the only possible value
|
||||
if ((!$oAttDef->IsNullAllowed()) || ($iExpectCode & OPT_ATT_MANDATORY))
|
||||
{
|
||||
if ($oAttDef->IsExternalKey())
|
||||
{
|
||||
$oAllowedValues = MetaModel::GetAllowedValuesAsObjectSet($sClass, $sAttCode, $aArgs);
|
||||
if ($oAllowedValues->Count() == 1)
|
||||
{
|
||||
$oRemoteObj = $oAllowedValues->Fetch();
|
||||
$oObj->Set($sAttCode, $oRemoteObj->GetKey());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$aAllowedValues = MetaModel::GetAllowedValues_att($sClass, $sAttCode, $aArgs);
|
||||
if (count($aAllowedValues) == 1)
|
||||
{
|
||||
$aValues = array_keys($aAllowedValues);
|
||||
$oObj->Set($sAttCode, $aValues[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$sHTMLValue = cmdbAbstractObject::GetFormElementForField($oP, $sClass, $sAttCode, $oAttDef, $oObj->Get($sAttCode), $oObj->GetEditValue($sAttCode), 'att_'.$iFieldIndex, '', $iExpectCode, $aArgs);
|
||||
$aDetails[] = array('label' => '<span>'.$oAttDef->GetLabel().'</span>', 'value' => "<span id=\"field_att_$iFieldIndex\">$sHTMLValue</span>");
|
||||
$aFieldsMap[$sAttCode] = 'att_'.$iFieldIndex;
|
||||
$iFieldIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$oP->add('<table><tr><td>');
|
||||
$oP->details($aDetails);
|
||||
$oP->add('</td></tr></table>');
|
||||
$oP->add("<input type=\"hidden\" name=\"id\" value=\"$id\" id=\"id\">\n");
|
||||
$aFieldsMap['id'] = 'id';
|
||||
$oP->add("<input type=\"hidden\" name=\"class\" value=\"$sClass\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"operation\" value=\"apply_stimulus\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"stimulus\" value=\"$sStimulus\">\n");
|
||||
$oP->add("<input type=\"hidden\" name=\"transaction_id\" value=\"".utils::GetNewTransactionId()."\">\n");
|
||||
$oP->add($oAppContext->GetForForm());
|
||||
$oP->add("<button type=\"button\" class=\"action\" onClick=\"BackToDetails('$sClass', $id)\"><span>".Dict::S('UI:Button:Cancel')."</span></button> \n");
|
||||
$oP->add("<button type=\"submit\" class=\"action\"><span>$sActionLabel</span></button>\n");
|
||||
$oP->add("</form>\n");
|
||||
$oP->add("</div>\n");
|
||||
if ($sButtonsPosition != 'top')
|
||||
{
|
||||
// bottom or both: Displays the ticket details AFTER the actions
|
||||
$oP->add('<div class="ui-widget-content">');
|
||||
$oObj->DisplayBareProperties($oP);
|
||||
$oP->add('</div>');
|
||||
}
|
||||
|
||||
$iFieldsCount = count($aFieldsMap);
|
||||
$sJsonFieldsMap = json_encode($aFieldsMap);
|
||||
|
||||
$oP->add_script(
|
||||
<<<EOF
|
||||
// Initializes the object once at the beginning of the page...
|
||||
var oWizardHelper = new WizardHelper('$sClass', '', '$sTargetState');
|
||||
oWizardHelper.SetFieldsMap($sJsonFieldsMap);
|
||||
oWizardHelper.SetFieldsCount($iFieldsCount);
|
||||
EOF
|
||||
);
|
||||
$oP->add_ready_script(
|
||||
<<<EOF
|
||||
// Starts the validation when the page is ready
|
||||
CheckFields('apply_stimulus', false);
|
||||
EOF
|
||||
);
|
||||
$oObj->DisplayStimulusForm($oP, $sStimulus);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1533,6 +1409,7 @@ EOF
|
||||
$aStimuli = MetaModel::EnumStimuli($sClass);
|
||||
$sMessage = '';
|
||||
$sSeverity = 'ok';
|
||||
$bDisplayDetails = true;
|
||||
if (!isset($aTransitions[$sStimulus]))
|
||||
{
|
||||
throw new ApplicationException(Dict::Format('UI:Error:Invalid_Stimulus_On_Object_In_State', $sStimulus, $oObj->GetName(), $oObj->GetStateLabel()));
|
||||
@@ -1568,20 +1445,52 @@ EOF
|
||||
}
|
||||
}
|
||||
|
||||
$oObj->UpdateObjectFromPostedForm('', array_keys($aExpectedAttributes), $sTargetState);
|
||||
$oObj->UpdateObjectFromPostedForm('', array_keys($aExpectedAttributes), $sTargetState);
|
||||
|
||||
if (count($aErrors) == 0)
|
||||
{
|
||||
if ($oObj->ApplyStimulus($sStimulus))
|
||||
$sIssues = '';
|
||||
$bApplyStimulus = true;
|
||||
list($bRes, $aIssues) = $oObj->CheckToWrite(); // Check before trying to write the object
|
||||
if ($bRes)
|
||||
{
|
||||
$oObj->DBUpdate();
|
||||
$sMessage = Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName());
|
||||
$sSeverity = 'ok';
|
||||
try
|
||||
{
|
||||
$bApplyStimulus = $oObj->ApplyStimulus($sStimulus); // will write the object in the DB
|
||||
}
|
||||
catch(CoreException $e)
|
||||
{
|
||||
// Rollback to the previous state... by reloading the object from the database and applying the modifications again
|
||||
$oObj = MetaModel::GetObject(get_class($oObj), $oObj->GetKey());
|
||||
$oObj->UpdateObjectFromPostedForm('', array_keys($aExpectedAttributes), $sTargetState);
|
||||
$aData = $e->getContextData();
|
||||
$sIssues = (array_key_exists('issues', $aData)) ? $aData['issues'] : 'Unknown error...';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$sIssues = implode(' ', $aIssues);
|
||||
}
|
||||
|
||||
if (!$bApplyStimulus)
|
||||
{
|
||||
$sMessage = Dict::S('UI:FailedToApplyStimuli');
|
||||
$sSeverity = 'error';
|
||||
$sSeverity = 'error';
|
||||
}
|
||||
else if ($sIssues != '')
|
||||
{
|
||||
$bDisplayDetails = false;
|
||||
// Found issues, explain and give the user a second chance
|
||||
//
|
||||
$oObj->DisplayStimulusForm($oP, $sStimulus);
|
||||
$sIssueDesc = Dict::Format('UI:ObjectCouldNotBeWritten',$sIssues);
|
||||
$oP->add_ready_script("alert('".addslashes($sIssueDesc)."');");
|
||||
}
|
||||
else
|
||||
{
|
||||
$sMessage = Dict::Format('UI:Class_Object_Updated', MetaModel::GetName(get_class($oObj)), $oObj->GetName());
|
||||
$sSeverity = 'ok';
|
||||
utils::RemoveTransaction($sTransactionId);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1590,7 +1499,10 @@ EOF
|
||||
$sSeverity = 'error';
|
||||
}
|
||||
}
|
||||
ReloadAndDisplay($oP, $oObj, 'apply_stimulus', $sMessage, $sSeverity);
|
||||
if ($bDisplayDetails)
|
||||
{
|
||||
ReloadAndDisplay($oP, $oObj, 'apply_stimulus', $sMessage, $sSeverity);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user