N°8210 - Remove iApplicationObjectExtension (#737)

This commit is contained in:
Benjamin Dalsass
2025-09-05 09:27:55 +02:00
committed by GitHub
parent a104310379
commit 44972f34e5
14 changed files with 61 additions and 585 deletions

View File

@@ -57,12 +57,6 @@ require_once(APPROOT.'application/applicationextension/backoffice/SeparatorPopup
require_once(APPROOT.'application/applicationextension/backoffice/URLButtonItem.php');
require_once(APPROOT.'application/applicationextension/backoffice/URLPopupMenuItem.php');
//deprecated class and interface
require_once(APPROOT.'application/applicationextension/backoffice/iApplicationObjectExtension.php');
require_once(APPROOT.'application/applicationextension/backoffice/AbstractApplicationObjectExtension.php');
require_once(APPROOT.'application/applicationextension/iBackupExtraFilesExtension.php');
require_once(APPROOT.'application/applicationextension/iKPILoggerExtension.php');
require_once(APPROOT.'application/applicationextension/iModuleExtension.php');

View File

@@ -1,58 +0,0 @@
<?php
/**
* Extend this class instead of iApplicationObjectExtension if you don't need to overload all methods
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method
* @package ORMExtensibilityAPI
* @since 2.7.0
*/
abstract class AbstractApplicationObjectExtension implements iApplicationObjectExtension
{
/**
* @inheritDoc
*/
public function OnIsModified($oObject)
{
return false;
}
/**
* @inheritDoc
*/
public function OnCheckToWrite($oObject)
{
return array();
}
/**
* @inheritDoc
*/
public function OnCheckToDelete($oObject)
{
return array();
}
/**
* @inheritDoc
*/
public function OnDBUpdate($oObject, $oChange = null)
{
}
/**
* @inheritDoc
*/
public function OnDBInsert($oObject, $oChange = null)
{
}
/**
* @inheritDoc
*/
public function OnDBDelete($oObject, $oChange = null)
{
}
}

View File

@@ -1,111 +0,0 @@
<?php
/**
* Implement this interface to perform specific operations when objects are manipulated
*
* Note that those methods will be called when objects are manipulated, either in a programmatic way
* or through the GUI.
*
* @api
* @deprecated 3.1.0 N°4756 use the new event service instead, see {@see DBObject::FireEvent()} method. More details on each method PHPDoc.
* @package ORMExtensibilityAPI
*/
interface iApplicationObjectExtension
{
/**
* Invoked to determine whether an object has been modified in memory
*
* The GUI calls this verb to determine the message that will be displayed to the end-user.
* Anyhow, this API can be called in other contexts such as the CSV import tool.
*
* If the extension returns false, then the framework will perform the usual evaluation.
* Otherwise, the answer is definitively "yes, the object has changed".
*
* @param /cmdbAbstractObject $oObject The target object
*
* @return boolean True if something has changed for the target object
* @api
* @deprecated 3.1.0 N°4756 No alternative available, this API was unstable and is abandoned
*/
public function OnIsModified($oObject);
/**
* Invoked to determine whether an object can be written to the database
*
* The GUI calls this verb and reports any issue.
* Anyhow, this API can be called in other contexts such as the CSV import tool.
*
* @param \cmdbAbstractObject $oObject The target object
*
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_WRITE event instead
*/
public function OnCheckToWrite($oObject);
/**
* Invoked to determine wether an object can be deleted from the database
*
* The GUI calls this verb and stops the deletion process if any issue is reported.
*
* Please not that it is not possible to cascade deletion by this mean: only stopper issues can be handled.
*
* @param \cmdbAbstractObject $oObject The target object
*
* @return string[] A list of errors message. An error message is made of one line and it can be displayed to the end-user.
* @api
* @deprecated 3.1.0 N°4756 Use EVENT_DB_CHECK_TO_DELETE event instead
*/
public function OnCheckToDelete($oObject);
/**
* Invoked when an object is updated into the database. The method is called right <b>after</b> the object has been written to the
* database.
*
* Useful methods you can call on $oObject :
*
* * {@see DBObject::ListPreviousValuesForUpdatedAttributes()} : list of changed attributes and their values before the change
* * {@see DBObject::Get()} : for a given attribute the new value that was persisted
*
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
*
* @return void
*
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
* @api
* @since 2.7.0 N°2293 can access object changes by calling {@see DBObject::ListPreviousValuesForUpdatedAttributes()} on $oObject
*/
public function OnDBUpdate($oObject, $oChange = null);
/**
* Invoked when an object is created into the database
*
* The method is called right <b>after</b> the object has been written to the database.
*
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
*
* @return void
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_WRITE event instead
* @api
*/
public function OnDBInsert($oObject, $oChange = null);
/**
* Invoked when an object is deleted from the database
*
* The method is called right <b>before</b> the object will be deleted from the database.
*
* @param \cmdbAbstractObject $oObject The target object
* @param CMDBChange|null $oChange A change context. Since 2.0 it is fine to ignore it, as the framework does maintain this information
* once for all the changes made within the current page
*
* @return void
* @deprecated 3.1.0 N°4756 Use EVENT_DB_AFTER_DELETE event instead
* @api
*/
public function OnDBDelete($oObject, $oChange = null);
}

View File

@@ -214,6 +214,15 @@ abstract class cmdbAbstractObject extends CMDBObject implements iDisplay
*/
protected static bool $bBlockEventDBLinksChanged = false;
/**
* If set to true, the object is considered as modified, whatever the actual state is.
* This is used when an object is modified indirectly (eg. through a linked set)
*
* @var bool
*
* @since 3.3.0 N°8210 - Remove iApplicationObjectExtension
*/
private bool $bIsMarkedAsModified = false;
/**
* Constructor from a row of data (as a hash 'attcode' => value)
@@ -4542,21 +4551,6 @@ HTML;
return $res;
}
protected function PostInsertActions(): void
{
parent::PostInsertActions();
// Invoke extensions after insertion (the object must exist, have an id, etc.)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBInsert()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBInsert($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBInsert');
}
}
/**
* @inheritdoc
* Attaches InlineImages to the current object
@@ -4589,21 +4583,6 @@ HTML;
return $res;
}
protected function PostUpdateActions(array $aChanges): void
{
parent::PostUpdateActions($aChanges);
// Invoke extensions after the update (could be before)
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach (MetaModel::EnumPlugins(iApplicationObjectExtension::class) as $oExtensionInstance) {
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBUpdate()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBUpdate($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBUpdate');
}
}
/**
* @param string $sMessageIdPrefix
*
@@ -4639,21 +4618,6 @@ HTML;
return $oDeletionPlan;
}
final protected function PreDeleteActions(): void
{
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnDBDelete()");
$oKPI = new ExecutionKPI();
$oExtensionInstance->OnDBDelete($this, self::GetCurrentChange());
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnDBDelete');
}
parent::PreDeleteActions();
}
final protected function PostDeleteActions(): void
{
parent::PostDeleteActions();
@@ -4666,25 +4630,20 @@ HTML;
return true;
}
// Plugins
//
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified()");
$oKPI = new ExecutionKPI();
$bIsModified = $oExtensionInstance->OnIsModified($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnIsModified');
if ($bIsModified) {
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> true");
return true;
} else {
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnIsModified() -> false");
}
}
return $this->bIsMarkedAsModified;
}
return false;
/**
* Override the default modification state of the object.
*
* The object is considered as modified, whatever the actual state is.
* This is used when an object is modified indirectly (eg. through a linked set)
*
* @return void
*/
public function MarkObjectAsModified(): void
{
$this->bIsMarkedAsModified = true;
}
/**
@@ -4698,7 +4657,7 @@ HTML;
}
/**
* Whether to bypass the checks of user rights when writing this object, could be used in {@link \iApplicationObjectExtension::OnCheckToWrite()}
* Whether to bypass the checks of user rights when writing this object
*
* @return bool
*/
@@ -4727,22 +4686,6 @@ HTML;
{
parent::DoCheckToWrite();
// Plugins
//
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnCheckToWrite()");
$oKPI = new ExecutionKPI();
$aNewIssues = $oExtensionInstance->OnCheckToWrite($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToWrite');
if (is_array($aNewIssues) && (count($aNewIssues) > 0)) // Some extensions return null instead of an empty array
{
$this->m_aCheckIssues = array_merge($this->m_aCheckIssues, $aNewIssues);
}
}
// User rights
//
if (!$this->bAllowWrite)
@@ -4779,22 +4722,6 @@ HTML;
{
parent::DoCheckToDelete($oDeletionPlan);
// Plugins
//
/** @var \iApplicationObjectExtension $oExtensionInstance */
foreach(MetaModel::EnumPlugins('iApplicationObjectExtension') as $oExtensionInstance)
{
$sExtensionClass = get_class($oExtensionInstance);
$this->LogCRUDDebug(__METHOD__, "Calling $sExtensionClass::OnCheckToDelete()");
$oKPI = new ExecutionKPI();
$aNewIssues = $oExtensionInstance->OnCheckToDelete($this);
$oKPI->ComputeStatsForExtension($oExtensionInstance, 'OnCheckToDelete');
if (is_array($aNewIssues) && count($aNewIssues) > 0)
{
$this->m_aDeleteIssues = array_merge($this->m_aDeleteIssues, $aNewIssues);
}
}
// User rights
//
if (! $this->bAllowDelete)
@@ -5809,7 +5736,7 @@ JS
{
$this->NotifyAttachedObjectsOnLinkClassModification();
$this->RemoveObjectAwaitingEventDbLinksChanged(get_class($this), $this->GetKey());
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied]);
$this->FireEvent(EVENT_DB_AFTER_WRITE, ['is_new' => $bIsNew, 'changes' => $aChanges, 'stimulus_applied' => $sStimulusBeingApplied, 'cmdb_change' => self::GetCurrentChange()]);
}
//////////////
@@ -5847,7 +5774,7 @@ JS
final protected function FireEventAfterDelete(): void
{
$this->NotifyAttachedObjectsOnLinkClassModification();
$this->FireEvent(EVENT_DB_AFTER_DELETE);
$this->FireEvent(EVENT_DB_AFTER_DELETE, ['cmdb_change' => self::GetCurrentChange()]);
}
/**

View File

@@ -7709,7 +7709,6 @@ abstract class MetaModel
'iLoginUIExtension',
'iPreferencesExtension',
'iApplicationUIExtension',
'iApplicationObjectExtension',
'iPopupMenuExtension',
'iPageUIBlockExtension',
'iBackofficeLinkedScriptsExtension',

View File

@@ -5,15 +5,16 @@
*/
use Combodo\iTop\Application\WebPage\WebPage;
use Combodo\iTop\Service\Events\EventData;
use Combodo\iTop\Service\Events\EventService;
use Combodo\iTop\Service\Events\iEventServiceSetup;
class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExtension
class AttachmentPlugIn implements iApplicationUIExtension, iEventServiceSetup
{
const ENUM_GUI_ALL = 'all';
const ENUM_GUI_BACKOFFICE = 'backoffice';
const ENUM_GUI_PORTALS = 'portals';
protected static $m_bIsModified = false;
public function OnDisplayProperties($oObject, WebPage $oPage, $bEditMode = false)
{
if ($this->GetAttachmentsPosition() == 'properties')
@@ -158,45 +159,39 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
return array();
}
public function OnIsModified($oObject)
public function RegisterEventsAndListeners() : void
{
return self::$m_bIsModified;
EventService::RegisterListener(EVENT_DB_AFTER_WRITE, [$this, 'OnDBAfterWrite']);
EventService::RegisterListener(EVENT_DB_AFTER_DELETE, [$this, 'OnDBAfterDelete']);
}
public function OnCheckToWrite($oObject)
public function OnDBAfterWrite(EventData $oEventData)
{
return array();
}
$oObject = $oEventData->Get('object');
$oCMDBChange = $oEventData->Get('cmdb_change');
$bIsNew = $oEventData->Get('is_new');
public function OnCheckToDelete($oObject)
{
return array();
}
public function OnDBUpdate($oObject, $oChange = null)
{
if ($this->IsTargetObject($oObject))
{
// Get all current attachments
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
while ($oAttachment = $oSet->Fetch())
{
$oAttachment->SetItem($oObject, true /*updateonchange*/);
if($bIsNew){
self::UpdateAttachments($oObject, $oCMDBChange);
}
else{
// Get all current attachments
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
$oSet = new DBObjectSet($oSearch, array(), array('class' => get_class($oObject), 'item_id' => $oObject->GetKey()));
while ($oAttachment = $oSet->Fetch())
{
$oAttachment->SetItem($oObject, true /*updateonchange*/);
}
}
}
}
public function OnDBInsert($oObject, $oChange = null)
public function OnDBAfterDelete(EventData $oEventData)
{
if ($this->IsTargetObject($oObject))
{
self::UpdateAttachments($oObject, $oChange);
}
}
$oObject = $oEventData->Get('object');
public function OnDBDelete($oObject, $oChange = null)
{
if ($this->IsTargetObject($oObject))
{
$oSearch = DBObjectSearch::FromOQL("SELECT Attachment WHERE item_class = :class AND item_id = :item_id");
@@ -291,7 +286,7 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
* @see ObjectFormManager::FinalizeAttachments() for the portal version
*
* @param $oObject
* @param $oChange
* @param $oCMDBChange
*
* @return void
* @throws \ArchivedObjectException
@@ -303,10 +298,8 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
* @throws \MySQLHasGoneAwayException
* @throws \OQLException
*/
protected static function UpdateAttachments($oObject, $oChange = null)
protected static function UpdateAttachments($oObject, $oCMDBChange = null)
{
self::$m_bIsModified = false;
if (utils::ReadParam('attachment_plugin', 'not-in-form') == 'not-in-form')
{
// Workaround to an issue in iTop < 2.0
@@ -363,9 +356,10 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
{
foreach ($aActions as $oChangeOp)
{
self::RecordHistory($oChange, $oObject, $oChangeOp);
self::RecordHistory($oCMDBChange, $oObject, $oChangeOp);
}
self::$m_bIsModified = true;
$oObject->MarkObjectAsModified();
}
}
}
@@ -556,11 +550,11 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
}
/////////////////////////////////////////////////////////////////////////
private static function RecordHistory($oChange, $oTargetObject, $oMyChangeOp)
private static function RecordHistory($oCMDBChange, $oTargetObject, $oMyChangeOp)
{
if (!is_null($oChange))
if (!is_null($oCMDBChange))
{
$oMyChangeOp->Set("change", $oChange->GetKey());
$oMyChangeOp->Set("change", $oCMDBChange->GetKey());
}
$oMyChangeOp->Set("objclass", get_class($oTargetObject));
$oMyChangeOp->Set("objkey", $oTargetObject->GetKey());
@@ -648,6 +642,8 @@ class AttachmentPlugIn implements iApplicationUIExtension, iApplicationObjectExt
return $bReadonly;
}
}
/**

View File

@@ -6,7 +6,6 @@ $vendorDir = dirname(__DIR__);
$baseDir = dirname($vendorDir);
return array(
'AbstractApplicationObjectExtension' => $baseDir . '/application/applicationextension.inc.php',
'AbstractApplicationUIExtension' => $baseDir . '/application/applicationextension.inc.php',
'AbstractLoginFSMExtension' => $baseDir . '/application/applicationextension.inc.php',
'AbstractPageUIBlockExtension' => $baseDir . '/application/applicationextension.inc.php',
@@ -3185,7 +3184,6 @@ return array(
'appUserPreferences' => $baseDir . '/application/user.preferences.class.inc.php',
'cmdbAbstractObject' => $baseDir . '/application/cmdbabstract.class.inc.php',
'cmdbDataGenerator' => $baseDir . '/core/data.generator.class.inc.php',
'iApplicationObjectExtension' => $baseDir . '/application/applicationextension.inc.php',
'iApplicationUIExtension' => $baseDir . '/application/applicationextension.inc.php',
'iAttributeNoGroupBy' => $baseDir . '/core/attributedef.class.inc.php',
'iBackgroundProcess' => $baseDir . '/core/backgroundprocess.inc.php',

View File

@@ -384,7 +384,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
);
public static $classMap = array (
'AbstractApplicationObjectExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'AbstractApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'AbstractLoginFSMExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'AbstractPageUIBlockExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
@@ -3563,7 +3562,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
'appUserPreferences' => __DIR__ . '/../..' . '/application/user.preferences.class.inc.php',
'cmdbAbstractObject' => __DIR__ . '/../..' . '/application/cmdbabstract.class.inc.php',
'cmdbDataGenerator' => __DIR__ . '/../..' . '/core/data.generator.class.inc.php',
'iApplicationObjectExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'iApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php',
'iAttributeNoGroupBy' => __DIR__ . '/../..' . '/core/attributedef.class.inc.php',
'iBackgroundProcess' => __DIR__ . '/../..' . '/core/backgroundprocess.inc.php',

View File

@@ -3,7 +3,7 @@
'name' => 'combodo/itop',
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '5b9e0a1d4f4751778386710eb52a1326d3c29423',
'reference' => '965c9dba1435ed8605dc3d05f6021e77654137c9',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
@@ -22,7 +22,7 @@
'combodo/itop' => array(
'pretty_version' => 'dev-develop',
'version' => 'dev-develop',
'reference' => '5b9e0a1d4f4751778386710eb52a1326d3c29423',
'reference' => '965c9dba1435ed8605dc3d05f6021e77654137c9',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),

View File

@@ -1,103 +0,0 @@
<?php
/*
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
class ApplicationObjectExtensionTest extends \Combodo\iTop\Test\UnitTest\ItopDataTestCase
{
const CREATE_TEST_ORG = true;
// Count the calls by name
private static array $aCalls = [];
private static int $iCalls = 0;
protected function setUp(): void
{
parent::setUp();
$this->RequireOnceUnitTestFile('iApplicationObjectExtension/MockApplicationObjectExtensionForTest1.php');
$this->ResetApplicationObjectExtensions();
// Count all the calls to this object
MockApplicationObjectExtensionForTest1::SetCallBack([ApplicationObjectExtensionTest::class, 'IncrementCallCount']);
}
public function tearDown(): void
{
MockApplicationObjectExtensionForTest1::SetModifications('Person', 'name', 0);
MockApplicationObjectExtensionForTest1::SetCallBack(null);
parent::tearDown();
}
public static function IncrementCallCount(string $sOrigin)
{
self::$aCalls[$sOrigin] = (self::$aCalls[$sOrigin] ?? 0) + 1;
self::$iCalls++;
}
public static function ResetCallCount()
{
self::$aCalls = [];
self::$iCalls = 0;
}
public function testExtensionCalled()
{
// Check that extension is called
$oPerson = $this->CreatePerson(1);
$oPerson->Set('first_name', 'testUpdateReentranceProtection');
MockApplicationObjectExtensionForTest1::SetModifications('Person', 'name', 1);
self::ResetCallCount();
$oPerson->DBUpdate();
// Called twice, the first call will provoke the DBUpdate and call again the object extension
$this->assertEquals(2, self::$iCalls);
}
public function testUpdateReentranceProtection()
{
$oPerson = $this->CreatePerson(1);
// Check that loop limit is 10
$i = 15;
self::ResetCallCount();
MockApplicationObjectExtensionForTest1::SetModifications('Person', 'name', $i);
$oPerson->Set('first_name', 'testUpdateReentranceProtection');
$oPerson->DBUpdate();
$this->assertEquals(10, self::$iCalls);
}
public function testModificationsOnUpdate()
{
$oPerson = $this->CreatePerson(1);
$oPerson->Set('first_name', 'testUpdateReentranceProtection');
self::ResetCallCount();
MockApplicationObjectExtensionForTest1::SetModifications('Person', 'name', 1);
$oPerson->DBUpdate();
$this->assertEquals(2, self::$iCalls);
}
public function testModificationsOnInsert()
{
self::ResetCallCount();
MockApplicationObjectExtensionForTest1::SetModifications('Person', 'name', 1);
$oPerson = $this->CreatePerson(1);
$this->assertEquals(2, self::$iCalls);
}
public function testModificationsOnInsertWith2Extensions()
{
self::ResetCallCount();
$this->RequireOnceUnitTestFile('iApplicationObjectExtension/MockApplicationObjectExtensionForTest2.php');
$this->ResetApplicationObjectExtensions();
// Count all the calls to this object
MockApplicationObjectExtensionForTest2::SetCallBack([ApplicationObjectExtensionTest::class, 'IncrementCallCount']);
MockApplicationObjectExtensionForTest1::SetModifications('Person', 'name', 2);
MockApplicationObjectExtensionForTest2::SetModifications('Person', 'first_name', 2);
$oPerson = $this->CreatePerson(1);
$this->assertEquals(6, self::$iCalls);
}
}

View File

@@ -78,10 +78,6 @@ class ApplicationExtensionTest extends ItopCustomDatamodelTestCase
\iApplicationUIExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iApplicationObjectExtension::class => [
\iApplicationObjectExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,
],
\iPopupMenuExtension::class => [
\iPopupMenuExtension::class,
static::ENUM_API_CALL_METHOD_ENUMPLUGINS,

View File

@@ -66,16 +66,6 @@ class ExampleFor_iPreferencesExtension extends \AbstractPreferencesExtension
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iApplicationUIExtension extends \AbstractApplicationUIExtension
{
// Do nothing, we just need the class to exists for the unit test
}
]]></content>
</snippet>
<snippet id="ExampleFor_iApplicationObjectExtension" _delta="define">
<placement>core</placement>
<rank>0</rank>
<content><![CDATA[
class ExampleFor_iApplicationObjectExtension extends \AbstractApplicationObjectExtension
{
// Do nothing, we just need the class to exists for the unit test
}

View File

@@ -1,75 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* Test object for AbstractApplicationObjectExtension API
*/
class MockApplicationObjectExtensionForTest1 extends AbstractApplicationObjectExtension
{
protected static $iCountModify;
protected static $sClass;
protected static $sAttCodeToModify;
protected static $callBack;
public function __construct()
{
}
public static function SetCallBack($callBack)
{
static::$callBack = $callBack;
}
public static function SetModifications($sClass, $sAttCodeToModify, $iCountModify)
{
static::$sClass = $sClass;
static::$sAttCodeToModify = $sAttCodeToModify;
if (!MetaModel::IsValidClass($sClass) || !MetaModel::IsValidAttCode($sClass, $sAttCodeToModify)) {
throw new Exception("Invalid class $sClass or attcode $sAttCodeToModify");
}
static::$iCountModify = $iCountModify;
}
public function OnDBUpdate($oObject, $oChange = null)
{
if (get_class($oObject) !== static::$sClass) {
return;
}
if (!is_null(static::$callBack)) {
call_user_func(static::$callBack, 'OnDBUpdate');
}
$aPreviousValues = $oObject->ListPreviousValuesForUpdatedAttributes();
$sPreviousValues = print_r($aPreviousValues, true);
IssueLog::Info(__METHOD__." received previous values:\n$sPreviousValues");
if (static::$iCountModify > 0) {
static::$iCountModify--;
$oObject->Set(static::$sAttCodeToModify, 'Value_'.rand());
$oObject->DBUpdate();
}
}
public function OnDBInsert($oObject, $oChange = null)
{
if (get_class($oObject) !== static::$sClass) {
return;
}
if (!is_null(static::$callBack)) {
call_user_func(static::$callBack, 'OnDBInsert');
}
if (static::$iCountModify > 0) {
static::$iCountModify--;
$oObject->Set(static::$sAttCodeToModify, 'Value_'.rand());
$oObject->DBUpdate();
}
}
}

View File

@@ -1,75 +0,0 @@
<?php
/**
* @copyright Copyright (C) 2010-2024 Combodo SAS
* @license http://opensource.org/licenses/AGPL-3.0
*/
/**
* Test object for AbstractApplicationObjectExtension API
*/
class MockApplicationObjectExtensionForTest2 extends AbstractApplicationObjectExtension
{
protected static $iCountModify;
protected static $sClass;
protected static $sAttCodeToModify;
protected static $callBack;
public function __construct()
{
}
public static function SetCallBack($callBack)
{
static::$callBack = $callBack;
}
public static function SetModifications($sClass, $sAttCodeToModify, $iCountModify)
{
static::$sClass = $sClass;
static::$sAttCodeToModify = $sAttCodeToModify;
if (!MetaModel::IsValidClass($sClass) || !MetaModel::IsValidAttCode($sClass, $sAttCodeToModify)) {
throw new Exception("Invalid class $sClass or attcode $sAttCodeToModify");
}
static::$iCountModify = $iCountModify;
}
public function OnDBUpdate($oObject, $oChange = null)
{
if (get_class($oObject) !== static::$sClass) {
return;
}
if (!is_null(static::$callBack)) {
call_user_func(static::$callBack, 'OnDBUpdate');
}
$aPreviousValues = $oObject->ListPreviousValuesForUpdatedAttributes();
$sPreviousValues = print_r($aPreviousValues, true);
IssueLog::Info(__METHOD__." received previous values:\n$sPreviousValues");
if (static::$iCountModify > 0) {
static::$iCountModify--;
$oObject->Set(static::$sAttCodeToModify, 'Value_'.rand());
$oObject->DBUpdate();
}
}
public function OnDBInsert($oObject, $oChange = null)
{
if (get_class($oObject) !== static::$sClass) {
return;
}
if (!is_null(static::$callBack)) {
call_user_func(static::$callBack, 'OnDBInsert');
}
if (static::$iCountModify > 0) {
static::$iCountModify--;
$oObject->Set(static::$sAttCodeToModify, 'Value_'.rand());
$oObject->DBUpdate();
}
}
}