mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-12 23:14:18 +01:00
Merge remote-tracking branch 'origin/support/3.1' into support/3.2
This commit is contained in:
@@ -304,8 +304,8 @@
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_BEFORE_APPLY_STIMULUS" _delta="define">
|
||||
<description>A stimulus is about to be applied to an object</description>
|
||||
<event id="EVENT_ENUM_TRANSITIONS" _delta="define">
|
||||
<description>Manage the allowed transitions in current object state. The only action allowed is to deny transitions with DBObject::DenyTransition()</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
@@ -314,89 +314,9 @@
|
||||
<description>The object where the stimulus is targeted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus">
|
||||
<description>Current stimulus applied</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="previous_state">
|
||||
<description>Object previous state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="new_state">
|
||||
<description>Object new state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="save_object">
|
||||
<description>The object must be saved in the database</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_AFTER_APPLY_STIMULUS" _delta="define">
|
||||
<description>A stimulus has been applied to an object</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<event_data>
|
||||
<event_datum id="object">
|
||||
<description>The object where the stimulus is targeted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus">
|
||||
<description>Current stimulus applied</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="previous_state">
|
||||
<description>Object previous state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="new_state">
|
||||
<description>Object new state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="save_object">
|
||||
<description>The object is asked to be saved in the database</description>
|
||||
<type>boolean</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
</event_data>
|
||||
</event>
|
||||
<event id="EVENT_DB_APPLY_STIMULUS_FAILED" _delta="define">
|
||||
<description>A stimulus has failed</description>
|
||||
<sources>
|
||||
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
|
||||
</sources>
|
||||
<event_data>
|
||||
<event_datum id="action">
|
||||
<description>The action that failed to apply the stimulus</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="object">
|
||||
<description>The object where the stimulus is targeted</description>
|
||||
<type>DBObject</type>
|
||||
</event_datum>
|
||||
<event_datum id="stimulus">
|
||||
<description>Current stimulus applied</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="previous_state">
|
||||
<description>Object previous state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="new_state">
|
||||
<description>Object new state</description>
|
||||
<type>string</type>
|
||||
</event_datum>
|
||||
<event_datum id="save_object">
|
||||
<description>The object must be saved in the database</description>
|
||||
<type>boolean</type>
|
||||
<event_datum id="allowed_stimuli">
|
||||
<description>The list of available stimuli in the current state</description>
|
||||
<type>array</type>
|
||||
</event_datum>
|
||||
<event_datum id="debug_info">
|
||||
<description>Debug string</description>
|
||||
|
||||
@@ -210,6 +210,7 @@ abstract class DBObject implements iDisplay
|
||||
const MAX_UPDATE_LOOP_COUNT = 10;
|
||||
|
||||
private $aEventListeners = [];
|
||||
private array $aAllowedTransitions = [];
|
||||
|
||||
/**
|
||||
* DBObject constructor.
|
||||
@@ -4404,9 +4405,32 @@ abstract class DBObject implements iDisplay
|
||||
]);
|
||||
}
|
||||
|
||||
$this->aAllowedTransitions = $aSortedTransitions;
|
||||
$this->FireEvent(EVENT_ENUM_TRANSITIONS, ['allowed_stimuli' => array_keys($aSortedTransitions)]);
|
||||
$aSortedTransitions = $this->aAllowedTransitions;
|
||||
$this->aAllowedTransitions = [];
|
||||
|
||||
return $aSortedTransitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a transition for a specific stimulus.
|
||||
* This is only usable by EVENT_ENUM_TRANSITIONS listeners in order
|
||||
* to manage the allowed transitions in the current object state.
|
||||
*
|
||||
* @param string $sStimulus
|
||||
*
|
||||
* @return void
|
||||
* @api
|
||||
* @since 3.1.2
|
||||
*/
|
||||
public function DenyTransition(string $sStimulus): void
|
||||
{
|
||||
if (isset($this->aAllowedTransitions[$sStimulus])) {
|
||||
unset($this->aAllowedTransitions[$sStimulus]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to reset a stop-watch
|
||||
* Suitable for use as a lifecycle action
|
||||
@@ -4492,14 +4516,6 @@ abstract class DBObject implements iDisplay
|
||||
$sNewState = $aTransitionDef['target_state'];
|
||||
$this->Set($sStateAttCode, $sNewState);
|
||||
|
||||
$aEventData = [
|
||||
'stimulus' => $sStimulusCode,
|
||||
'previous_state' => $sPreviousState,
|
||||
'new_state' => $sNewState,
|
||||
'save_object' => !$bDoNotWrite,
|
||||
];
|
||||
$this->FireEvent(EVENT_DB_BEFORE_APPLY_STIMULUS, $aEventData);
|
||||
|
||||
// $aTransitionDef is an
|
||||
// array('target_state'=>..., 'actions'=>array of handlers procs, 'user_restriction'=>TBD
|
||||
|
||||
@@ -4584,8 +4600,6 @@ abstract class DBObject implements iDisplay
|
||||
if (!$bDoNotWrite) {
|
||||
$this->DBWrite();
|
||||
}
|
||||
|
||||
$this->FireEvent(EVENT_DB_AFTER_APPLY_STIMULUS, $aEventData);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4594,8 +4608,6 @@ abstract class DBObject implements iDisplay
|
||||
{
|
||||
$this->m_aCurrValues[$sAttCode] = $aBackupValues[$sAttCode];
|
||||
}
|
||||
$aEventData['action'] = $sActionDesc;
|
||||
$this->FireEvent(EVENT_DB_APPLY_STIMULUS_FAILED, $aEventData);
|
||||
}
|
||||
return $bSuccess;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ use const EVENT_DB_CHECK_TO_DELETE;
|
||||
use const EVENT_DB_CHECK_TO_WRITE;
|
||||
use const EVENT_DB_COMPUTE_VALUES;
|
||||
use const EVENT_DB_LINKS_CHANGED;
|
||||
use const EVENT_ENUM_TRANSITIONS;
|
||||
|
||||
class CRUDEventTest extends ItopDataTestCase
|
||||
{
|
||||
@@ -624,6 +625,29 @@ class CRUDEventTest extends ItopDataTestCase
|
||||
|
||||
//echo($oDBObject->oEventDataReceived->Get('debug_info'));
|
||||
}
|
||||
|
||||
public function testEnumTransitions()
|
||||
{
|
||||
$oEventReceiver = new CRUDEventReceiver($this);
|
||||
$oEventReceiver->RegisterCRUDListeners();
|
||||
|
||||
// Object with no lifecycle
|
||||
/** @var DBObject $oPerson */
|
||||
$oPerson = $this->CreatePerson(1);
|
||||
$oEventReceiver->AddCallback(EVENT_ENUM_TRANSITIONS, Person::class, 'EnumTransitions');
|
||||
self::CleanCallCount();
|
||||
$oPerson->EnumTransitions();
|
||||
$this->assertEquals(0, self::$iEventCalls);
|
||||
|
||||
// Object with lifecycle
|
||||
$oTicket = $this->CreateTicket(1);
|
||||
$oEventReceiver->AddCallback(EVENT_ENUM_TRANSITIONS, UserRequest::class, 'EnumTransitions');
|
||||
self::CleanCallCount();
|
||||
$aTransitions = $oTicket->EnumTransitions();
|
||||
$this->assertEquals(1, self::$aEventCalls[EVENT_ENUM_TRANSITIONS]);
|
||||
$this->assertEquals(1, self::$iEventCalls);
|
||||
$this->assertCount(0, $aTransitions);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -713,7 +737,7 @@ class CRUDEventReceiver extends ClassesWithDebug
|
||||
$aCallBack = $this->aCallbacks[$sEvent][$sClass];
|
||||
if ($aCallBack['count'] > 0) {
|
||||
$this->aCallbacks[$sEvent][$sClass]['count']--;
|
||||
call_user_func($this->aCallbacks[$sEvent][$sClass]['callback'], $oObject);
|
||||
call_user_func($this->aCallbacks[$sEvent][$sClass]['callback'], $oData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -730,6 +754,7 @@ class CRUDEventReceiver extends ClassesWithDebug
|
||||
$this->oTestCase->EventService_RegisterListener(EVENT_DB_ABOUT_TO_DELETE, [$this, 'OnEvent']);
|
||||
$this->oTestCase->EventService_RegisterListener(EVENT_DB_AFTER_DELETE, [$this, 'OnEvent']);
|
||||
$this->oTestCase->EventService_RegisterListener(EVENT_DB_LINKS_CHANGED, [$this, 'OnEvent']);
|
||||
$this->oTestCase->EventService_RegisterListener(EVENT_ENUM_TRANSITIONS, [$this, 'OnEvent']);
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -739,9 +764,10 @@ class CRUDEventReceiver extends ClassesWithDebug
|
||||
/**
|
||||
* @noinspection PhpUnusedPrivateMethodInspection Used as a callback
|
||||
*/
|
||||
private function AddRoleToLink($oObject): void
|
||||
private function AddRoleToLink(EventData $oData): void
|
||||
{
|
||||
$this->Debug(__METHOD__);
|
||||
$oObject = $oData->Get('object');
|
||||
$oContactType = MetaModel::NewObject(ContactType::class, ['name' => 'test_'.$oObject->GetKey()]);
|
||||
$oContactType->DBInsert();
|
||||
$oObject->Set('role_id', $oContactType->GetKey());
|
||||
@@ -750,27 +776,44 @@ class CRUDEventReceiver extends ClassesWithDebug
|
||||
/**
|
||||
* @noinspection PhpUnusedPrivateMethodInspection Used as a callback
|
||||
*/
|
||||
private function SetPersonFunction($oObject): void
|
||||
private function SetPersonFunction(EventData $oData): void
|
||||
{
|
||||
$this->Debug(__METHOD__);
|
||||
$oObject = $oData->Get('object');
|
||||
$oObject->Set('function', 'CRUD_function_'.rand());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnusedPrivateMethodInspection Used as a callback
|
||||
*/
|
||||
private function SetPersonFirstName($oObject): void
|
||||
private function SetPersonFirstName(EventData $oData): void
|
||||
{
|
||||
$this->Debug(__METHOD__);
|
||||
$oObject = $oData->Get('object');
|
||||
$oObject->Set('first_name', 'CRUD_first_name_'.rand());
|
||||
}
|
||||
|
||||
/**
|
||||
* @noinspection PhpUnusedPrivateMethodInspection Used as a callback
|
||||
*/
|
||||
private function CheckCrudStack(DBObject $oObject): void
|
||||
private function CheckCrudStack(EventData $oData): void
|
||||
{
|
||||
$this->Debug(__METHOD__);
|
||||
$oObject = $oData->Get('object');
|
||||
self::$bIsObjectInCrudStack = DBObject::IsObjectCurrentlyInCrud(get_class($oObject), $oObject->GetKey());
|
||||
}
|
||||
|
||||
private function EnumTransitions(EventData $oData): void
|
||||
{
|
||||
$this->Debug(__METHOD__);
|
||||
/** @var \DBObject $oObject */
|
||||
$oObject = $oData->Get('object');
|
||||
$aAllowedStimuli = $oData->Get('allowed_stimuli');
|
||||
// Deny all transitions
|
||||
foreach ($aAllowedStimuli as $sStimulus) {
|
||||
$this->debug(" * Deny $sStimulus");
|
||||
$oObject->DenyTransition($sStimulus);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user