This commit is contained in:
Eric Espie
2022-05-31 15:37:29 +02:00
parent aed8337c51
commit c9317542c8
8 changed files with 150 additions and 66 deletions

View File

@@ -5740,7 +5740,7 @@ JS
if ($sClass == 'UserRequest') {
IssueLog::Debug("CRUD: DBInsert $sClass::0 About to write in DB", LogChannels::DM_CRUD);
}
$this->FireEvent(EVENT_SERVICE_DB_BEFORE_INSERT);
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_INSERT);
}
/**
@@ -5754,7 +5754,7 @@ JS
IssueLog::Debug("CRUD: $sClass::{$this->m_iKey} Inserted in DB", LogChannels::DM_CRUD);
}
$this->FireEvent(EVENT_SERVICE_DB_AFTER_INSERT);
$this->FireEvent(EVENT_SERVICE_DB_INSERT_DONE);
}
/**
@@ -5805,7 +5805,7 @@ JS
$sKey = $sClass.'::'.$this->GetKey();
IssueLog::Debug("CRUD: DBUpdate $sClass::$sKey About to be written in DB", LogChannels::DM_CRUD);
}
$this->FireEvent(EVENT_SERVICE_DB_BEFORE_UPDATE);
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_UPDATE);
}
/**
@@ -5821,7 +5821,7 @@ JS
$sKey = $sClass.'::'.$this->GetKey();
IssueLog::Debug("CRUD: DBUpdate $sClass::$sKey Updated", LogChannels::DM_CRUD);
}
$this->FireEvent(EVENT_SERVICE_DB_AFTER_UPDATE, $aEventData);
$this->FireEvent(EVENT_SERVICE_DB_UPDATE_DONE, $aEventData);
}
/**
@@ -5830,7 +5830,7 @@ JS
*/
final protected function EventDeleteBefore()
{
$this->FireEvent(EVENT_SERVICE_DB_BEFORE_DELETE);
$this->FireEvent(EVENT_SERVICE_DB_ABOUT_TO_DELETE);
}
/**
@@ -5839,7 +5839,7 @@ JS
*/
final protected function EventDeleteAfter()
{
$this->FireEvent(EVENT_SERVICE_DB_AFTER_DELETE);
$this->FireEvent(EVENT_SERVICE_DB_DELETE_DONE);
}
}

View File

