mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
N°1345 - Add possibility to sort transitions automatically
This commit is contained in:
@@ -64,6 +64,32 @@ require_once('mutex.class.inc.php');
|
||||
*/
|
||||
abstract class DBObject implements iDisplay
|
||||
{
|
||||
/**
|
||||
* @var string For sorting based on the XML order (like in iTop 3.0 and older)
|
||||
* @since 3.1.0 N°1345
|
||||
*/
|
||||
public const ENUM_TRANSITIONS_SORT_TYPE_XML = 'xml';
|
||||
/**
|
||||
* @var string For sorting based on the transitions labels
|
||||
* @since 3.1.0 N°1345
|
||||
*/
|
||||
public const ENUM_TRANSITIONS_SORT_TYPE_ALPHABETICAL = 'alphabetical';
|
||||
/**
|
||||
* @var string For sorting based on the arrival states rank, ascending sort
|
||||
* @since 3.1.0 N°1345
|
||||
*/
|
||||
public const ENUM_TRANSITIONS_SORT_TYPE_FIXED = 'fixed';
|
||||
/**
|
||||
* @var string For sorting based on the arrival states rank but depending on the current state (first transitions to states with higher ranks, then transitions to states with lower ranks)
|
||||
* @since 3.1.0 N°1345
|
||||
*/
|
||||
public const ENUM_TRANSITIONS_SORT_TYPE_RELATIVE = 'relative';
|
||||
/**
|
||||
* @var string Default sort type of the transitions
|
||||
* @since 3.1.0 N°1345
|
||||
*/
|
||||
public const DEFAULT_TRANSITIONS_SORT_TYPE = self::ENUM_TRANSITIONS_SORT_TYPE_RELATIVE;
|
||||
|
||||
private static $m_aMemoryObjectsByClass = array();
|
||||
|
||||
/** @var array class => array of ('table' => array of (array of <sql_value>)) */
|
||||
@@ -3939,11 +3965,83 @@ abstract class DBObject implements iDisplay
|
||||
public function EnumTransitions()
|
||||
{
|
||||
$sClass = get_class($this);
|
||||
if (!MetaModel::HasLifecycle($sClass)) return array();
|
||||
if (!MetaModel::HasLifecycle($sClass)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||
$sState = $this->Get($sStateAttCode);
|
||||
return MetaModel::EnumTransitions($sClass, $sState);
|
||||
$aTransitions = MetaModel::EnumTransitions($sClass, $sState);
|
||||
|
||||
if (count($aTransitions) === 0) {
|
||||
return $aTransitions;
|
||||
}
|
||||
|
||||
// Try to sort transitions depending on the configuration
|
||||
$sSortType = utils::GetConfig()->Get('lifecycle.transitions_sort_type');
|
||||
switch ($sSortType) {
|
||||
case static::ENUM_TRANSITIONS_SORT_TYPE_XML:
|
||||
$aSortedTransitions = $aTransitions;
|
||||
break;
|
||||
|
||||
case static::ENUM_TRANSITIONS_SORT_TYPE_ALPHABETICAL:
|
||||
$aSortedTransitions = $aTransitions;
|
||||
$aStimuli = MetaModel::EnumStimuli($sClass);
|
||||
|
||||
// Sort $aSortedTransitions based on labels from $aStimuli
|
||||
uksort($aSortedTransitions, function($sKey1, $sKey2) use ($aStimuli) {
|
||||
// If any transition is not in $aStimuli, put it at the end even though it's a weird situation
|
||||
if ((false === isset($aStimuli[$sKey1])) || (false === isset($aStimuli[$sKey2]))) {
|
||||
return 1;
|
||||
}
|
||||
return $aStimuli[$sKey1]->GetLabel() > $aStimuli[$sKey2]->GetLabel() ? 1 : -1;
|
||||
});
|
||||
break;
|
||||
|
||||
case static::ENUM_TRANSITIONS_SORT_TYPE_FIXED:
|
||||
case static::ENUM_TRANSITIONS_SORT_TYPE_RELATIVE:
|
||||
$aSortedTransitions = $aTransitions;
|
||||
|
||||
// Get states sorted as defined in the datamodel
|
||||
$sStateAttCode = MetaModel::GetStateAttributeCode($sClass);
|
||||
$oAttDef = MetaModel::GetAttributeDef($sClass, $sStateAttCode);
|
||||
$aAllowedValues = $oAttDef->GetAllowedValues();
|
||||
$aStatesSortFromDatamodel = array_keys($aAllowedValues);
|
||||
|
||||
// Sort $aSortedTransitions based on the states sort from the datamodel
|
||||
uksort($aSortedTransitions, function($sKey1, $sKey2) use ($aSortedTransitions, $aStatesSortFromDatamodel) {
|
||||
$sTargetState1 = $aSortedTransitions[$sKey1]['target_state'];
|
||||
$sTargetState2 = $aSortedTransitions[$sKey2]['target_state'];
|
||||
|
||||
return array_search($sTargetState1, $aStatesSortFromDatamodel) > array_search($sTargetState2, $aStatesSortFromDatamodel) ? 1 : -1;
|
||||
});
|
||||
|
||||
if ($sSortType === static::ENUM_TRANSITIONS_SORT_TYPE_RELATIVE) {
|
||||
// Find current state position
|
||||
$sCurrentState = $this->Get($sStateAttCode);
|
||||
$iCurrentStatePos = array_search($sCurrentState, $aStatesSortFromDatamodel);
|
||||
|
||||
foreach ($aSortedTransitions as $sStimulusCode => $aTransitionDef) {
|
||||
// Leave state with higher ranks than the current's in their positions
|
||||
if (array_search($aTransitionDef['target_state'], $aStatesSortFromDatamodel) >= $iCurrentStatePos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove transition from beginning of the array and move it back at the end
|
||||
array_shift($aSortedTransitions);
|
||||
$aSortedTransitions = array_merge($aSortedTransitions, [$sStimulusCode => $aTransitionDef]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
$aSortedTransitions = $aTransitions;
|
||||
IssueLog::Error('Could not sort object transitions as the sort type is not correct. Check "lifecycle.transitions_sort_type" conf. parameter.', LogChannels::CORE, [
|
||||
'lifecycle.transitions_sort_type' => $sSortType,
|
||||
]);
|
||||
}
|
||||
|
||||
return $aSortedTransitions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user