@@ -200,7 +200,7 @@
</argument>
</arguments>
</event>
<event id="EVENT_SERVICE_DB_BEFORE_INSERT" _delta="define">
<event id="EVENT_SERVICE_DB_ABOUT_TO_INSERT" _delta="define">
<description>An object is about to be inserted in the database (no change possible)</description>
<replaces>DBObject::OnInsert</replaces>
<arguments>
@@ -214,7 +214,7 @@
</argument>
</arguments>
</event>
<event id="EVENT_SERVICE_DB_AFTER_INSERT" _delta="define">
<event id="EVENT_SERVICE_DB_INSERT_DONE" _delta="define">
<description>An object has been inserted into the database (but not reloaded). All changes to the object will be persisted automatically.</description>
<replaces>DBObject::AfterInsert</replaces>
<arguments>
@@ -242,7 +242,7 @@
</argument>
</arguments>
</event>
<event id="EVENT_SERVICE_DB_BEFORE_UPDATE" _delta="define">
<event id="EVENT_SERVICE_DB_ABOUT_TO_UPDATE" _delta="define">
<description>An object is about to be updated in the database (no change possible)</description>
<replaces>DBObject::OnUpdate</replaces>
<arguments>
@@ -256,7 +256,7 @@
</argument>
</arguments>
</event>
<event id="EVENT_SERVICE_DB_AFTER_UPDATE" _delta="define">
<event id="EVENT_SERVICE_DB_UPDATE_DONE" _delta="define">
<description>An object has been updated into the database and reloaded. All changes to the object will be persisted automatically.</description>
<replaces>DBObject::AfterUpdate</replaces>
<arguments>
@@ -270,7 +270,7 @@
</argument>
</arguments>
</event>
<event id="EVENT_SERVICE_DB_BEFORE_DELETE" _delta="define">
<event id="EVENT_SERVICE_DB_ABOUT_TO_DELETE" _delta="define">
<description>An object is about to be deleted in the database</description>
<replaces>DBObject::OnDelete</replaces>
<arguments>
@@ -284,7 +284,7 @@
</argument>
</arguments>
</event>
<event id="EVENT_SERVICE_DB_AFTER_DELETE" _delta="define">
<event id="EVENT_SERVICE_DB_DELETE_DONE" _delta="define">
<description>An object has been deleted into the database</description>
<replaces>DBObject::AfterDelete</replaces>
<arguments>
@@ -302,13 +302,25 @@
<description>A stimulus is about to be applied to an object</description>
<arguments>
<argument id="object">
<description>The object where the stimulus is to be applied</description>
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</argument>
<argument id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</argument>
<argument id="previous_state">
<description>Object previous state</description>
<type>string</type>
</argument>
<argument id="new_state">
<description>Object new state</description>
<type>string</type>
</argument>
<argument id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
</argument>
<argument id="debug_info">
<description>Debug string</description>
<type>string</type>
@@ -319,13 +331,58 @@
<description>A stimulus has been applied to an object</description>
<arguments>
<argument id="object">
<description>The object where the stimulus has been applied</description>
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</argument>
<argument id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</argument>
<argument id="previous_state">
<description>Object previous state</description>
<type>string</type>
</argument>
<argument id="new_state">
<description>Object new state</description>
<type>string</type>
</argument>
<argument id="save_object">
<description>The object is asked to be saved in the database</description>
<type>boolean</type>
</argument>
<argument id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event>
<event id="EVENT_SERVICE_DB_APPLY_STIMULUS_FAILED" _delta="define">
<description>A stimulus has failed</description>
<arguments>
<argument id="action">
<description>The action that failed to apply the stimulus</description>
<type>string</type>
</argument>
<argument id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</argument>
<argument id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</argument>
<argument id="previous_state">
<description>Object previous state</description>
<type>string</type>
</argument>
<argument id="new_state">
<description>Object new state</description>
<type>string</type>
</argument>
<argument id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
</argument>
<argument id="debug_info">
<description>Debug string</description>
<type>string</type>

View File

@@ -6015,7 +6015,9 @@ class AttributeDateTime extends AttributeDBField
public function GetDefaultValue(DBObject $oHostObject = null)
{
// null value will be replaced by the current date, if not already set, in DoComputeValues
if (!$this->IsNullAllowed()) {
return date($this->GetInternalFormat());
}
return $this->GetNullValue();
}
@@ -7805,7 +7807,7 @@ class AttributeBlob extends AttributeDefinition
public function GetDefaultValue(DBObject $oHostObject = null)
{
return "";
return new ormDocument('', '', '');
}
public function IsNullAllowed(DBObject $oHostObject = null)
@@ -11350,6 +11352,13 @@ class AttributeTagSet extends AttributeSet
return new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetMaxItems());
}
public function GetDefaultValue(DBObject $oHostObject = null)
{
$oTagSet = new ormTagSet(MetaModel::GetAttributeOrigin($this->GetHostClass(), $this->GetCode()), $this->GetCode(), $this->GetMaxItems());
$oTagSet->SetValues([]);
return $oTagSet;
}
public function IsNull($proposedValue)
{
if (is_null($proposedValue))

View File

@@ -491,7 +491,7 @@ abstract class CMDBObject extends DBObject
$oMyChangeOp->Set("objkey", $this->GetKey());
$oMyChangeOp->Set("attcode", $sAttCode);
$oMyChangeOp->Set("oldvalue", $original);
$oMyChangeOp->Set("newvalue", $value[$sAttCode]);
$oMyChangeOp->Set("newvalue", $value);
$iId = $oMyChangeOp->DBInsertNoReload();
}
elseif ($oAttDef instanceOf AttributeCustomFields)

View File

@@ -1034,13 +1034,11 @@ abstract class DBObject implements iDisplay
/**
* Compute scalar attributes that depend on any other type of attribute
*
* if you want to customize this behaviour, overwrite @see ComputeValues()
*
* @throws \CoreException
* @throws \CoreUnexpectedValue
* if you want to customize this behaviour, overwrite @internal
*
* @see ComputeValues()
*
* @internal
*/
final public function DoComputeValues()
{
@@ -1055,17 +1053,7 @@ abstract class DBObject implements iDisplay
if ($aCallInfo["function"] != "ComputeValues") continue;
return; //skip!
}
// Set the "null-not-allowed" datetimes (and dates) whose value is not initialized
foreach(MetaModel::ListAttributeDefs(get_class($this)) as $sAttCode => $oAttDef)
{
// AttributeDate is derived from AttributeDateTime
if (($oAttDef instanceof AttributeDateTime) && (!$oAttDef->IsNullAllowed()) && ($this->Get($sAttCode) == $oAttDef->GetNullValue()))
{
$this->Set($sAttCode, date($oAttDef->GetInternalFormat()));
}
}
$this->ComputeValues();
}
@@ -2255,8 +2243,6 @@ abstract class DBObject implements iDisplay
*/
public function DoCheckToWrite()
{
$this->DoComputeValues();
$this->DoCheckUniqueness();
$aChanges = $this->ListChanges();
@@ -2323,7 +2309,7 @@ abstract class DBObject implements iDisplay
* @throws \OQLException
*
*/
final public function CheckToWrite()
final public function CheckToWrite($bDoComputeValues = true)
{
if (MetaModel::SkipCheckToWrite())
{
@@ -2334,6 +2320,9 @@ abstract class DBObject implements iDisplay
$this->m_aCheckIssues = array();
$oKPI = new ExecutionKPI();
if ($bDoComputeValues) {
$this->DoComputeValues();
}
$this->DoCheckToWrite();
$this->EventCheckToWrite(['error_messages' => &$this->m_aCheckIssues]);
$oKPI->ComputeStats('CheckToWrite', get_class($this));
@@ -2961,7 +2950,7 @@ abstract class DBObject implements iDisplay
// Ultimate check - ensure DB integrity
$this->SetReadOnly('No modification allowed during CheckToWrite');
list($bRes, $aIssues) = $this->CheckToWrite();
list($bRes, $aIssues) = $this->CheckToWrite(false);
$this->SetReadWrite();
if (!$bRes) {
throw new CoreCannotSaveObjectException(array('issues' => $aIssues, 'class' => get_class($this), 'id' => $this->GetKey()));
@@ -2984,7 +2973,7 @@ abstract class DBObject implements iDisplay
}
}
$this->SetReadOnly('No modification allowed during The Event :'.EVENT_SERVICE_DB_BEFORE_INSERT);
$this->SetReadOnly('No modification allowed during The Event :'.EVENT_SERVICE_DB_ABOUT_TO_INSERT);
$this->EventInsertBefore();
$this->SetReadWrite();
@@ -3203,7 +3192,7 @@ abstract class DBObject implements iDisplay
// Ultimate check - ensure DB integrity
$this->SetReadOnly('No modification allowed during CheckToWrite');
list($bRes, $aIssues) = $this->CheckToWrite();
list($bRes, $aIssues) = $this->CheckToWrite(false);
$this->SetReadWrite();
if (!$bRes)
{
@@ -3238,7 +3227,7 @@ abstract class DBObject implements iDisplay
$iIsTransactionRetryDelay = MetaModel::GetConfig()->Get('db_core_transactions_retry_delay_ms');
$iTransactionRetry = $iTransactionRetryCount;
}
$this->SetReadOnly('No modification allowed during The Event :'.EVENT_SERVICE_DB_BEFORE_UPDATE);
$this->SetReadOnly('No modification allowed during The Event :'.EVENT_SERVICE_DB_ABOUT_TO_UPDATE);
$this->EventUpdateBefore();
$this->SetReadWrite();
@@ -3380,6 +3369,10 @@ abstract class DBObject implements iDisplay
}
}
$this->AfterUpdate();
$this->EventUpdateAfter(['changes' => $aChanges]);
// - TriggerOnObjectUpdate
$aParams = array('class_list' => MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL));
$oSet = new DBObjectSet(DBObjectSearch::FromOQL("SELECT TriggerOnObjectUpdate AS t WHERE t.target_class IN (:class_list)"),
@@ -3398,10 +3391,6 @@ abstract class DBObject implements iDisplay
// - TriggerOnObjectMention
// Forgotten by the fix of N°3245
$this->ActivateOnMentionTriggers(false);
$this->AfterUpdate();
$this->EventUpdateAfter(['changes' => $aChanges]);
}
catch (Exception $e)
{
@@ -3928,18 +3917,25 @@ abstract class DBObject implements iDisplay
$aTransitionDef = $aStateTransitions[$sStimulusCode];
$this->FireEvent(EVENT_SERVICE_DB_BEFORE_APPLY_STIMULUS, ['stimulus' => $sStimulusCode]);
// Change the state before proceeding to the actions, this is necessary because an action might
// trigger another stimuli (alternative: push the stimuli into a queue)
$sPreviousState = $this->Get($sStateAttCode);
$sNewState = $aTransitionDef['target_state'];
$this->Set($sStateAttCode, $sNewState);
$aEventData = [
'stimulus' => $sStimulusCode,
'previous_state' => $sPreviousState,
'new_state' => $sNewState,
'save_object' => !$bDoNotWrite,
];
$this->FireEvent(EVENT_SERVICE_DB_BEFORE_APPLY_STIMULUS, $aEventData);
// $aTransitionDef is an
// array('target_state'=>..., 'actions'=>array of handlers procs, 'user_restriction'=>TBD
$bSuccess = true;
$sActionDesc = '';
foreach ($aTransitionDef['actions'] as $actionHandler)
{
if (is_string($actionHandler))
@@ -4048,7 +4044,7 @@ abstract class DBObject implements iDisplay
}
}
$this->FireEvent(EVENT_SERVICE_DB_AFTER_APPLY_STIMULUS, ['stimulus' => $sStimulusCode]);
$this->FireEvent(EVENT_SERVICE_DB_AFTER_APPLY_STIMULUS, $aEventData);
}
else
{
@@ -4057,6 +4053,8 @@ abstract class DBObject implements iDisplay
{
$this->m_aCurrValues[$sAttCode] = $aBackupValues[$sAttCode];
}
$aEventData['action'] = $sActionDesc;
$this->FireEvent(EVENT_SERVICE_DB_APPLY_STIMULUS_FAILED, $aEventData);
}
if ($sClass == 'UserRequest') {
IssueLog::Debug("CRUD: ApplyStimulus $sStimulusCode $sClass::{$this->m_iKey} Ending", LogChannels::DM_CRUD);

View File

@@ -1198,7 +1198,19 @@
</state>
</states>
</lifecycle>
<methods>
<event_listeners>
<listener id="OnInsertRequested">
<event>EVENT_SERVICE_DB_INSERT_REQUESTED</event>
<callback>OnInsertRequested</callback>
<priority>0</priority>
</listener>
<listener id="OnUpdateRequested">
<event>EVENT_SERVICE_DB_UPDATE_REQUESTED</event>
<callback>OnUpdateRequested</callback>
<priority>0</priority>
</listener>
</event_listeners>
<methods>
<method id="GetTicketRefFormat">
<static>true</static>
<access>public</access>
@@ -1537,27 +1549,25 @@
$this->UpdateImpactedItems();
}]]></code>
</method>
<method id="OnInsert">
<method id="OnInsertRequested">
<static>false</static>
<access>protected</access>
<type>Overload-DBObject</type>
<code><![CDATA[
protected function OnInsert()
protected function OnInsertRequested(Combodo\iTop\Service\EventData $oEventData)
{
parent::OnInsert();
$this->ComputeImpactedItems();
$this->SetIfNull('last_update', time());
$this->SetIfNull('start_date', time());
}]]></code>
</method>
<method id="OnUpdate">
<method id="OnUpdateRequested">
<static>false</static>
<access>protected</access>
<type>Overload-DBObject</type>
<code><![CDATA[
protected function OnUpdate()
protected function OnUpdateRequested(Combodo\iTop\Service\EventData $oEventData)
{
parent::OnUpdate();
$aChanges = $this->ListChanges();
if (array_key_exists('functionalcis_list', $aChanges))
{

View File

@@ -1232,14 +1232,14 @@
</states>
</lifecycle>
<event_listeners>
<listener id="OnBeforeInsertEvent">
<event>BeforeInsert</event>
<callback>OnBeforeInsertEvent</callback>
<listener id="OnInsertRequested">
<event>EVENT_SERVICE_DB_INSERT_REQUESTED</event>
<callback>OnInsertRequested</callback>
<priority>0</priority>
</listener>
<listener id="OnBeforeUpdateEvent">
<event>BeforeUpdate</event>
<callback>OnBeforeUpdateEvent</callback>
<listener id="OnUpdateRequested">
<event>EVENT_SERVICE_DB_UPDATE_REQUESTED</event>
<callback>OnUpdateRequested</callback>
<priority>0</priority>
</listener>
</event_listeners>
@@ -1594,12 +1594,12 @@
$this->UpdateImpactedItems();
}]]></code>
</method>
<method id="OnBeforeInsertEvent">
<method id="OnInsertRequested">
<static>false</static>
<access>public</access>
<type>Internal</type>
<code><![CDATA[
public function OnBeforeInsertEvent(Combodo\iTop\Service\EventData $oEventData)
public function OnInsertRequested(Combodo\iTop\Service\EventData $oEventData)
{
$this->ComputeImpactedItems();
@@ -1607,12 +1607,12 @@
$this->SetIfNull('start_date', time());
}]]></code>
</method>
<method id="OnBeforeUpdateEvent">
<method id="OnUpdateRequested">
<static>false</static>
<access>public</access>
<type>Internal</type>
<code><![CDATA[
public function OnBeforeUpdateEvent(Combodo\iTop\Service\EventData $oEventData)
public function OnUpdateRequested(Combodo\iTop\Service\EventData $oEventData)
{
$aChanges = $this->ListChanges();
if (array_key_exists('functionalcis_list', $aChanges))

View File

@@ -1080,11 +1080,21 @@ EOF
$sName = $oEvent->getAttribute('id');
$oDescription = $oEvent->GetOptionalElement('description');
$sDescription = empty($oDescription) ? '' : $oDescription->GetText('');
$aArguments = [];
foreach ($oEvent->GetNodes('./arguments/argument') as $oArgumentNode) {
$aArg = [];
$sArgId = $oArgumentNode->getAttribute('id');
$oArgDesc = $oArgumentNode->GetOptionalElement('description');
$aArg['description'] = empty($oArgDesc) ? '' : $oArgDesc->GetText('');
$oArgType = $oArgumentNode->GetOptionalElement('type');
$aArg['type'] = empty($oArgType) ? '' : $oArgType->GetText('');
$aArguments[$sArgId] = $aArg;
}
$sArguments = var_export($aArguments, true);
$sConstant = $sName;
$sOutput = "define('$sConstant', '$sName');\n";
$sOutput .= "Combodo\iTop\Service\EventService::RegisterEvent('$sName', '$sDescription', '$sModuleName');\n";
$sOutput .= "Combodo\iTop\Service\EventService::RegisterEvent('$sName', '$sDescription', $sArguments, '$sModuleName');\n";
return $sOutput;
}